Auto merge of #71689 - Dylan-DPC:rollup-8nyuwm1, r=Dylan-DPC

Rollup of 6 pull requests

Successful merges:

 - #71507 (Document unsafety in core::ptr)
 - #71572 (test iterator chain type length blowup)
 - #71617 (Suggest `into` instead of `try_into` if possible with int types)
 - #71627 (Fix wrong argument in autoderef process)
 - #71678 (Add an index page for nightly rustc docs.)
 - #71680 (Fix doc link to Eq trait from PartialEq trait)

Failed merges:

 - #71597 (Rename Unique::empty() -> Unique::dangling())

r? @ghost
This commit is contained in:
bors 2020-04-29 20:32:41 +00:00
commit fa51f810e5
11 changed files with 137 additions and 74 deletions

View File

@ -478,7 +478,11 @@ impl Step for Rustc {
// Build cargo command. // Build cargo command.
let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "doc"); 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); compile::rustc_cargo(builder, &mut cargo, target);
// Only include compiler crates, no dependencies of those, such as `libc`. // Only include compiler crates, no dependencies of those, such as `libc`.

View File

@ -191,6 +191,7 @@ use self::Ordering::*;
/// assert_eq!(x.eq(&y), false); /// assert_eq!(x.eq(&y), false);
/// ``` /// ```
/// ///
/// [`Eq`]: Eq
/// [`eq`]: PartialEq::eq /// [`eq`]: PartialEq::eq
/// [`ne`]: PartialEq::ne /// [`ne`]: PartialEq::ne
#[lang = "eq"] #[lang = "eq"]

View File

@ -65,8 +65,6 @@
//! [`write_volatile`]: ./fn.write_volatile.html //! [`write_volatile`]: ./fn.write_volatile.html
//! [`NonNull::dangling`]: ./struct.NonNull.html#method.dangling //! [`NonNull::dangling`]: ./struct.NonNull.html#method.dangling
// ignore-tidy-undocumented-unsafe
#![stable(feature = "rust1", since = "1.0.0")] #![stable(feature = "rust1", since = "1.0.0")]
use crate::cmp::Ordering; 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 /// // create a slice pointer when starting out with a pointer to the first element
/// let x = [5, 6, 7]; /// let x = [5, 6, 7];
/// let ptr = x.as_ptr(); /// let raw_pointer = x.as_ptr();
/// let slice = ptr::slice_from_raw_parts(ptr, 3); /// let slice = ptr::slice_from_raw_parts(raw_pointer, 3);
/// assert_eq!(unsafe { &*slice }[2], 7); /// assert_eq!(unsafe { &*slice }[2], 7);
/// ``` /// ```
#[inline] #[inline]
#[stable(feature = "slice_from_raw_parts", since = "1.42.0")] #[stable(feature = "slice_from_raw_parts", since = "1.42.0")]
#[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")] #[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] { 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 } 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 /// [`slice_from_raw_parts`]: fn.slice_from_raw_parts.html
/// [`from_raw_parts_mut`]: ../../std/slice/fn.from_raw_parts_mut.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] #[inline]
#[stable(feature = "slice_from_raw_parts", since = "1.42.0")] #[stable(feature = "slice_from_raw_parts", since = "1.42.0")]
#[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")] #[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] { 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 } unsafe { Repr { raw: FatPtr { data, len } }.rust_mut }
} }

View File

