about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/bootstrap/doc.rs6
-rw-r--r--src/libcore/cmp.rs1
-rw-r--r--src/libcore/ptr/mod.rs27
-rw-r--r--src/libcore/ptr/non_null.rs18
-rw-r--r--src/libcore/ptr/unique.rs7
-rw-r--r--src/librustc_typeck/check/autoderef.rs4
-rw-r--r--src/librustc_typeck/check/demand.rs11
-rw-r--r--src/test/ui/iterators/issue-58952-filter-type-length.rs31
-rw-r--r--src/test/ui/numeric/numeric-cast-2.stderr22
-rw-r--r--src/test/ui/numeric/numeric-cast.fixed14
-rw-r--r--src/test/ui/numeric/numeric-cast.stderr70
11 files changed, 137 insertions, 74 deletions
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index fc217a707db..7eab92ddc92 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -478,7 +478,11 @@ impl Step for Rustc {
 
         // Build cargo command.
         let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "doc");
-        cargo.env("RUSTDOCFLAGS", "--document-private-items");
+        cargo.env(
+            "RUSTDOCFLAGS",
+            "--document-private-items \
+            --enable-index-page -Zunstable-options",
+        );
         compile::rustc_cargo(builder, &mut cargo, target);
 
         // Only include compiler crates, no dependencies of those, such as `libc`.
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 335969b3ef0..9856efc6bd8 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -191,6 +191,7 @@ use self::Ordering::*;
 /// assert_eq!(x.eq(&y), false);
 /// ```
 ///
+/// [`Eq`]: Eq
 /// [`eq`]: PartialEq::eq
 /// [`ne`]: PartialEq::ne
 #[lang = "eq"]
diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs
index 84f28488c74..58f779106f7 100644
--- a/src/libcore/ptr/mod.rs
+++ b/src/libcore/ptr/mod.rs
@@ -65,8 +65,6 @@
 //! [`write_volatile`]: ./fn.write_volatile.html
 //! [`NonNull::dangling`]: ./struct.NonNull.html#method.dangling
 
-// ignore-tidy-undocumented-unsafe
-
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::cmp::Ordering;
@@ -248,14 +246,17 @@ pub(crate) struct FatPtr<T> {
 ///
 /// // create a slice pointer when starting out with a pointer to the first element
 /// let x = [5, 6, 7];
-/// let ptr = x.as_ptr();
-/// let slice = ptr::slice_from_raw_parts(ptr, 3);
+/// let raw_pointer = x.as_ptr();
+/// let slice = ptr::slice_from_raw_parts(raw_pointer, 3);
 /// assert_eq!(unsafe { &*slice }[2], 7);
 /// ```
 #[inline]
 #[stable(feature = "slice_from_raw_parts", since = "1.42.0")]
 #[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")]
 pub const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
+    // SAFETY: Accessing the value from the `Repr` union is safe since *const [T]
+    // and FatPtr have the same memory layouts. Only std can make this
+    // guarantee.
     unsafe { Repr { raw: FatPtr { data, len } }.rust }
 }
 
@@ -269,10 +270,28 @@ pub const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
 ///
 /// [`slice_from_raw_parts`]: fn.slice_from_raw_parts.html
 /// [`from_raw_parts_mut`]: ../../std/slice/fn.from_raw_parts_mut.html
+///
+/// # Examples
+///
+/// ```rust
+/// use std::ptr;
+///
+/// let x = &mut [5, 6, 7];
+/// let raw_pointer = x.as_mut_ptr();
+/// let slice = ptr::slice_from_raw_parts_mut(raw_pointer, 3);
+///
+/// unsafe {
+///     (*slice)[2] = 99; // assign a value at an index in the slice
+/// };
+///
+/// assert_eq!(unsafe { &*slice }[2], 99);
+/// ```
 #[inline]
 #[stable(feature = "slice_from_raw_parts", since = "1.42.0")]
 #[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")]
 pub const fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
+    // SAFETY: Accessing the value from the `Repr` union is safe since *mut [T]
+    // and FatPtr have the same memory layouts
     unsafe { Repr { raw: FatPtr { data, len } }.rust_mut }
 }
 
