about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-02-07 13:57:24 +0000
committerbors <bors@rust-lang.org>2021-02-07 13:57:24 +0000
commit5a5f3a980c0d2afd55f2162300339471378e341f (patch)
treef37be80d51410721e381e20574d6acc5ebc4553b
parentae00b62ceb7eaf1f02f5289ab233bf7e0e8060d5 (diff)
parent9a82417a853ce6a90c2f5d3eb90436247952dfaa (diff)
downloadrust-5a5f3a980c0d2afd55f2162300339471378e341f.tar.gz
rust-5a5f3a980c0d2afd55f2162300339471378e341f.zip
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
-rw-r--r--compiler/rustc_error_codes/src/error_codes.rs2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0542.md47
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0546.md11
-rw-r--r--library/alloc/src/collections/btree/map.rs11
-rw-r--r--library/alloc/src/collections/btree/mod.rs16
-rw-r--r--library/alloc/src/collections/btree/navigate.rs11
-rw-r--r--library/alloc/src/collections/btree/remove.rs5
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/core/src/iter/traits/exact_size.rs6
-rw-r--r--src/test/ui/issues/issue-29821.rs19
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-sanity.stderr2
11 files changed, 96 insertions, 35 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
index 1ed43669ad8..849ef18fb90 100644
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ b/compiler/rustc_error_codes/src/error_codes.rs
@@ -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'
diff --git a/compiler/rustc_error_codes/src/error_codes/E0542.md b/compiler/rustc_error_codes/src/error_codes/E0542.md
new file mode 100644
index 00000000000..dbbc34a71be
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0542.md
@@ -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
diff --git a/compiler/rustc_error_codes/src/error_codes/E0546.md b/compiler/rustc_error_codes/src/error_codes/E0546.md
index b2df22c0f8f..0073357b5ea 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0546.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0546.md
@@ -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
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index d5352a877a3..8fb9198a7cb 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -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() }
     }
 }
 
diff --git a/library/alloc/src/collections/btree/mod.rs b/library/alloc/src/collections/btree/mod.rs
index cdb39104047..cf91c17b511 100644
--- a/library/alloc/src/collections/btree/mod.rs
+++ b/library/alloc/src/collections/btree/mod.rs
@@ -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 {
diff --git a/library/alloc/src/collections/btree/navigate.rs b/library/alloc/src/collections/btree/navigate.rs
index 2773b427fb1..1ef2a572ddd 100644
--- a/library/alloc/src/collections/btree/navigate.rs
+++ b/library/alloc/src/collections/btree/navigate.rs
@@ -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.
diff --git a/library/alloc/src/collections/btree/remove.rs b/library/alloc/src/collections/btree/remove.rs
index ff842197d19..9cd016fa62f 100644
--- a/library/alloc/src/collections/btree/remove.rs
+++ b/library/alloc/src/collections/btree/remove.rs
@@ -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)
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index a49979fb7aa..99c42a4ba44 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -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)]
diff --git a/library/core/src/iter/traits/exact_size.rs b/library/core/src/iter/traits/exact_size.rs
index 996d62e2b4a..167db3359f2 100644
--- a/library/core/src/iter/traits/exact_size.rs
+++ b/library/core/src/iter/traits/exact_size.rs
@@ -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
diff --git a/src/test/ui/issues/issue-29821.rs b/src/test/ui/issues/issue-29821.rs
new file mode 100644
index 00000000000..54be3afb59d
--- /dev/null
+++ b/src/test/ui/issues/issue-29821.rs
@@ -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() {}
diff --git a/src/test/ui/stability-attribute/stability-attribute-sanity.stderr b/src/test/ui/stability-attribute/stability-attribute-sanity.stderr
index ee9a93359f0..151b96b8b5a 100644
--- a/src/test/ui/stability-attribute/stability-attribute-sanity.stderr
+++ b/src/test/ui/stability-attribute/stability-attribute-sanity.stderr
@@ -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`.