@ -7,8 +7,6 @@ use crate::mem;
use crate::ops::{CoerceUnsized, DispatchFromDyn}; use crate::ops::{CoerceUnsized, DispatchFromDyn};
use crate::ptr::Unique; use crate::ptr::Unique;
// ignore-tidy-undocumented-unsafe
/// `*mut T` but non-zero and covariant. /// `*mut T` but non-zero and covariant.
/// ///
/// This is often the correct thing to use when building data structures using /// 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")] #[rustc_const_stable(feature = "const_nonnull_dangling", since = "1.32.0")]
#[inline] #[inline]
pub const fn dangling() -> Self { 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 { unsafe {
let ptr = mem::align_of::<T>() as *mut T; let ptr = mem::align_of::<T>() as *mut T;
NonNull::new_unchecked(ptr) NonNull::new_unchecked(ptr)
@ -93,7 +94,12 @@ impl<T: ?Sized> NonNull<T> {
#[stable(feature = "nonnull", since = "1.25.0")] #[stable(feature = "nonnull", since = "1.25.0")]
#[inline] #[inline]
pub fn new(ptr: *mut T) -> Option<Self> { 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. /// 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")] #[rustc_const_stable(feature = "const_nonnull_cast", since = "1.32.0")]
#[inline] #[inline]
pub const fn cast<U>(self) -> NonNull<U> { 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) } 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> { impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
#[inline] #[inline]
fn from(unique: Unique<T>) -> Self { 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()) } 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> { impl<T: ?Sized> From<&mut T> for NonNull<T> {
#[inline] #[inline]
fn from(reference: &mut T) -> Self { fn from(reference: &mut T) -> Self {
// SAFETY: A mutable reference cannot be null.
unsafe { NonNull { pointer: reference as *mut T } } 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> { impl<T: ?Sized> From<&T> for NonNull<T> {
#[inline] #[inline]
fn from(reference: &T) -> Self { 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 } } unsafe { NonNull { pointer: reference as *const T } }
} }
} }

View File

@ -73,6 +73,8 @@ impl<T: Sized> Unique<T> {
// FIXME: rename to dangling() to match NonNull? // FIXME: rename to dangling() to match NonNull?
#[inline] #[inline]
pub const fn empty() -> Self { 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) } unsafe { Unique::new_unchecked(mem::align_of::<T>() as *mut T) }
} }
} }
@ -93,6 +95,7 @@ impl<T: ?Sized> Unique<T> {
#[inline] #[inline]
pub fn new(ptr: *mut T) -> Option<Self> { pub fn new(ptr: *mut T) -> Option<Self> {
if !ptr.is_null() { if !ptr.is_null() {
// SAFETY: The pointer has already been checked and is not null.
Some(unsafe { Unique { pointer: ptr as _, _marker: PhantomData } }) Some(unsafe { Unique { pointer: ptr as _, _marker: PhantomData } })
} else { } else {
None None
@ -128,6 +131,9 @@ impl<T: ?Sized> Unique<T> {
/// Casts to a pointer of another type. /// Casts to a pointer of another type.
#[inline] #[inline]
pub const fn cast<U>(self) -> Unique<U> { 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) } 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> { impl<T: ?Sized> From<&mut T> for Unique<T> {
#[inline] #[inline]
fn from(reference: &mut T) -> Self { fn from(reference: &mut T) -> Self {
// SAFETY: A mutable reference cannot be null
unsafe { Unique { pointer: reference as *mut T, _marker: PhantomData } } unsafe { Unique { pointer: reference as *mut T, _marker: PhantomData } }
} }
} }

View File

@ -114,10 +114,10 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
// <cur_ty as Deref> // <ty as Deref>
let trait_ref = TraitRef { let trait_ref = TraitRef {
def_id: tcx.lang_items().deref_trait()?, 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); let cause = traits::ObligationCause::misc(self.span, self.body_id);

View File

@ -767,7 +767,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
suggest_to_change_suffix_or_into(err, is_fallible); suggest_to_change_suffix_or_into(err, is_fallible);
true 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); suggest_to_change_suffix_or_into(err, true);
true true
} }

View File

@ -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<_>>();
}

View File

@ -15,27 +15,21 @@ error[E0308]: mismatched types
--> $DIR/numeric-cast-2.rs:7:18 --> $DIR/numeric-cast-2.rs:7:18
| |
LL | let y: i64 = x + x; 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 | 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 error[E0308]: mismatched types
--> $DIR/numeric-cast-2.rs:9:18 --> $DIR/numeric-cast-2.rs:9:18
| |
LL | let z: i32 = x + x; 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 | 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 error: aborting due to 3 previous errors

View File

@ -49,7 +49,7 @@ fn main() {
//~^ ERROR mismatched types //~^ ERROR mismatched types
foo::<isize>(x_u16.try_into().unwrap()); foo::<isize>(x_u16.try_into().unwrap());
//~^ ERROR mismatched types //~^ ERROR mismatched types
foo::<isize>(x_u8.try_into().unwrap()); foo::<isize>(x_u8.into());
//~^ ERROR mismatched types //~^ ERROR mismatched types
foo::<isize>(x_isize); foo::<isize>(x_isize);
foo::<isize>(x_i64.try_into().unwrap()); foo::<isize>(x_i64.try_into().unwrap());
@ -89,11 +89,11 @@ fn main() {
//~^ ERROR mismatched types //~^ ERROR mismatched types
foo::<i64>(x_u64.try_into().unwrap()); foo::<i64>(x_u64.try_into().unwrap());
//~^ ERROR mismatched types //~^ ERROR mismatched types
foo::<i64>(x_u32.try_into().unwrap()); foo::<i64>(x_u32.into());
//~^ ERROR mismatched types //~^ ERROR mismatched types
foo::<i64>(x_u16.try_into().unwrap()); foo::<i64>(x_u16.into());
//~^ ERROR mismatched types //~^ ERROR mismatched types
foo::<i64>(x_u8.try_into().unwrap()); foo::<i64>(x_u8.into());
//~^ ERROR mismatched types //~^ ERROR mismatched types
foo::<i64>(x_isize.try_into().unwrap()); foo::<i64>(x_isize.try_into().unwrap());
//~^ ERROR mismatched types //~^ ERROR mismatched types
@ -135,9 +135,9 @@ fn main() {
//~^ ERROR mismatched types //~^ ERROR mismatched types
foo::<i32>(x_u32.try_into().unwrap()); foo::<i32>(x_u32.try_into().unwrap());
//~^ ERROR mismatched types //~^ ERROR mismatched types
foo::<i32>(x_u16.try_into().unwrap()); foo::<i32>(x_u16.into());
//~^ ERROR mismatched types //~^ ERROR mismatched types
foo::<i32>(x_u8.try_into().unwrap()); foo::<i32>(x_u8.into());
//~^ ERROR mismatched types //~^ ERROR mismatched types
foo::<i32>(x_isize.try_into().unwrap()); foo::<i32>(x_isize.try_into().unwrap());
//~^ ERROR mismatched types //~^ ERROR mismatched types
@ -181,7 +181,7 @@ fn main() {
//~^ ERROR mismatched types //~^ ERROR mismatched types
foo::<i16>(x_u16.try_into().unwrap()); foo::<i16>(x_u16.try_into().unwrap());
//~^ ERROR mismatched types //~^ ERROR mismatched types
foo::<i16>(x_u8.try_into().unwrap()); foo::<i16>(x_u8.into());
//~^ ERROR mismatched types //~^ ERROR mismatched types
foo::<i16>(x_isize.try_into().unwrap()); foo::<i16>(x_isize.try_into().unwrap());
//~^ ERROR mismatched types //~^ ERROR mismatched types

View File

@ -141,12 +141,10 @@ error[E0308]: mismatched types
--> $DIR/numeric-cast.rs:52:18 --> $DIR/numeric-cast.rs:52:18
| |
LL | foo::<isize>(x_u8); 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 | expected `isize`, found `u8`
| | help: you can convert an `u8` to `isize`: `x_u8.into()`
LL | foo::<isize>(x_u8.try_into().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/numeric-cast.rs:55:18 --> $DIR/numeric-cast.rs:55:18
@ -307,34 +305,28 @@ error[E0308]: mismatched types
--> $DIR/numeric-cast.rs:92:16 --> $DIR/numeric-cast.rs:92:16
| |
LL | foo::<i64>(x_u32); 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 | expected `i64`, found `u32`
| | help: you can convert an `u32` to `i64`: `x_u32.into()`
LL | foo::<i64>(x_u32.try_into().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/numeric-cast.rs:94:16 --> $DIR/numeric-cast.rs:94:16
| |
LL | foo::<i64>(x_u16); 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 | expected `i64`, found `u16`
| | help: you can convert an `u16` to `i64`: `x_u16.into()`
LL | foo::<i64>(x_u16.try_into().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/numeric-cast.rs:96:16 --> $DIR/numeric-cast.rs:96:16
| |
LL | foo::<i64>(x_u8); 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 | expected `i64`, found `u8`
| | help: you can convert an `u8` to `i64`: `x_u8.into()`
LL | foo::<i64>(x_u8.try_into().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/numeric-cast.rs:98:16 --> $DIR/numeric-cast.rs:98:16
@ -506,23 +498,19 @@ error[E0308]: mismatched types
--> $DIR/numeric-cast.rs:138:16 --> $DIR/numeric-cast.rs:138:16
| |
LL | foo::<i32>(x_u16); 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 | expected `i32`, found `u16`
| | help: you can convert an `u16` to `i32`: `x_u16.into()`
LL | foo::<i32>(x_u16.try_into().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/numeric-cast.rs:140:16 --> $DIR/numeric-cast.rs:140:16
| |
LL | foo::<i32>(x_u8); 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 | expected `i32`, found `u8`
| | help: you can convert an `u8` to `i32`: `x_u8.into()`
LL | foo::<i32>(x_u8.try_into().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/numeric-cast.rs:142:16 --> $DIR/numeric-cast.rs:142:16
@ -709,12 +697,10 @@ error[E0308]: mismatched types
--> $DIR/numeric-cast.rs:184:16 --> $DIR/numeric-cast.rs:184:16
| |
LL | foo::<i16>(x_u8); 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 | expected `i16`, found `u8`
| | help: you can convert an `u8` to `i16`: `x_u8.into()`
LL | foo::<i16>(x_u8.try_into().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/numeric-cast.rs:186:16 --> $DIR/numeric-cast.rs:186:16