diff --git a/src/libcore/ptr/non_null.rs b/src/libcore/ptr/non_null.rs
index 626e58d4930..7d08503215e 100644
--- a/src/libcore/ptr/non_null.rs
+++ b/src/libcore/ptr/non_null.rs
@@ -7,8 +7,6 @@ use crate::mem;
 use crate::ops::{CoerceUnsized, DispatchFromDyn};
 use crate::ptr::Unique;
 
-// ignore-tidy-undocumented-unsafe
-
 /// `*mut T` but non-zero and covariant.
 ///
 /// This is often the correct thing to use when building data structures using
@@ -69,6 +67,9 @@ impl<T: Sized> NonNull<T> {
     #[rustc_const_stable(feature = "const_nonnull_dangling", since = "1.32.0")]
     #[inline]
     pub const fn dangling() -> Self {
+        // SAFETY: mem::align_of() returns a non-zero usize which is then casted
+        // to a *mut T. Therefore, `ptr` is not null and the conditions for
+        // calling new_unchecked() are respected.
         unsafe {
             let ptr = mem::align_of::<T>() as *mut T;
             NonNull::new_unchecked(ptr)
@@ -93,7 +94,12 @@ impl<T: ?Sized> NonNull<T> {
     #[stable(feature = "nonnull", since = "1.25.0")]
     #[inline]
     pub fn new(ptr: *mut T) -> Option<Self> {
-        if !ptr.is_null() { Some(unsafe { Self::new_unchecked(ptr) }) } else { None }
+        if !ptr.is_null() {
+            // SAFETY: The pointer is already checked and is not null
+            Some(unsafe { Self::new_unchecked(ptr) })
+        } else {
+            None
+        }
     }
 
     /// Acquires the underlying `*mut` pointer.
@@ -131,6 +137,7 @@ impl<T: ?Sized> NonNull<T> {
     #[rustc_const_stable(feature = "const_nonnull_cast", since = "1.32.0")]
     #[inline]
     pub const fn cast<U>(self) -> NonNull<U> {
+        // SAFETY: `self` is a `NonNull` pointer which is necessarily non-null
         unsafe { NonNull::new_unchecked(self.as_ptr() as *mut U) }
     }
 }
@@ -205,6 +212,8 @@ impl<T: ?Sized> hash::Hash for NonNull<T> {
 impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
     #[inline]
     fn from(unique: Unique<T>) -> Self {
+        // SAFETY: A Unique pointer cannot be null, so the conditions for
+        // new_unchecked() are respected.
         unsafe { NonNull::new_unchecked(unique.as_ptr()) }
     }
 }
@@ -213,6 +222,7 @@ impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
 impl<T: ?Sized> From<&mut T> for NonNull<T> {
     #[inline]
     fn from(reference: &mut T) -> Self {
+        // SAFETY: A mutable reference cannot be null.
         unsafe { NonNull { pointer: reference as *mut T } }
     }
 }
@@ -221,6 +231,8 @@ impl<T: ?Sized> From<&mut T> for NonNull<T> {
 impl<T: ?Sized> From<&T> for NonNull<T> {
     #[inline]
     fn from(reference: &T) -> Self {
+        // SAFETY: A reference cannot be null, so the conditions for
+        // new_unchecked() are respected.
         unsafe { NonNull { pointer: reference as *const T } }
     }
 }
diff --git a/src/libcore/ptr/unique.rs b/src/libcore/ptr/unique.rs
index d93dc1f3262..f5a5baceacc 100644
--- a/src/libcore/ptr/unique.rs
+++ b/src/libcore/ptr/unique.rs
@@ -73,6 +73,8 @@ impl<T: Sized> Unique<T> {
     // FIXME: rename to dangling() to match NonNull?
     #[inline]
     pub const fn empty() -> Self {
+        // SAFETY: mem::align_of() returns a valid, non-null pointer. The
+        // conditions to call new_unchecked() are thus respected.
         unsafe { Unique::new_unchecked(mem::align_of::<T>() as *mut T) }
     }
 }
@@ -93,6 +95,7 @@ impl<T: ?Sized> Unique<T> {
     #[inline]
     pub fn new(ptr: *mut T) -> Option<Self> {
         if !ptr.is_null() {
+            // SAFETY: The pointer has already been checked and is not null.
             Some(unsafe { Unique { pointer: ptr as _, _marker: PhantomData } })
         } else {
             None
@@ -128,6 +131,9 @@ impl<T: ?Sized> Unique<T> {
     /// Casts to a pointer of another type.
     #[inline]
     pub const fn cast<U>(self) -> Unique<U> {
+        // SAFETY: Unique::new_unchecked() creates a new unique and needs
+        // the given pointer to not be null.
+        // Since we are passing self as a pointer, it cannot be null.
         unsafe { Unique::new_unchecked(self.as_ptr() as *mut U) }
     }
 }
@@ -167,6 +173,7 @@ impl<T: ?Sized> fmt::Pointer for Unique<T> {
 impl<T: ?Sized> From<&mut T> for Unique<T> {
     #[inline]
     fn from(reference: &mut T) -> Self {
+        // SAFETY: A mutable reference cannot be null
         unsafe { Unique { pointer: reference as *mut T, _marker: PhantomData } }
     }
 }
diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs
index 0dab172230e..2bb00553232 100644
--- a/src/librustc_typeck/check/autoderef.rs
+++ b/src/librustc_typeck/check/autoderef.rs
@@ -114,10 +114,10 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
 
         let tcx = self.infcx.tcx;
 
-        // <cur_ty as Deref>
+        // <ty as Deref>
         let trait_ref = TraitRef {
             def_id: tcx.lang_items().deref_trait()?,
-            substs: tcx.mk_substs_trait(self.cur_ty, &[]),
+            substs: tcx.mk_substs_trait(ty, &[]),
         };
 
         let cause = traits::ObligationCause::misc(self.span, self.body_id);
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index c75283e419a..aa36bec6e1e 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -767,7 +767,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     suggest_to_change_suffix_or_into(err, is_fallible);
                     true
                 }
-                (&ty::Int(_), &ty::Uint(_)) | (&ty::Uint(_), &ty::Int(_)) => {
+                (&ty::Int(exp), &ty::Uint(found)) => {
+                    let is_fallible = match (exp.bit_width(), found.bit_width()) {
+                        (Some(exp), Some(found)) if found < exp => false,
+                        (None, Some(8)) => false,
+                        _ => true,
+                    };
+                    suggest_to_change_suffix_or_into(err, is_fallible);
+                    true
+                }
+                (&ty::Uint(_), &ty::Int(_)) => {
                     suggest_to_change_suffix_or_into(err, true);
                     true
                 }
diff --git a/src/test/ui/iterators/issue-58952-filter-type-length.rs b/src/test/ui/iterators/issue-58952-filter-type-length.rs
new file mode 100644
index 00000000000..046e3784084
--- /dev/null
+++ b/src/test/ui/iterators/issue-58952-filter-type-length.rs
@@ -0,0 +1,31 @@
+// run-pass
+//! This snippet causes the type length to blowup exponentially,
+//! so check that we don't accidentially exceed the type length limit.
+// FIXME: Once the size of iterator adaptors is further reduced,
+// increase the complexity of this test.
+
+fn main() {
+    let c = 2;
+    let bv = vec![2];
+    let b = bv
+        .iter()
+        .filter(|a| **a == c);
+
+    let _a = vec![1, 2, 3]
+        .into_iter()
+        .filter(|a| b.clone().any(|b| *b == *a))
+        .filter(|a| b.clone().any(|b| *b == *a))
+        .filter(|a| b.clone().any(|b| *b == *a))
+        .filter(|a| b.clone().any(|b| *b == *a))
+        .filter(|a| b.clone().any(|b| *b == *a))
+        .filter(|a| b.clone().any(|b| *b == *a))
+        .filter(|a| b.clone().any(|b| *b == *a))
+        .filter(|a| b.clone().any(|b| *b == *a))
+        .filter(|a| b.clone().any(|b| *b == *a))
+        .filter(|a| b.clone().any(|b| *b == *a))
+        .filter(|a| b.clone().any(|b| *b == *a))
+        .filter(|a| b.clone().any(|b| *b == *a))
+        .filter(|a| b.clone().any(|b| *b == *a))
+        .filter(|a| b.clone().any(|b| *b == *a))
+        .collect::<Vec<_>>();
+}
diff --git a/src/test/ui/numeric/numeric-cast-2.stderr b/src/test/ui/numeric/numeric-cast-2.stderr
index 465b507b788..3f900062cbb 100644
--- a/src/test/ui/numeric/numeric-cast-2.stderr
+++ b/src/test/ui/numeric/numeric-cast-2.stderr
@@ -15,27 +15,21 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast-2.rs:7:18
    |
 LL |     let y: i64 = x + x;
-   |            ---   ^^^^^ expected `i64`, found `u16`
-   |            |
+   |            ---   ^^^^^
+   |            |     |
+   |            |     expected `i64`, found `u16`
+   |            |     help: you can convert an `u16` to `i64`: `(x + x).into()`
    |            expected due to this
-   |
-help: you can convert an `u16` to `i64` and panic if the converted value wouldn't fit
-   |
-LL |     let y: i64 = (x + x).try_into().unwrap();
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast-2.rs:9:18
    |
 LL |     let z: i32 = x + x;
-   |            ---   ^^^^^ expected `i32`, found `u16`
-   |            |
+   |            ---   ^^^^^
+   |            |     |
+   |            |     expected `i32`, found `u16`
+   |            |     help: you can convert an `u16` to `i32`: `(x + x).into()`
    |            expected due to this
-   |
-help: you can convert an `u16` to `i32` and panic if the converted value wouldn't fit
-   |
-LL |     let z: i32 = (x + x).try_into().unwrap();
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/numeric/numeric-cast.fixed b/src/test/ui/numeric/numeric-cast.fixed
index 31acdb8faf6..cf0560a1077 100644
--- a/src/test/ui/numeric/numeric-cast.fixed
+++ b/src/test/ui/numeric/numeric-cast.fixed
@@ -49,7 +49,7 @@ fn main() {
     //~^ ERROR mismatched types
     foo::<isize>(x_u16.try_into().unwrap());
     //~^ ERROR mismatched types
-    foo::<isize>(x_u8.try_into().unwrap());
+    foo::<isize>(x_u8.into());
     //~^ ERROR mismatched types
     foo::<isize>(x_isize);
     foo::<isize>(x_i64.try_into().unwrap());
@@ -89,11 +89,11 @@ fn main() {
     //~^ ERROR mismatched types
     foo::<i64>(x_u64.try_into().unwrap());
     //~^ ERROR mismatched types
-    foo::<i64>(x_u32.try_into().unwrap());
+    foo::<i64>(x_u32.into());
     //~^ ERROR mismatched types
-    foo::<i64>(x_u16.try_into().unwrap());
+    foo::<i64>(x_u16.into());
     //~^ ERROR mismatched types
-    foo::<i64>(x_u8.try_into().unwrap());
+    foo::<i64>(x_u8.into());
     //~^ ERROR mismatched types
     foo::<i64>(x_isize.try_into().unwrap());
     //~^ ERROR mismatched types
@@ -135,9 +135,9 @@ fn main() {
     //~^ ERROR mismatched types
     foo::<i32>(x_u32.try_into().unwrap());
     //~^ ERROR mismatched types
-    foo::<i32>(x_u16.try_into().unwrap());
+    foo::<i32>(x_u16.into());
     //~^ ERROR mismatched types
-    foo::<i32>(x_u8.try_into().unwrap());
+    foo::<i32>(x_u8.into());
     //~^ ERROR mismatched types
     foo::<i32>(x_isize.try_into().unwrap());
     //~^ ERROR mismatched types
@@ -181,7 +181,7 @@ fn main() {
     //~^ ERROR mismatched types
     foo::<i16>(x_u16.try_into().unwrap());
     //~^ ERROR mismatched types
-    foo::<i16>(x_u8.try_into().unwrap());
+    foo::<i16>(x_u8.into());
     //~^ ERROR mismatched types
     foo::<i16>(x_isize.try_into().unwrap());
     //~^ ERROR mismatched types
diff --git a/src/test/ui/numeric/numeric-cast.stderr b/src/test/ui/numeric/numeric-cast.stderr
index ff92a86c3a7..cc1aa72d214 100644
--- a/src/test/ui/numeric/numeric-cast.stderr
+++ b/src/test/ui/numeric/numeric-cast.stderr
@@ -141,12 +141,10 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:52:18
    |
 LL |     foo::<isize>(x_u8);
-   |                  ^^^^ expected `isize`, found `u8`
-   |
-help: you can convert an `u8` to `isize` and panic if the converted value wouldn't fit
-   |
-LL |     foo::<isize>(x_u8.try_into().unwrap());
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^
+   |                  |
+   |                  expected `isize`, found `u8`
+   |                  help: you can convert an `u8` to `isize`: `x_u8.into()`
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:55:18
@@ -307,34 +305,28 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:92:16
    |
 LL |     foo::<i64>(x_u32);
-   |                ^^^^^ expected `i64`, found `u32`
-   |
-help: you can convert an `u32` to `i64` and panic if the converted value wouldn't fit
-   |
-LL |     foo::<i64>(x_u32.try_into().unwrap());
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                ^^^^^
+   |                |
+   |                expected `i64`, found `u32`
+   |                help: you can convert an `u32` to `i64`: `x_u32.into()`
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:94:16
    |
 LL |     foo::<i64>(x_u16);
-   |                ^^^^^ expected `i64`, found `u16`
-   |
-help: you can convert an `u16` to `i64` and panic if the converted value wouldn't fit
-   |
-LL |     foo::<i64>(x_u16.try_into().unwrap());
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                ^^^^^
+   |                |
+   |                expected `i64`, found `u16`
+   |                help: you can convert an `u16` to `i64`: `x_u16.into()`
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:96:16
    |
 LL |     foo::<i64>(x_u8);
-   |                ^^^^ expected `i64`, found `u8`
-   |
-help: you can convert an `u8` to `i64` and panic if the converted value wouldn't fit
-   |
-LL |     foo::<i64>(x_u8.try_into().unwrap());
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^
+   |                ^^^^
+   |                |
+   |                expected `i64`, found `u8`
+   |                help: you can convert an `u8` to `i64`: `x_u8.into()`
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:98:16
@@ -506,23 +498,19 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:138:16
    |
 LL |     foo::<i32>(x_u16);
-   |                ^^^^^ expected `i32`, found `u16`
-   |
-help: you can convert an `u16` to `i32` and panic if the converted value wouldn't fit
-   |
-LL |     foo::<i32>(x_u16.try_into().unwrap());
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                ^^^^^
+   |                |
+   |                expected `i32`, found `u16`
+   |                help: you can convert an `u16` to `i32`: `x_u16.into()`
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:140:16
    |
 LL |     foo::<i32>(x_u8);
-   |                ^^^^ expected `i32`, found `u8`
-   |
-help: you can convert an `u8` to `i32` and panic if the converted value wouldn't fit
-   |
-LL |     foo::<i32>(x_u8.try_into().unwrap());
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^
+   |                ^^^^
+   |                |
+   |                expected `i32`, found `u8`
+   |                help: you can convert an `u8` to `i32`: `x_u8.into()`
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:142:16
@@ -709,12 +697,10 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:184:16
    |
 LL |     foo::<i16>(x_u8);
-   |                ^^^^ expected `i16`, found `u8`
-   |
-help: you can convert an `u8` to `i16` and panic if the converted value wouldn't fit
-   |
-LL |     foo::<i16>(x_u8.try_into().unwrap());
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^
+   |                ^^^^
+   |                |
+   |                expected `i16`, found `u8`
+   |                help: you can convert an `u8` to `i16`: `x_u8.into()`
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:186:16