Auto merge of #81853 - GuillaumeGomez:rollup-xzh1z4v, r=GuillaumeGomez
Rollup of 5 pull requests Successful merges: - #81526 (btree: use Option's unwrap_unchecked()) - #81742 (Add a note about the correctness and the effect on unsafe code to the `ExactSizeIterator` docs) - #81830 (Add long error explanation for E0542) - #81835 (Improve long explanation for E0546) - #81843 (Add regression test for #29821) Failed merges: - #81836 (Add long explanation for E0547) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
5a5f3a980c
@ -285,6 +285,7 @@ E0537: include_str!("./error_codes/E0537.md"),
|
||||
E0538: include_str!("./error_codes/E0538.md"),
|
||||
E0539: include_str!("./error_codes/E0539.md"),
|
||||
E0541: include_str!("./error_codes/E0541.md"),
|
||||
E0542: include_str!("./error_codes/E0542.md"),
|
||||
E0546: include_str!("./error_codes/E0546.md"),
|
||||
E0550: include_str!("./error_codes/E0550.md"),
|
||||
E0551: include_str!("./error_codes/E0551.md"),
|
||||
@ -602,7 +603,6 @@ E0781: include_str!("./error_codes/E0781.md"),
|
||||
E0523,
|
||||
// E0526, // shuffle indices are not constant
|
||||
// E0540, // multiple rustc_deprecated attributes
|
||||
E0542, // missing 'since'
|
||||
E0543, // missing 'reason'
|
||||
E0544, // multiple stability levels
|
||||
E0545, // incorrect 'issue'
|
||||
|
47
compiler/rustc_error_codes/src/error_codes/E0542.md
Normal file
47
compiler/rustc_error_codes/src/error_codes/E0542.md
Normal file
@ -0,0 +1,47 @@
|
||||
The `since` value is missing in a stability attribute.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0542
|
||||
#![feature(staged_api)]
|
||||
#![stable(since = "1.0.0", feature = "test")]
|
||||
|
||||
#[stable(feature = "_stable_fn")] // invalid
|
||||
fn _stable_fn() {}
|
||||
|
||||
#[rustc_const_stable(feature = "_stable_const_fn")] // invalid
|
||||
fn _stable_const_fn() {}
|
||||
|
||||
#[stable(feature = "_deprecated_fn", since = "0.1.0")]
|
||||
#[rustc_deprecated(
|
||||
reason = "explanation for deprecation"
|
||||
)] // invalid
|
||||
fn _deprecated_fn() {}
|
||||
```
|
||||
|
||||
To fix the issue you need to provide the `since` field.
|
||||
|
||||
```
|
||||
#![feature(staged_api)]
|
||||
#![stable(since = "1.0.0", feature = "test")]
|
||||
|
||||
#[stable(feature = "_stable_fn", since = "1.0.0")] // ok!
|
||||
fn _stable_fn() {}
|
||||
|
||||
#[rustc_const_stable(feature = "_stable_const_fn", since = "1.0.0")] // ok!
|
||||
fn _stable_const_fn() {}
|
||||
|
||||
#[stable(feature = "_deprecated_fn", since = "0.1.0")]
|
||||
#[rustc_deprecated(
|
||||
since = "1.0.0",
|
||||
reason = "explanation for deprecation"
|
||||
)] // ok!
|
||||
fn _deprecated_fn() {}
|
||||
```
|
||||
|
||||
See the [How Rust is Made and “Nightly Rust”][how-rust-made-nightly] appendix
|
||||
of the Book and the [Stability attributes][stability-attributes] section of the
|
||||
Rustc Dev Guide for more details.
|
||||
|
||||
[how-rust-made-nightly]: https://doc.rust-lang.org/book/appendix-07-nightly-rust.html
|
||||
[stability-attributes]: https://rustc-dev-guide.rust-lang.org/stability.html
|
@ -1,4 +1,4 @@
|
||||
A feature name is missing.
|
||||
The `feature` value is missing in a stability attribute.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
@ -13,7 +13,7 @@ fn unstable_fn() {}
|
||||
fn stable_fn() {}
|
||||
```
|
||||
|
||||
To fix the issue you need to provide a feature name.
|
||||
To fix the issue you need to provide the `feature` field.
|
||||
|
||||
```
|
||||
#![feature(staged_api)]
|
||||
@ -25,3 +25,10 @@ fn unstable_fn() {}
|
||||
#[stable(feature = "stable_fn", since = "1.0.0")] // ok!
|
||||
fn stable_fn() {}
|
||||
```
|
||||
|
||||
See the [How Rust is Made and “Nightly Rust”][how-rust-made-nightly] appendix
|
||||
of the Book and the [Stability attributes][stability-attributes] section of the
|
||||
Rustc Dev Guide for more details.
|
||||
|
||||
[how-rust-made-nightly]: https://doc.rust-lang.org/book/appendix-07-nightly-rust.html
|
||||
[stability-attributes]: https://rustc-dev-guide.rust-lang.org/stability.html
|
||||
|
@ -11,7 +11,6 @@ use core::ptr;
|
||||
use super::borrow::DormantMutRef;
|
||||
use super::node::{self, marker, ForceResult::*, Handle, NodeRef, Root};
|
||||
use super::search::SearchResult::*;
|
||||
use super::unwrap_unchecked;
|
||||
|
||||
mod entry;
|
||||
pub use entry::{Entry, OccupiedEntry, VacantEntry};
|
||||
@ -1433,7 +1432,7 @@ impl<K, V> Drop for IntoIter<K, V> {
|
||||
|
||||
unsafe {
|
||||
let mut node =
|
||||
unwrap_unchecked(ptr::read(&self.0.front)).into_node().forget_type();
|
||||
ptr::read(&self.0.front).unwrap_unchecked().into_node().forget_type();
|
||||
while let Some(parent) = node.deallocate_and_ascend() {
|
||||
node = parent.into_node().forget_type();
|
||||
}
|
||||
@ -1758,7 +1757,7 @@ impl<'a, K, V> Range<'a, K, V> {
|
||||
}
|
||||
|
||||
unsafe fn next_unchecked(&mut self) -> (&'a K, &'a V) {
|
||||
unsafe { unwrap_unchecked(self.front.as_mut()).next_unchecked() }
|
||||
unsafe { self.front.as_mut().unwrap_unchecked().next_unchecked() }
|
||||
}
|
||||
}
|
||||
|
||||
@ -1847,7 +1846,7 @@ impl<'a, K, V> DoubleEndedIterator for Range<'a, K, V> {
|
||||
|
||||
impl<'a, K, V> Range<'a, K, V> {
|
||||
unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a V) {
|
||||
unsafe { unwrap_unchecked(self.back.as_mut()).next_back_unchecked() }
|
||||
unsafe { self.back.as_mut().unwrap_unchecked().next_back_unchecked() }
|
||||
}
|
||||
}
|
||||
|
||||
@ -1893,7 +1892,7 @@ impl<'a, K, V> RangeMut<'a, K, V> {
|
||||
}
|
||||
|
||||
unsafe fn next_unchecked(&mut self) -> (&'a K, &'a mut V) {
|
||||
unsafe { unwrap_unchecked(self.front.as_mut()).next_unchecked() }
|
||||
unsafe { self.front.as_mut().unwrap_unchecked().next_unchecked() }
|
||||
}
|
||||
|
||||
/// Returns an iterator of references over the remaining items.
|
||||
@ -1923,7 +1922,7 @@ impl<K, V> FusedIterator for RangeMut<'_, K, V> {}
|
||||
|
||||
impl<'a, K, V> RangeMut<'a, K, V> {
|
||||
unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a mut V) {
|
||||
unsafe { unwrap_unchecked(self.back.as_mut()).next_back_unchecked() }
|
||||
unsafe { self.back.as_mut().unwrap_unchecked().next_back_unchecked() }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,22 +19,6 @@ trait Recover<Q: ?Sized> {
|
||||
fn replace(&mut self, key: Self::Key) -> Option<Self::Key>;
|
||||
}
|
||||
|
||||
/// Same purpose as `Option::unwrap` but doesn't always guarantee a panic
|
||||
/// if the option contains no value.
|
||||
/// SAFETY: the caller must ensure that the option contains a value.
|
||||
#[inline(always)]
|
||||
pub unsafe fn unwrap_unchecked<T>(val: Option<T>) -> T {
|
||||
val.unwrap_or_else(|| {
|
||||
if cfg!(debug_assertions) {
|
||||
panic!("'unchecked' unwrap on None in BTreeMap");
|
||||
} else {
|
||||
unsafe {
|
||||
core::intrinsics::unreachable();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
/// XorShiftRng
|
||||
struct DeterministicRng {
|
||||
|
@ -6,7 +6,6 @@ use core::ptr;
|
||||
|
||||
use super::node::{marker, ForceResult::*, Handle, NodeRef};
|
||||
use super::search::SearchResult;
|
||||
use super::unwrap_unchecked;
|
||||
|
||||
/// Finds the leaf edges delimiting a specified range in or underneath a node.
|
||||
///
|
||||
@ -310,7 +309,7 @@ macro_rules! def_next_kv_uncheched_dealloc {
|
||||
Err(last_edge) => {
|
||||
unsafe {
|
||||
let parent_edge = last_edge.into_node().deallocate_and_ascend();
|
||||
unwrap_unchecked(parent_edge).forget_node_type()
|
||||
parent_edge.unwrap_unchecked().forget_node_type()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -331,7 +330,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Immut<'a>, K, V, marker::Leaf>, marker::Ed
|
||||
pub unsafe fn next_unchecked(&mut self) -> (&'a K, &'a V) {
|
||||
super::mem::replace(self, |leaf_edge| {
|
||||
let kv = leaf_edge.next_kv();
|
||||
let kv = unsafe { unwrap_unchecked(kv.ok()) };
|
||||
let kv = unsafe { kv.ok().unwrap_unchecked() };
|
||||
(kv.next_leaf_edge(), kv.into_kv())
|
||||
})
|
||||
}
|
||||
@ -344,7 +343,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Immut<'a>, K, V, marker::Leaf>, marker::Ed
|
||||
pub unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a V) {
|
||||
super::mem::replace(self, |leaf_edge| {
|
||||
let kv = leaf_edge.next_back_kv();
|
||||
let kv = unsafe { unwrap_unchecked(kv.ok()) };
|
||||
let kv = unsafe { kv.ok().unwrap_unchecked() };
|
||||
(kv.next_back_leaf_edge(), kv.into_kv())
|
||||
})
|
||||
}
|
||||
@ -359,7 +358,7 @@ impl<'a, K, V> Handle<NodeRef<marker::ValMut<'a>, K, V, marker::Leaf>, marker::E
|
||||
pub unsafe fn next_unchecked(&mut self) -> (&'a K, &'a mut V) {
|
||||
let kv = super::mem::replace(self, |leaf_edge| {
|
||||
let kv = leaf_edge.next_kv();
|
||||
let kv = unsafe { unwrap_unchecked(kv.ok()) };
|
||||
let kv = unsafe { kv.ok().unwrap_unchecked() };
|
||||
(unsafe { ptr::read(&kv) }.next_leaf_edge(), kv)
|
||||
});
|
||||
// Doing this last is faster, according to benchmarks.
|
||||
@ -374,7 +373,7 @@ impl<'a, K, V> Handle<NodeRef<marker::ValMut<'a>, K, V, marker::Leaf>, marker::E
|
||||
pub unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a mut V) {
|
||||
let kv = super::mem::replace(self, |leaf_edge| {
|
||||
let kv = leaf_edge.next_back_kv();
|
||||
let kv = unsafe { unwrap_unchecked(kv.ok()) };
|
||||
let kv = unsafe { kv.ok().unwrap_unchecked() };
|
||||
(unsafe { ptr::read(&kv) }.next_back_leaf_edge(), kv)
|
||||
});
|
||||
// Doing this last is faster, according to benchmarks.
|
||||
|
@ -1,6 +1,5 @@
|
||||
use super::map::MIN_LEN;
|
||||
use super::node::{marker, ForceResult::*, Handle, LeftOrRight::*, NodeRef};
|
||||
use super::unwrap_unchecked;
|
||||
|
||||
impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV> {
|
||||
/// Removes a key-value pair from the tree, and returns that pair, as well as
|
||||
@ -77,12 +76,12 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
|
||||
// the element we were asked to remove. Prefer the left adjacent KV,
|
||||
// for the reasons listed in `choose_parent_kv`.
|
||||
let left_leaf_kv = self.left_edge().descend().last_leaf_edge().left_kv();
|
||||
let left_leaf_kv = unsafe { unwrap_unchecked(left_leaf_kv.ok()) };
|
||||
let left_leaf_kv = unsafe { left_leaf_kv.ok().unwrap_unchecked() };
|
||||
let (left_kv, left_hole) = left_leaf_kv.remove_leaf_kv(handle_emptied_internal_root);
|
||||
|
||||
// The internal node may have been stolen from or merged. Go back right
|
||||
// to find where the original KV ended up.
|
||||
let mut internal = unsafe { unwrap_unchecked(left_hole.next_kv().ok()) };
|
||||
let mut internal = unsafe { left_hole.next_kv().ok().unwrap_unchecked() };
|
||||
let old_kv = internal.replace_kv(left_kv.0, left_kv.1);
|
||||
let pos = internal.next_leaf_edge();
|
||||
(old_kv, pos)
|
||||
|
@ -111,6 +111,7 @@
|
||||
#![feature(nll)]
|
||||
#![feature(nonnull_slice_from_raw_parts)]
|
||||
#![feature(auto_traits)]
|
||||
#![feature(option_result_unwrap_unchecked)]
|
||||
#![feature(or_patterns)]
|
||||
#![feature(pattern)]
|
||||
#![feature(ptr_internals)]
|
||||
|
@ -13,6 +13,12 @@
|
||||
/// implement it. However, you may be able to provide a more performant
|
||||
/// implementation than the default, so overriding it in this case makes sense.
|
||||
///
|
||||
/// Note that this trait is a safe trait and as such does *not* and *cannot*
|
||||
/// guarantee that the returned length is correct. This means that `unsafe`
|
||||
/// code **must not** rely on the correctness of [`Iterator::size_hint`]. The
|
||||
/// unstable and unsafe [`TrustedLen`](super::marker::TrustedLen) trait gives
|
||||
/// this additional guarantee.
|
||||
///
|
||||
/// [`len`]: ExactSizeIterator::len
|
||||
///
|
||||
/// # Examples
|
||||
|
19
src/test/ui/issues/issue-29821.rs
Normal file
19
src/test/ui/issues/issue-29821.rs
Normal file
@ -0,0 +1,19 @@
|
||||
// build-pass
|
||||
|
||||
pub trait Foo {
|
||||
type FooAssoc;
|
||||
}
|
||||
|
||||
pub struct Bar<F: Foo> {
|
||||
id: F::FooAssoc
|
||||
}
|
||||
|
||||
pub struct Baz;
|
||||
|
||||
impl Foo for Baz {
|
||||
type FooAssoc = usize;
|
||||
}
|
||||
|
||||
static mut MY_FOO: Bar<Baz> = Bar { id: 0 };
|
||||
|
||||
fn main() {}
|
@ -116,5 +116,5 @@ LL | #[rustc_deprecated(since = "a", reason = "text")]
|
||||
|
||||
error: aborting due to 19 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0539, E0541, E0546, E0550.
|
||||
Some errors have detailed explanations: E0539, E0541, E0542, E0546, E0550.
|
||||
For more information about an error, try `rustc --explain E0539`.
|
||||
|
Loading…
x
Reference in New Issue
Block a user