diff options
309 files changed, 2239 insertions, 1293 deletions
diff --git a/Cargo.lock b/Cargo.lock index c1fa3bef07c..5c767817ae5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4345,9 +4345,9 @@ checksum = "ffbc596e092fe5f598b12ef46cc03754085ac2f4d8c739ad61c4ae266cc3b3fa" [[package]] name = "stacker" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72dd941b456e1c006d6b9f27c526d5b69281288aeea8cba82c19d3843d8ccdd2" +checksum = "a92bc346006ae78c539d6ab2cf1a1532bc657b8339c464877a990ec82073c66f" dependencies = [ "cc", "cfg-if", diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index 03b798d57db..fcd07befae5 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -385,6 +385,7 @@ pub trait Into<T>: Sized { ))] pub trait From<T>: Sized { /// Performs the conversion. + #[cfg_attr(not(bootstrap), lang = "from")] #[stable(feature = "rust1", since = "1.0.0")] fn from(_: T) -> Self; } diff --git a/library/core/src/future/future.rs b/library/core/src/future/future.rs index 733ebdc0e97..8169c146137 100644 --- a/library/core/src/future/future.rs +++ b/library/core/src/future/future.rs @@ -96,6 +96,7 @@ pub trait Future { /// [`Context`]: ../task/struct.Context.html /// [`Waker`]: ../task/struct.Waker.html /// [`Waker::wake`]: ../task/struct.Waker.html#method.wake + #[cfg_attr(not(bootstrap), lang = "poll")] #[stable(feature = "futures_api", since = "1.36.0")] fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>; } diff --git a/library/core/src/future/mod.rs b/library/core/src/future/mod.rs index 6d1ad9db744..d44ef857c13 100644 --- a/library/core/src/future/mod.rs +++ b/library/core/src/future/mod.rs @@ -53,6 +53,7 @@ unsafe impl Sync for ResumeTy {} /// This function returns a `GenFuture` underneath, but hides it in `impl Trait` to give /// better error messages (`impl Future` rather than `GenFuture<[closure.....]>`). // This is `const` to avoid extra errors after we recover from `const async fn` +#[cfg_attr(not(bootstrap), lang = "from_generator")] #[doc(hidden)] #[unstable(feature = "gen_future", issue = "50547")] #[inline] @@ -85,6 +86,7 @@ where GenFuture(gen) } +#[cfg_attr(not(bootstrap), lang = "get_context")] #[doc(hidden)] #[unstable(feature = "gen_future", issue = "50547")] #[inline] diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index 9d20022b6ed..84c7787a18f 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -235,6 +235,7 @@ pub trait IntoIterator { /// assert_eq!(Some(3), iter.next()); /// assert_eq!(None, iter.next()); /// ``` + #[cfg_attr(not(bootstrap), lang = "into_iter")] #[stable(feature = "rust1", since = "1.0.0")] fn into_iter(self) -> Self::IntoIter; } diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index f89b616c4e2..81d8f27ec19 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -129,6 +129,7 @@ pub trait Iterator { /// assert_eq!(None, iter.next()); /// assert_eq!(None, iter.next()); /// ``` + #[cfg_attr(not(bootstrap), lang = "next")] #[stable(feature = "rust1", since = "1.0.0")] fn next(&mut self) -> Option<Self::Item>; diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 763457d485d..3838fcf74cc 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -114,6 +114,7 @@ #![feature(optin_builtin_traits)] #![feature(or_patterns)] #![feature(prelude_import)] +#![feature(ptr_as_uninit)] #![feature(repr_simd, platform_intrinsics)] #![feature(rustc_attrs)] #![feature(simd_ffi)] diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs index 179038d1977..e9ab82b5398 100644 --- a/library/core/src/ops/range.rs +++ b/library/core/src/ops/range.rs @@ -38,6 +38,7 @@ use crate::hash::Hash; /// [`IntoIterator`]: ../iter/trait.Iterator.html /// [`Iterator`]: ../iter/trait.IntoIterator.html /// [slicing index]: ../slice/trait.SliceIndex.html +#[cfg_attr(not(bootstrap), lang = "RangeFull")] #[doc(alias = "..")] #[derive(Copy, Clone, Default, PartialEq, Eq, Hash)] #[stable(feature = "rust1", since = "1.0.0")] @@ -70,6 +71,7 @@ impl fmt::Debug for RangeFull { /// assert_eq!(arr[1.. 3], [ 1,2 ]); // Range /// assert_eq!(arr[1..=3], [ 1,2,3 ]); /// ``` +#[cfg_attr(not(bootstrap), lang = "Range")] #[doc(alias = "..")] #[derive(Clone, Default, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] @@ -178,6 +180,7 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> { /// ``` /// /// [`Iterator`]: ../iter/trait.IntoIterator.html +#[cfg_attr(not(bootstrap), lang = "RangeFrom")] #[doc(alias = "..")] #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] @@ -260,6 +263,7 @@ impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> { /// [`IntoIterator`]: ../iter/trait.Iterator.html /// [`Iterator`]: ../iter/trait.IntoIterator.html /// [slicing index]: ../slice/trait.SliceIndex.html +#[cfg_attr(not(bootstrap), lang = "RangeTo")] #[doc(alias = "..")] #[derive(Copy, Clone, PartialEq, Eq, Hash)] #[stable(feature = "rust1", since = "1.0.0")] @@ -328,6 +332,7 @@ impl<Idx: PartialOrd<Idx>> RangeTo<Idx> { /// assert_eq!(arr[1.. 3], [ 1,2 ]); /// assert_eq!(arr[1..=3], [ 1,2,3 ]); // RangeInclusive /// ``` +#[cfg_attr(not(bootstrap), lang = "RangeInclusive")] #[doc(alias = "..=")] #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "inclusive_range", since = "1.26.0")] @@ -359,6 +364,7 @@ impl<Idx> RangeInclusive<Idx> { /// /// assert_eq!(3..=5, RangeInclusive::new(3, 5)); /// ``` + #[cfg_attr(not(bootstrap), lang = "range_inclusive_new")] #[stable(feature = "inclusive_range_methods", since = "1.27.0")] #[inline] #[rustc_promotable] @@ -555,6 +561,7 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> { /// [`IntoIterator`]: ../iter/trait.Iterator.html /// [`Iterator`]: ../iter/trait.IntoIterator.html /// [slicing index]: ../slice/trait.SliceIndex.html +#[cfg_attr(not(bootstrap), lang = "RangeToInclusive")] #[doc(alias = "..=")] #[derive(Copy, Clone, PartialEq, Eq, Hash)] #[stable(feature = "inclusive_range", since = "1.26.0")] diff --git a/library/core/src/ops/try.rs b/library/core/src/ops/try.rs index 9bc35ae1f5c..e6b05cc641e 100644 --- a/library/core/src/ops/try.rs +++ b/library/core/src/ops/try.rs @@ -43,16 +43,19 @@ pub trait Try { /// in the return type of the enclosing scope (which must itself implement /// `Try`). Specifically, the value `X::from_error(From::from(e))` /// is returned, where `X` is the return type of the enclosing function. + #[cfg_attr(not(bootstrap), lang = "into_result")] #[unstable(feature = "try_trait", issue = "42327")] fn into_result(self) -> Result<Self::Ok, Self::Error>; /// Wrap an error value to construct the composite result. For example, /// `Result::Err(x)` and `Result::from_error(x)` are equivalent. + #[cfg_attr(not(bootstrap), lang = "from_error")] #[unstable(feature = "try_trait", issue = "42327")] fn from_error(v: Self::Error) -> Self; /// Wrap an OK value to construct the composite result. For example, /// `Result::Ok(x)` and `Result::from_ok(x)` are equivalent. + #[cfg_attr(not(bootstrap), lang = "from_ok")] #[unstable(feature = "try_trait", issue = "42327")] fn from_ok(v: Self::Ok) -> Self; } diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 6d078fb0a54..b6aa2c66971 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -144,9 +144,11 @@ use crate::{ #[stable(feature = "rust1", since = "1.0.0")] pub enum Option<T> { /// No value + #[cfg_attr(not(bootstrap), lang = "None")] #[stable(feature = "rust1", since = "1.0.0")] None, /// Some value `T` + #[cfg_attr(not(bootstrap), lang = "Some")] #[stable(feature = "rust1", since = "1.0.0")] Some(#[stable(feature = "rust1", since = "1.0.0")] T), } diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 960cccc0fb2..b63219a4403 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -569,6 +569,7 @@ impl<P: Deref> Pin<P> { /// ``` /// /// [`mem::swap`]: ../../std/mem/fn.swap.html + #[cfg_attr(not(bootstrap), lang = "new_unchecked")] #[stable(feature = "pin", since = "1.33.0")] #[inline(always)] pub unsafe fn new_unchecked(pointer: P) -> Pin<P> { diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index ac20897d258..7d7306574a6 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -2,7 +2,7 @@ use super::*; use crate::cmp::Ordering::{self, Equal, Greater, Less}; use crate::intrinsics; use crate::mem; -use crate::slice::SliceIndex; +use crate::slice::{self, SliceIndex}; #[lang = "const_ptr"] impl<T: ?Sized> *const T { @@ -13,6 +13,15 @@ impl<T: ?Sized> *const T { /// Therefore, two pointers that are null may still not compare equal to /// each other. /// + /// ## Behavior during const evaluation + /// + /// When this function is used during const evaluation, it may return `false` for pointers + /// that turn out to be null at runtime. Specifically, when a pointer to some memory + /// is offset beyond its bounds in such a way that the resulting pointer is null, + /// the function will still return `false`. There is no way for CTFE to know + /// the absolute position of that memory, so we cannot tell if the pointer is + /// null or not. + /// /// # Examples /// /// Basic usage: @@ -23,11 +32,12 @@ impl<T: ?Sized> *const T { /// assert!(!ptr.is_null()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")] #[inline] - pub fn is_null(self) -> bool { + pub const fn is_null(self) -> bool { // Compare via a cast to a thin pointer, so fat pointers are only // considering their "data" part for null-ness. - (self as *const u8) == null() + (self as *const u8).guaranteed_eq(null()) } /// Casts to a pointer of another type. @@ -38,32 +48,33 @@ impl<T: ?Sized> *const T { self as _ } - /// Returns `None` if the pointer is null, or else returns a reference to - /// the value wrapped in `Some`. + /// Returns `None` if the pointer is null, or else returns a shared reference to + /// the value wrapped in `Some`. If the value may be uninitialized, [`as_uninit_ref`] + /// must be used instead. /// - /// # Safety + /// [`as_uninit_ref`]: #method.as_uninit_ref /// - /// While this method and its mutable counterpart are useful for - /// null-safety, it is important to note that this is still an unsafe - /// operation because the returned value could be pointing to invalid - /// memory. + /// # Safety /// /// When calling this method, you have to ensure that *either* the pointer is NULL *or* /// all of the following is true: - /// - it is properly aligned - /// - it must point to an initialized instance of T; in particular, the pointer must be - /// "dereferenceable" in the sense defined [here]. + /// + /// * The pointer must be properly aligned. + /// + /// * It must be "dereferencable" in the sense defined in [the module documentation]. + /// + /// * The pointer must point to an initialized instance of `T`. + /// + /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is + /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. + /// In particular, for the duration of this lifetime, the memory the pointer points to must + /// not get mutated (except inside `UnsafeCell`). /// /// This applies even if the result of this method is unused! /// (The part about being initialized is not yet fully decided, but until /// it is, the only safe approach is to ensure that they are indeed initialized.) /// - /// Additionally, the lifetime `'a` returned is arbitrarily chosen and does - /// not necessarily reflect the actual lifetime of the data. *You* must enforce - /// Rust's aliasing rules. In particular, for the duration of this lifetime, - /// the memory the pointer points to must not get mutated (except inside `UnsafeCell`). - /// - /// [here]: crate::ptr#safety + /// [the module documentation]: crate::ptr#safety /// /// # Examples /// @@ -101,6 +112,56 @@ impl<T: ?Sized> *const T { if self.is_null() { None } else { unsafe { Some(&*self) } } } + /// Returns `None` if the pointer is null, or else returns a shared reference to + /// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require + /// that the value has to be initialized. + /// + /// [`as_ref`]: #method.as_ref + /// + /// # Safety + /// + /// When calling this method, you have to ensure that *either* the pointer is NULL *or* + /// all of the following is true: + /// + /// * The pointer must be properly aligned. + /// + /// * It must be "dereferencable" in the sense defined in [the module documentation]. + /// + /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is + /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. + /// In particular, for the duration of this lifetime, the memory the pointer points to must + /// not get mutated (except inside `UnsafeCell`). + /// + /// This applies even if the result of this method is unused! + /// + /// [the module documentation]: crate::ptr#safety + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(ptr_as_uninit)] + /// + /// let ptr: *const u8 = &10u8 as *const u8; + /// + /// unsafe { + /// if let Some(val_back) = ptr.as_uninit_ref() { + /// println!("We got back the value: {}!", val_back.assume_init()); + /// } + /// } + /// ``` + #[inline] + #[unstable(feature = "ptr_as_uninit", issue = "75402")] + pub unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit<T>> + where + T: Sized, + { + // SAFETY: the caller must guarantee that `self` meets all the + // requirements for a reference. + if self.is_null() { None } else { Some(unsafe { &*(self as *const MaybeUninit<T>) }) } + } + /// Calculates the offset from a pointer. /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer @@ -915,6 +976,55 @@ impl<T> *const [T] { // SAFETY: the caller ensures that `self` is dereferencable and `index` in-bounds. unsafe { index.get_unchecked(self) } } + + /// Returns `None` if the pointer is null, or else returns a shared slice to + /// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require + /// that the value has to be initialized. + /// + /// [`as_ref`]: #method.as_ref + /// + /// # Safety + /// + /// When calling this method, you have to ensure that *either* the pointer is NULL *or* + /// all of the following is true: + /// + /// * The pointer must be [valid] for reads for `ptr.len() * mem::size_of::<T>()` many bytes, + /// and it must be properly aligned. This means in particular: + /// + /// * The entire memory range of this slice must be contained within a single allocated object! + /// Slices can never span across multiple allocated objects. + /// + /// * The pointer must be aligned even for zero-length slices. One + /// reason for this is that enum layout optimizations may rely on references + /// (including slices of any length) being aligned and non-null to distinguish + /// them from other data. You can obtain a pointer that is usable as `data` + /// for zero-length slices using [`NonNull::dangling()`]. + /// + /// * The total size `ptr.len() * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`. + /// See the safety documentation of [`pointer::offset`]. + /// + /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is + /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. + /// In particular, for the duration of this lifetime, the memory the pointer points to must + /// not get mutated (except inside `UnsafeCell`). + /// + /// This applies even if the result of this method is unused! + /// + /// See also [`slice::from_raw_parts`][]. + /// + /// [valid]: crate::ptr#safety + /// [`NonNull::dangling()`]: NonNull::dangling + /// [`pointer::offset`]: ../std/primitive.pointer.html#method.offset + #[inline] + #[unstable(feature = "ptr_as_uninit", issue = "75402")] + pub unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit<T>]> { + if self.is_null() { + None + } else { + // SAFETY: the caller must uphold the safety contract for `as_uninit_slice`. + Some(unsafe { slice::from_raw_parts(self as *const MaybeUninit<T>, self.len()) }) + } + } } // Equality for pointers diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index df00139118a..3daeec36041 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1,7 +1,7 @@ use super::*; use crate::cmp::Ordering::{self, Equal, Greater, Less}; use crate::intrinsics; -use crate::slice::SliceIndex; +use crate::slice::{self, SliceIndex}; #[lang = "mut_ptr"] impl<T: ?Sized> *mut T { @@ -12,6 +12,15 @@ impl<T: ?Sized> *mut T { /// Therefore, two pointers that are null may still not compare equal to /// each other. /// + /// ## Behavior during const evaluation + /// + /// When this function is used during const evaluation, it may return `false` for pointers + /// that turn out to be null at runtime. Specifically, when a pointer to some memory + /// is offset beyond its bounds in such a way that the resulting pointer is null, + /// the function will still return `false`. There is no way for CTFE to know + /// the absolute position of that memory, so we cannot tell if the pointer is + /// null or not. + /// /// # Examples /// /// Basic usage: @@ -22,11 +31,12 @@ impl<T: ?Sized> *mut T { /// assert!(!ptr.is_null()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")] #[inline] - pub fn is_null(self) -> bool { + pub const fn is_null(self) -> bool { // Compare via a cast to a thin pointer, so fat pointers are only // considering their "data" part for null-ness. - (self as *mut u8) == null_mut() + (self as *mut u8).guaranteed_eq(null_mut()) } /// Casts to a pointer of another type. @@ -37,32 +47,36 @@ impl<T: ?Sized> *mut T { self as _ } - /// Returns `None` if the pointer is null, or else returns a reference to - /// the value wrapped in `Some`. + /// Returns `None` if the pointer is null, or else returns a shared reference to + /// the value wrapped in `Some`. If the value may be uninitialized, [`as_uninit_ref`] + /// must be used instead. /// - /// # Safety + /// For the mutable counterpart see [`as_mut`]. /// - /// While this method and its mutable counterpart are useful for - /// null-safety, it is important to note that this is still an unsafe - /// operation because the returned value could be pointing to invalid - /// memory. + /// [`as_uninit_ref`]: #method.as_uninit_ref-1 + /// [`as_mut`]: #method.as_mut + /// + /// # Safety /// /// When calling this method, you have to ensure that *either* the pointer is NULL *or* /// all of the following is true: - /// - it is properly aligned - /// - it must point to an initialized instance of T; in particular, the pointer must be - /// "dereferencable" in the sense defined [here]. + /// + /// * The pointer must be properly aligned. + /// + /// * It must be "dereferencable" in the sense defined in [the module documentation]. + /// + /// * The pointer must point to an initialized instance of `T`. + /// + /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is + /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. + /// In particular, for the duration of this lifetime, the memory the pointer points to must + /// not get mutated (except inside `UnsafeCell`). /// /// This applies even if the result of this method is unused! /// (The part about being initialized is not yet fully decided, but until /// it is, the only safe approach is to ensure that they are indeed initialized.) /// - /// Additionally, the lifetime `'a` returned is arbitrarily chosen and does - /// not necessarily reflect the actual lifetime of the data. *You* must enforce - /// Rust's aliasing rules. In particular, for the duration of this lifetime, - /// the memory the pointer points to must not get mutated (except inside `UnsafeCell`). - /// - /// [here]: crate::ptr#safety + /// [the module documentation]: crate::ptr#safety /// /// # Examples /// @@ -100,6 +114,59 @@ impl<T: ?Sized> *mut T { if self.is_null() { None } else { unsafe { Some(&*self) } } } + /// Returns `None` if the pointer is null, or else returns a shared reference to + /// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require + /// that the value has to be initialized. + /// + /// For the mutable counterpart see [`as_uninit_mut`]. + /// + /// [`as_ref`]: #method.as_ref-1 + /// [`as_uninit_mut`]: #method.as_uninit_mut + /// + /// # Safety + /// + /// When calling this method, you have to ensure that *either* the pointer is NULL *or* + /// all of the following is true: + /// + /// * The pointer must be properly aligned. + /// + /// * It must be "dereferencable" in the sense defined in [the module documentation]. + /// + /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is + /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. + /// In particular, for the duration of this lifetime, the memory the pointer points to must + /// not get mutated (except inside `UnsafeCell`). + /// + /// This applies even if the result of this method is unused! + /// + /// [the module documentation]: crate::ptr#safety + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(ptr_as_uninit)] + /// + /// let ptr: *mut u8 = &mut 10u8 as *mut u8; + /// + /// unsafe { + /// if let Some(val_back) = ptr.as_uninit_ref() { + /// println!("We got back the value: {}!", val_back.assume_init()); + /// } + /// } + /// ``` + #[inline] + #[unstable(feature = "ptr_as_uninit", issue = "75402")] + pub unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit<T>> + where + T: Sized, + { + // SAFETY: the caller must guarantee that `self` meets all the + // requirements for a reference. + if self.is_null() { None } else { Some(unsafe { &*(self as *const MaybeUninit<T>) }) } + } + /// Calculates the offset from a pointer. /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer @@ -225,33 +292,36 @@ impl<T: ?Sized> *mut T { unsafe { intrinsics::arith_offset(self, count) as *mut T } } - /// Returns `None` if the pointer is null, or else returns a mutable - /// reference to the value wrapped in `Some`. + /// Returns `None` if the pointer is null, or else returns a unique reference to + /// the value wrapped in `Some`. If the value may be uninitialized, [`as_uninit_mut`] + /// must be used instead. /// - /// # Safety + /// For the shared counterpart see [`as_ref`]. + /// + /// [`as_uninit_mut`]: #method.as_uninit_mut + /// [`as_ref`]: #method.as_ref-1 /// - /// As with [`as_ref`], this is unsafe because it cannot verify the validity - /// of the returned pointer, nor can it ensure that the lifetime `'a` - /// returned is indeed a valid lifetime for the contained data. + /// # Safety /// /// When calling this method, you have to ensure that *either* the pointer is NULL *or* /// all of the following is true: - /// - it is properly aligned - /// - it must point to an initialized instance of T; in particular, the pointer must be - /// "dereferenceable" in the sense defined [here]. + /// + /// * The pointer must be properly aligned. + /// + /// * It must be "dereferencable" in the sense defined in [the module documentation]. + /// + /// * The pointer must point to an initialized instance of `T`. + /// + /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is + /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. + /// In particular, for the duration of this lifetime, the memory the pointer points to must + /// not get accessed (read or written) through any other pointer. /// /// This applies even if the result of this method is unused! /// (The part about being initialized is not yet fully decided, but until - /// it is the only safe approach is to ensure that they are indeed initialized.) - /// - /// Additionally, the lifetime `'a` returned is arbitrarily chosen and does - /// not necessarily reflect the actual lifetime of the data. *You* must enforce - /// Rust's aliasing rules. In particular, for the duration of this lifetime, - /// the memory this pointer points to must not get accessed (read or written) - /// through any other pointer. + /// it is, the only safe approach is to ensure that they are indeed initialized.) /// - /// [here]: crate::ptr#safety - /// [`as_ref`]: #method.as_ref + /// [the module documentation]: crate::ptr#safety /// /// # Examples /// @@ -262,6 +332,7 @@ impl<T: ?Sized> *mut T { /// let ptr: *mut u32 = s.as_mut_ptr(); /// let first_value = unsafe { ptr.as_mut().unwrap() }; /// *first_value = 4; + /// # assert_eq!(s, [4, 2, 3]); /// println!("{:?}", s); // It'll print: "[4, 2, 3]". /// ``` /// @@ -276,6 +347,7 @@ impl<T: ?Sized> *mut T { /// let ptr: *mut u32 = s.as_mut_ptr(); /// let first_value = unsafe { &mut *ptr }; /// *first_value = 4; + /// # assert_eq!(s, [4, 2, 3]); /// println!("{:?}", s); // It'll print: "[4, 2, 3]". /// ``` #[stable(feature = "ptr_as_ref", since = "1.9.0")] @@ -286,6 +358,43 @@ impl<T: ?Sized> *mut T { if self.is_null() { None } else { unsafe { Some(&mut *self) } } } + /// Returns `None` if the pointer is null, or else returns a unique reference to + /// the value wrapped in `Some`. In contrast to [`as_mut`], this does not require + /// that the value has to be initialized. + /// + /// For the shared counterpart see [`as_uninit_ref`]. + /// + /// [`as_mut`]: #method.as_mut + /// [`as_uninit_ref`]: #method.as_uninit_ref-1 + /// + /// # Safety + /// + /// When calling this method, you have to ensure that *either* the pointer is NULL *or* + /// all of the following is true: + /// + /// * The pointer must be properly aligned. + /// + /// * It must be "dereferencable" in the sense defined in [the module documentation]. + /// + /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is + /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. + /// In particular, for the duration of this lifetime, the memory the pointer points to must + /// not get accessed (read or written) through any other pointer. + /// + /// This applies even if the result of this method is unused! + /// + /// [the module documentation]: crate::ptr#safety + #[inline] + #[unstable(feature = "ptr_as_uninit", issue = "75402")] + pub unsafe fn as_uninit_mut<'a>(self) -> Option<&'a mut MaybeUninit<T>> + where + T: Sized, + { + // SAFETY: the caller must guarantee that `self` meets all the + // requirements for a reference. + if self.is_null() { None } else { Some(unsafe { &mut *(self as *mut MaybeUninit<T>) }) } + } + /// Returns whether two pointers are guaranteed to be equal. /// /// At runtime this function behaves like `self == other`. @@ -1121,6 +1230,110 @@ impl<T> *mut [T] { // SAFETY: the caller ensures that `self` is dereferencable and `index` in-bounds. unsafe { index.get_unchecked_mut(self) } } + + /// Returns `None` if the pointer is null, or else returns a shared slice to + /// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require + /// that the value has to be initialized. + /// + /// For the mutable counterpart see [`as_uninit_slice_mut`]. + /// + /// [`as_ref`]: #method.as_ref-1 + /// [`as_uninit_slice_mut`]: #method.as_uninit_slice_mut + /// + /// # Safety + /// + /// When calling this method, you have to ensure that *either* the pointer is NULL *or* + /// all of the following is true: + /// + /// * The pointer must be [valid] for reads for `ptr.len() * mem::size_of::<T>()` many bytes, + /// and it must be properly aligned. This means in particular: + /// + /// * The entire memory range of this slice must be contained within a single allocated object! + /// Slices can never span across multiple allocated objects. + /// + /// * The pointer must be aligned even for zero-length slices. One + /// reason for this is that enum layout optimizations may rely on references + /// (including slices of any length) being aligned and non-null to distinguish + /// them from other data. You can obtain a pointer that is usable as `data` + /// for zero-length slices using [`NonNull::dangling()`]. + /// + /// * The total size `ptr.len() * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`. + /// See the safety documentation of [`pointer::offset`]. + /// + /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is + /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. + /// In particular, for the duration of this lifetime, the memory the pointer points to must + /// not get mutated (except inside `UnsafeCell`). + /// + /// This applies even if the result of this method is unused! + /// + /// See also [`slice::from_raw_parts`][]. + /// + /// [valid]: crate::ptr#safety + /// [`NonNull::dangling()`]: NonNull::dangling + /// [`pointer::offset`]: ../std/primitive.pointer.html#method.offset + #[inline] + #[unstable(feature = "ptr_as_uninit", issue = "75402")] + pub unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit<T>]> { + if self.is_null() { + None + } else { + // SAFETY: the caller must uphold the safety contract for `as_uninit_slice`. + Some(unsafe { slice::from_raw_parts(self as *const MaybeUninit<T>, self.len()) }) + } + } + + /// Returns `None` if the pointer is null, or else returns a unique slice to + /// the value wrapped in `Some`. In contrast to [`as_mut`], this does not require + /// that the value has to be initialized. + /// + /// For the shared counterpart see [`as_uninit_slice`]. + /// + /// [`as_mut`]: #method.as_mut + /// [`as_uninit_slice`]: #method.as_uninit_slice-1 + /// + /// # Safety + /// + /// When calling this method, you have to ensure that *either* the pointer is NULL *or* + /// all of the following is true: + /// + /// * The pointer must be [valid] for reads and writes for `ptr.len() * mem::size_of::<T>()` + /// many bytes, and it must be properly aligned. This means in particular: + /// + /// * The entire memory range of this slice must be contained within a single allocated object! + /// Slices can never span across multiple allocated objects. + /// + /// * The pointer must be aligned even for zero-length slices. One + /// reason for this is that enum layout optimizations may rely on references + /// (including slices of any length) being aligned and non-null to distinguish + /// them from other data. You can obtain a pointer that is usable as `data` + /// for zero-length slices using [`NonNull::dangling()`]. + /// + /// * The total size `ptr.len() * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`. + /// See the safety documentation of [`pointer::offset`]. + /// + /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is + /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. + /// In particular, for the duration of this lifetime, the memory the pointer points to must + /// not get accessed (read or written) through any other pointer. + /// + /// This applies even if the result of this method is unused! + /// + /// See also [`slice::from_raw_parts_mut`][]. + /// + /// [valid]: crate::ptr#safety + /// [`NonNull::dangling()`]: NonNull::dangling + /// [`pointer::offset`]: ../std/primitive.pointer.html#method.offset + #[inline] + #[unstable(feature = "ptr_as_uninit", issue = "75402")] + pub unsafe fn as_uninit_slice_mut<'a>(self) -> Option<&'a mut [MaybeUninit<T>]> { + if self.is_null() { + None + } else { + // SAFETY: the caller must uphold the safety contract for `as_uninit_slice_mut`. + Some(unsafe { slice::from_raw_parts_mut(self as *mut MaybeUninit<T>, self.len()) }) + } + } } // Equality for pointers diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index d876ab23653..294a3173d0c 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -3,10 +3,10 @@ use crate::convert::From; use crate::fmt; use crate::hash; use crate::marker::Unsize; -use crate::mem; +use crate::mem::{self, MaybeUninit}; use crate::ops::{CoerceUnsized, DispatchFromDyn}; use crate::ptr::Unique; -use crate::slice::SliceIndex; +use crate::slice::{self, SliceIndex}; /// `*mut T` but non-zero and covariant. /// @@ -76,6 +76,70 @@ impl<T: Sized> NonNull<T> { NonNull::new_unchecked(ptr) } } + + /// Returns a shared references to the value. In contrast to [`as_ref`], this does not require + /// that the value has to be initialized. + /// + /// For the mutable counterpart see [`as_uninit_mut`]. + /// + /// [`as_ref`]: #method.as_ref + /// [`as_uninit_mut`]: #method.as_uninit_mut + /// + /// # Safety + /// + /// When calling this method, you have to ensure that all of the following is true: + /// + /// * The pointer must be properly aligned. + /// + /// * It must be "dereferencable" in the sense defined in [the module documentation]. + /// + /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is + /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. + /// In particular, for the duration of this lifetime, the memory the pointer points to must + /// not get mutated (except inside `UnsafeCell`). + /// + /// This applies even if the result of this method is unused! + /// + /// [the module documentation]: crate::ptr#safety + #[inline] + #[unstable(feature = "ptr_as_uninit", issue = "75402")] + pub unsafe fn as_uninit_ref(&self) -> &MaybeUninit<T> { + // SAFETY: the caller must guarantee that `self` meets all the + // requirements for a reference. + unsafe { &*self.cast().as_ptr() } + } + + /// Returns a unique references to the value. In contrast to [`as_mut`], this does not require + /// that the value has to be initialized. + /// + /// For the shared counterpart see [`as_uninit_ref`]. + /// + /// [`as_mut`]: #method.as_mut + /// [`as_uninit_ref`]: #method.as_uninit_ref + /// + /// # Safety + /// + /// When calling this method, you have to ensure that all of the following is true: + /// + /// * The pointer must be properly aligned. + /// + /// * It must be "dereferencable" in the sense defined in [the module documentation]. + /// + /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is + /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. + /// In particular, for the duration of this lifetime, the memory the pointer points to must + /// not get accessed (read or written) through any other pointer. + /// + /// This applies even if the result of this method is unused! + /// + /// [the module documentation]: crate::ptr#safety + #[inline] + #[unstable(feature = "ptr_as_uninit", issue = "75402")] + pub unsafe fn as_uninit_mut(&mut self) -> &mut MaybeUninit<T> { + // SAFETY: the caller must guarantee that `self` meets all the + // requirements for a reference. + unsafe { &mut *self.cast().as_ptr() } + } } impl<T: ?Sized> NonNull<T> { @@ -112,29 +176,34 @@ impl<T: ?Sized> NonNull<T> { self.pointer as *mut T } - /// Dereferences the content. + /// Returns a shared reference to the value. If the value may be uninitialized, [`as_uninit_ref`] + /// must be used instead. + /// + /// For the mutable counterpart see [`as_mut`]. /// - /// The resulting lifetime is bound to self so this behaves "as if" - /// it were actually an instance of T that is getting borrowed. If a longer - /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`. + /// [`as_uninit_ref`]: #method.as_uninit_ref + /// [`as_mut`]: #method.as_mut /// /// # Safety /// /// When calling this method, you have to ensure that all of the following is true: - /// - `self` is properly aligned - /// - `self` must point to an initialized instance of T; in particular, the pointer must be - /// "dereferencable" in the sense defined [here]. + /// + /// * The pointer must be properly aligned. + /// + /// * It must be "dereferencable" in the sense defined in [the module documentation]. + /// + /// * The pointer must point to an initialized instance of `T`. + /// + /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is + /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. + /// In particular, for the duration of this lifetime, the memory the pointer points to must + /// not get mutated (except inside `UnsafeCell`). /// /// This applies even if the result of this method is unused! /// (The part about being initialized is not yet fully decided, but until /// it is, the only safe approach is to ensure that they are indeed initialized.) /// - /// Additionally, the lifetime of `self` does not necessarily reflect the actual - /// lifetime of the data. *You* must enforce Rust's aliasing rules. In particular, - /// for the duration of this lifetime, the memory the pointer points to must not - /// get mutated (except inside `UnsafeCell`). - /// - /// [here]: crate::ptr#safety + /// [the module documentation]: crate::ptr#safety #[stable(feature = "nonnull", since = "1.25.0")] #[inline] pub unsafe fn as_ref(&self) -> &T { @@ -143,29 +212,34 @@ impl<T: ?Sized> NonNull<T> { unsafe { &*self.as_ptr() } } - /// Mutably dereferences the content. + /// Returns a unique reference to the value. If the value may be uninitialized, [`as_uninit_mut`] + /// must be used instead. + /// + /// For the shared counterpart see [`as_ref`]. /// - /// The resulting lifetime is bound to self so this behaves "as if" - /// it were actually an instance of T that is getting borrowed. If a longer - /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`. + /// [`as_uninit_mut`]: #method.as_uninit_mut + /// [`as_ref`]: #method.as_ref /// /// # Safety /// /// When calling this method, you have to ensure that all of the following is true: - /// - `self` is properly aligned - /// - `self` must point to an initialized instance of T; in particular, the pointer must be - /// "dereferenceable" in the sense defined [here]. + /// + /// * The pointer must be properly aligned. + /// + /// * It must be "dereferencable" in the sense defined in [the module documentation]. + /// + /// * The pointer must point to an initialized instance of `T`. + /// + /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is + /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. + /// In particular, for the duration of this lifetime, the memory the pointer points to must + /// not get accessed (read or written) through any other pointer. /// /// This applies even if the result of this method is unused! /// (The part about being initialized is not yet fully decided, but until - /// it is the only safe approach is to ensure that they are indeed initialized.) - /// - /// Additionally, the lifetime of `self` does not necessarily reflect the actual - /// lifetime of the data. *You* must enforce Rust's aliasing rules. In particular, - /// for the duration of this lifetime, the memory this pointer points to must not - /// get accessed (read or written) through any other pointer. + /// it is, the only safe approach is to ensure that they are indeed initialized.) /// - /// [here]: crate::ptr#safety + /// [the module documentation]: crate::ptr#safety #[stable(feature = "nonnull", since = "1.25.0")] #[inline] pub unsafe fn as_mut(&mut self) -> &mut T { @@ -278,6 +352,115 @@ impl<T> NonNull<[T]> { self.as_non_null_ptr().as_ptr() } + /// Returns a shared reference to a slice of possibly uninitialized values. In contrast to + /// [`as_ref`], this does not require that the value has to be initialized. + /// + /// For the mutable counterpart see [`as_uninit_slice_mut`]. + /// + /// [`as_ref`]: #method.as_ref + /// [`as_uninit_slice_mut`]: #method.as_uninit_slice_mut + /// + /// # Safety + /// + /// When calling this method, you have to ensure that all of the following is true: + /// + /// * The pointer must be [valid] for reads for `ptr.len() * mem::size_of::<T>()` many bytes, + /// and it must be properly aligned. This means in particular: + /// + /// * The entire memory range of this slice must be contained within a single allocated object! + /// Slices can never span across multiple allocated objects. + /// + /// * The pointer must be aligned even for zero-length slices. One + /// reason for this is that enum layout optimizations may rely on references + /// (including slices of any length) being aligned and non-null to distinguish + /// them from other data. You can obtain a pointer that is usable as `data` + /// for zero-length slices using [`NonNull::dangling()`]. + /// + /// * The total size `ptr.len() * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`. + /// See the safety documentation of [`pointer::offset`]. + /// + /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is + /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. + /// In particular, for the duration of this lifetime, the memory the pointer points to must + /// not get mutated (except inside `UnsafeCell`). + /// + /// This applies even if the result of this method is unused! + /// + /// See also [`slice::from_raw_parts`][]. + /// + /// [valid]: crate::ptr#safety + /// [`NonNull::dangling()`]: NonNull::dangling + /// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset + #[inline] + #[unstable(feature = "ptr_as_uninit", issue = "75402")] + pub unsafe fn as_uninit_slice(&self) -> &[MaybeUninit<T>] { + // SAFETY: the caller must uphold the safety contract for `as_uninit_slice`. + unsafe { slice::from_raw_parts(self.cast().as_ptr(), self.len()) } + } + + /// Returns a unique reference to a slice of possibly uninitialized values. In contrast to + /// [`as_mut`], this does not require that the value has to be initialized. + /// + /// For the shared counterpart see [`as_uninit_slice`]. + /// + /// [`as_mut`]: #method.as_mut + /// [`as_uninit_slice`]: #method.as_uninit_slice + /// + /// # Safety + /// + /// When calling this method, you have to ensure that all of the following is true: + /// + /// * The pointer must be [valid] for reads and writes for `ptr.len() * mem::size_of::<T>()` + /// many bytes, and it must be properly aligned. This means in particular: + /// + /// * The entire memory range of this slice must be contained within a single allocated object! + /// Slices can never span across multiple allocated objects. + /// + /// * The pointer must be aligned even for zero-length slices. One + /// reason for this is that enum layout optimizations may rely on references + /// (including slices of any length) being aligned and non-null to distinguish + /// them from other data. You can obtain a pointer that is usable as `data` + /// for zero-length slices using [`NonNull::dangling()`]. + /// + /// * The total size `ptr.len() * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`. + /// See the safety documentation of [`pointer::offset`]. + /// + /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is + /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. + /// In particular, for the duration of this lifetime, the memory the pointer points to must + /// not get accessed (read or written) through any other pointer. + /// + /// This applies even if the result of this method is unused! + /// + /// See also [`slice::from_raw_parts_mut`][]. + /// + /// [valid]: crate::ptr#safety + /// [`NonNull::dangling()`]: NonNull::dangling + /// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset + /// + /// # Examples + /// + /// ```rust + /// #![feature(allocator_api, ptr_as_uninit)] + /// + /// use std::alloc::{AllocRef, Layout, Global}; + /// use std::mem::MaybeUninit; + /// use std::ptr::NonNull; + /// + /// let memory: NonNull<[u8]> = Global.alloc(Layout::new::<[u8; 32]>())?; + /// // This is safe as `memory` is valid for reads and writes for `memory.len()` many bytes. + /// // Note that calling `memory.as_mut()` is not allowed here as the content may be uninitialized. + /// # #[allow(unused_variables)] + /// let slice: &mut [MaybeUninit<u8>] = unsafe { memory.as_uninit_slice_mut() }; + /// # Ok::<_, std::alloc::AllocErr>(()) + /// ``` + #[inline] + #[unstable(feature = "ptr_as_uninit", issue = "75402")] + pub unsafe fn as_uninit_slice_mut(&self) -> &mut [MaybeUninit<T>] { + // SAFETY: the caller must uphold the safety contract for `as_uninit_slice_mut`. + unsafe { slice::from_raw_parts_mut(self.cast().as_ptr(), self.len()) } + } + /// Returns a raw pointer to an element or subslice, without doing bounds /// checking. /// diff --git a/library/core/src/result.rs b/library/core/src/result.rs index e68dbf5215f..5eddcb2172a 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -246,10 +246,12 @@ use crate::{convert, fmt}; #[stable(feature = "rust1", since = "1.0.0")] pub enum Result<T, E> { /// Contains the success value + #[cfg_attr(not(bootstrap), lang = "Ok")] #[stable(feature = "rust1", since = "1.0.0")] Ok(#[stable(feature = "rust1", since = "1.0.0")] T), /// Contains the error value + #[cfg_attr(not(bootstrap), lang = "Err")] #[stable(feature = "rust1", since = "1.0.0")] Err(#[stable(feature = "rust1", since = "1.0.0")] E), } diff --git a/library/core/src/task/poll.rs b/library/core/src/task/poll.rs index b3a4bd20b8f..fea396d20ff 100644 --- a/library/core/src/task/poll.rs +++ b/library/core/src/task/poll.rs @@ -10,6 +10,7 @@ use crate::result::Result; #[stable(feature = "futures_api", since = "1.36.0")] pub enum Poll<T> { /// Represents that a value is immediately ready. + #[cfg_attr(not(bootstrap), lang = "Ready")] #[stable(feature = "futures_api", since = "1.36.0")] Ready(#[stable(feature = "futures_api", since = "1.36.0")] T), @@ -18,6 +19,7 @@ pub enum Poll<T> { /// When a function returns `Pending`, the function *must* also /// ensure that the current task is scheduled to be awoken when /// progress can be made. + #[cfg_attr(not(bootstrap), lang = "Pending")] #[stable(feature = "futures_api", since = "1.36.0")] Pending, } diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index 54272165fb1..74427199346 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -7,8 +7,6 @@ //! like `cdylib`s and `staticlib`s are guaranteed to use the [`System`] by //! default. //! -//! [`System`]: struct.System.html -//! //! # The `#[global_allocator]` attribute //! //! This attribute allows configuring the choice of global allocator. @@ -43,8 +41,6 @@ //! The attribute is used on a `static` item whose type implements the //! [`GlobalAlloc`] trait. This type can be provided by an external library: //! -//! [`GlobalAlloc`]: ../../core/alloc/trait.GlobalAlloc.html -//! //! ```rust,ignore (demonstrates crates.io usage) //! extern crate jemallocator; //! @@ -277,9 +273,6 @@ static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut()); /// about the allocation that failed. /// /// The allocation error hook is a global resource. -/// -/// [`set_alloc_error_hook`]: fn.set_alloc_error_hook.html -/// [`take_alloc_error_hook`]: fn.take_alloc_error_hook.html #[unstable(feature = "alloc_error_hook", issue = "51245")] pub fn set_alloc_error_hook(hook: fn(Layout)) { HOOK.store(hook as *mut (), Ordering::SeqCst); @@ -290,8 +283,6 @@ pub fn set_alloc_error_hook(hook: fn(Layout)) { /// *See also the function [`set_alloc_error_hook`].* /// /// If no custom hook is registered, the default hook will be returned. -/// -/// [`set_alloc_error_hook`]: fn.set_alloc_error_hook.html #[unstable(feature = "alloc_error_hook", issue = "51245")] pub fn take_alloc_error_hook() -> fn(Layout) { let hook = HOOK.swap(ptr::null_mut(), Ordering::SeqCst); diff --git a/library/std/src/ascii.rs b/library/std/src/ascii.rs index 5cd2a25b117..c9106136d34 100644 --- a/library/std/src/ascii.rs +++ b/library/std/src/ascii.rs @@ -10,9 +10,6 @@ //! //! The [`escape_default`] function provides an iterator over the bytes of an //! escaped version of the character given. -//! -//! [`AsciiExt`]: trait.AsciiExt.html -//! [`escape_default`]: fn.escape_default.html #![stable(feature = "rust1", since = "1.0.0")] @@ -52,7 +49,7 @@ pub trait AsciiExt { /// /// # Note /// - /// This method will be deprecated in favor of the identically-named + /// This method is deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. #[stable(feature = "rust1", since = "1.0.0")] fn is_ascii(&self) -> bool; @@ -69,10 +66,10 @@ pub trait AsciiExt { /// /// # Note /// - /// This method will be deprecated in favor of the identically-named + /// This method is deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. /// - /// [`make_ascii_uppercase`]: #tymethod.make_ascii_uppercase + /// [`make_ascii_uppercase`]: AsciiExt::make_ascii_uppercase /// [`str::to_uppercase`]: ../primitive.str.html#method.to_uppercase #[stable(feature = "rust1", since = "1.0.0")] #[allow(deprecated)] @@ -90,10 +87,10 @@ pub trait AsciiExt { /// /// # Note /// - /// This method will be deprecated in favor of the identically-named + /// This method is deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. /// - /// [`make_ascii_lowercase`]: #tymethod.make_ascii_lowercase + /// [`make_ascii_lowercase`]: AsciiExt::make_ascii_lowercase /// [`str::to_lowercase`]: ../primitive.str.html#method.to_lowercase #[stable(feature = "rust1", since = "1.0.0")] #[allow(deprecated)] @@ -106,7 +103,7 @@ pub trait AsciiExt { /// /// # Note /// - /// This method will be deprecated in favor of the identically-named + /// This method is deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. #[stable(feature = "rust1", since = "1.0.0")] fn eq_ignore_ascii_case(&self, other: &Self) -> bool; @@ -121,10 +118,10 @@ pub trait AsciiExt { /// /// # Note /// - /// This method will be deprecated in favor of the identically-named + /// This method is deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. /// - /// [`to_ascii_uppercase`]: #tymethod.to_ascii_uppercase + /// [`to_ascii_uppercase`]: AsciiExt::to_ascii_uppercase #[stable(feature = "ascii", since = "1.9.0")] fn make_ascii_uppercase(&mut self); @@ -138,10 +135,10 @@ pub trait AsciiExt { /// /// # Note /// - /// This method will be deprecated in favor of the identically-named + /// This method is deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. /// - /// [`to_ascii_lowercase`]: #tymethod.to_ascii_lowercase + /// [`to_ascii_lowercase`]: AsciiExt::to_ascii_lowercase #[stable(feature = "ascii", since = "1.9.0")] fn make_ascii_lowercase(&mut self); } diff --git a/library/std/src/env.rs b/library/std/src/env.rs index 6489e0709cb..387c588f4a0 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -7,9 +7,6 @@ //! There are several functions and structs in this module that have a //! counterpart ending in `os`. Those ending in `os` will return an [`OsString`] //! and those without will return a [`String`]. -//! -//! [`OsString`]: ../../std/ffi/struct.OsString.html -//! [`String`]: ../string/struct.String.html #![stable(feature = "env", since = "1.0.0")] @@ -31,9 +28,6 @@ use crate::sys::os as os_imp; /// * Current directory does not exist. /// * There are insufficient permissions to access the current directory. /// -/// [`PathBuf`]: ../../std/path/struct.PathBuf.html -/// [`Err`]: ../../std/result/enum.Result.html#method.err -/// /// # Examples /// /// ``` @@ -54,8 +48,6 @@ pub fn current_dir() -> io::Result<PathBuf> { /// /// Returns an [`Err`] if the operation fails. /// -/// [`Err`]: ../../std/result/enum.Result.html#method.err -/// /// # Examples /// /// ``` @@ -76,7 +68,7 @@ pub fn set_current_dir<P: AsRef<Path>>(path: P) -> io::Result<()> { /// This structure is created by the [`std::env::vars`] function. See its /// documentation for more. /// -/// [`std::env::vars`]: fn.vars.html +/// [`std::env::vars`]: vars #[stable(feature = "env", since = "1.0.0")] pub struct Vars { inner: VarsOs, @@ -87,7 +79,7 @@ pub struct Vars { /// This structure is created by the [`std::env::vars_os`] function. See /// its documentation for more. /// -/// [`std::env::vars_os`]: fn.vars_os.html +/// [`std::env::vars_os`]: vars_os #[stable(feature = "env", since = "1.0.0")] pub struct VarsOs { inner: os_imp::Env, @@ -106,7 +98,7 @@ pub struct VarsOs { /// environment is not valid unicode. If this is not desired, consider using the /// [`env::vars_os`] function. /// -/// [`env::vars_os`]: fn.vars_os.html +/// [`env::vars_os`]: vars_os /// /// # Examples /// @@ -222,8 +214,6 @@ fn _var(key: &OsStr) -> Result<String, VarError> { /// Fetches the environment variable `key` from the current process, returning /// [`None`] if the variable isn't set. /// -/// [`None`]: ../option/enum.Option.html#variant.None -/// /// # Panics /// /// This function may panic if `key` is empty, contains an ASCII equals sign @@ -254,7 +244,7 @@ fn _var_os(key: &OsStr) -> Option<OsString> { /// The error type for operations interacting with environment variables. /// Possibly returned from the [`env::var`] function. /// -/// [`env::var`]: fn.var.html +/// [`env::var`]: var #[derive(Debug, PartialEq, Eq, Clone)] #[stable(feature = "env", since = "1.0.0")] pub enum VarError { @@ -382,8 +372,7 @@ fn _remove_var(k: &OsStr) { /// This structure is created by the [`std::env::split_paths`] function. See its /// documentation for more. /// -/// [`PathBuf`]: ../../std/path/struct.PathBuf.html -/// [`std::env::split_paths`]: fn.split_paths.html +/// [`std::env::split_paths`]: split_paths #[stable(feature = "env", since = "1.0.0")] pub struct SplitPaths<'a> { inner: os_imp::SplitPaths<'a>, @@ -410,8 +399,6 @@ pub struct SplitPaths<'a> { /// None => println!("{} is not defined in the environment.", key) /// } /// ``` -/// -/// [`PathBuf`]: ../../std/path/struct.PathBuf.html #[stable(feature = "env", since = "1.0.0")] pub fn split_paths<T: AsRef<OsStr> + ?Sized>(unparsed: &T) -> SplitPaths<'_> { SplitPaths { inner: os_imp::split_paths(unparsed.as_ref()) } @@ -438,7 +425,7 @@ impl fmt::Debug for SplitPaths<'_> { /// The error type for operations on the `PATH` variable. Possibly returned from /// the [`env::join_paths`] function. /// -/// [`env::join_paths`]: fn.join_paths.html +/// [`env::join_paths`]: join_paths #[derive(Debug)] #[stable(feature = "env", since = "1.0.0")] pub struct JoinPathsError { @@ -450,14 +437,10 @@ pub struct JoinPathsError { /// /// # Errors /// -/// Returns an [`Err`][err] (containing an error message) if one of the input +/// Returns an [`Err`] (containing an error message) if one of the input /// [`Path`]s contains an invalid character for constructing the `PATH` /// variable (a double quote on Windows or a colon on Unix). /// -/// [`Path`]: ../../std/path/struct.Path.html -/// [`OsString`]: ../../std/ffi/struct.OsString.html -/// [err]: ../../std/result/enum.Result.html#variant.Err -/// /// # Examples /// /// Joining paths on a Unix-like platform: @@ -508,7 +491,7 @@ pub struct JoinPathsError { /// } /// ``` /// -/// [`env::split_paths`]: fn.split_paths.html +/// [`env::split_paths`]: split_paths #[stable(feature = "env", since = "1.0.0")] pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError> where @@ -688,8 +671,7 @@ pub fn current_exe() -> io::Result<PathBuf> { /// set to arbitrary text, and may not even exist. This means this property /// should not be relied upon for security purposes. /// -/// [`String`]: ../string/struct.String.html -/// [`std::env::args`]: ./fn.args.html +/// [`std::env::args`]: args #[stable(feature = "env", since = "1.0.0")] pub struct Args { inner: ArgsOs, @@ -705,8 +687,7 @@ pub struct Args { /// set to arbitrary text, and may not even exist. This means this property /// should not be relied upon for security purposes. /// -/// [`OsString`]: ../ffi/struct.OsString.html -/// [`std::env::args_os`]: ./fn.args_os.html +/// [`std::env::args_os`]: args_os #[stable(feature = "env", since = "1.0.0")] pub struct ArgsOs { inner: sys::args::Args, @@ -744,8 +725,6 @@ pub struct ArgsOs { /// println!("{}", argument); /// } /// ``` -/// -/// [`args_os`]: ./fn.args_os.html #[stable(feature = "env", since = "1.0.0")] pub fn args() -> Args { Args { inner: args_os() } diff --git a/library/std/src/error.rs b/library/std/src/error.rs index 3b4cb859dd4..1b7681bd4bb 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -40,10 +40,8 @@ use crate::string; /// provide its own errors while also revealing some of the implementation for /// debugging via [`source`] chains. /// -/// [`Result<T, E>`]: ../result/enum.Result.html -/// [`Display`]: ../fmt/trait.Display.html -/// [`Debug`]: ../fmt/trait.Debug.html -/// [`source`]: trait.Error.html#method.source +/// [`Result<T, E>`]: Result +/// [`source`]: Error::source #[stable(feature = "rust1", since = "1.0.0")] pub trait Error: Debug + Display { /// The lower-level source of this error, if any. @@ -164,8 +162,6 @@ mod private { impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> { /// Converts a type of [`Error`] into a box of dyn [`Error`]. /// - /// [`Error`]: ../error/trait.Error.html - /// /// # Examples /// /// ``` @@ -199,8 +195,6 @@ impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + /// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of /// dyn [`Error`] + [`Send`] + [`Sync`]. /// - /// [`Error`]: ../error/trait.Error.html - /// /// # Examples /// /// ``` @@ -238,8 +232,6 @@ impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + impl From<String> for Box<dyn Error + Send + Sync> { /// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. /// - /// [`Error`]: ../error/trait.Error.html - /// /// # Examples /// /// ``` @@ -283,8 +275,6 @@ impl From<String> for Box<dyn Error + Send + Sync> { impl From<String> for Box<dyn Error> { /// Converts a [`String`] into a box of dyn [`Error`]. /// - /// [`Error`]: ../error/trait.Error.html - /// /// # Examples /// /// ``` @@ -306,8 +296,6 @@ impl From<String> for Box<dyn Error> { impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> { /// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. /// - /// [`Error`]: ../error/trait.Error.html - /// /// # Examples /// /// ``` @@ -329,8 +317,6 @@ impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> { impl From<&str> for Box<dyn Error> { /// Converts a [`str`] into a box of dyn [`Error`]. /// - /// [`Error`]: ../error/trait.Error.html - /// /// # Examples /// /// ``` @@ -350,9 +336,6 @@ impl From<&str> for Box<dyn Error> { impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> { /// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. /// - /// [`Cow`]: ../borrow/enum.Cow.html - /// [`Error`]: ../error/trait.Error.html - /// /// # Examples /// /// ``` @@ -374,9 +357,6 @@ impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> { impl<'a> From<Cow<'a, str>> for Box<dyn Error> { /// Converts a [`Cow`] into a box of dyn [`Error`]. /// - /// [`Cow`]: ../borrow/enum.Cow.html - /// [`Error`]: ../error/trait.Error.html - /// /// # Examples /// /// ``` @@ -703,7 +683,7 @@ impl dyn Error { /// assert!(iter.next().is_none()); /// ``` /// - /// [`source`]: trait.Error.html#method.source + /// [`source`]: Error::source #[unstable(feature = "error_iter", issue = "58520")] #[inline] pub fn chain(&self) -> Chain<'_> { @@ -715,8 +695,6 @@ impl dyn Error { /// /// If you want to omit the initial error and only process /// its sources, use `skip(1)`. -/// -/// [`Error`]: trait.Error.html #[unstable(feature = "error_iter", issue = "58520")] #[derive(Clone, Debug)] pub struct Chain<'a> { diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index 6ad5519d34a..8fcb24033b1 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -30,10 +30,6 @@ pub use core::panic::{Location, PanicInfo}; /// purpose of this trait is to encode what types are safe to cross a [`catch_unwind`] /// boundary with no fear of unwind safety. /// -/// [`Send`]: ../marker/trait.Send.html -/// [`Sync`]: ../marker/trait.Sync.html -/// [`catch_unwind`]: ./fn.catch_unwind.html -/// /// ## What is unwind safety? /// /// In Rust a function can "return" early if it either panics or calls a @@ -99,8 +95,6 @@ pub use core::panic::{Location, PanicInfo}; /// above, the lack of `unsafe` means it is mostly an advisory. The /// [`AssertUnwindSafe`] wrapper struct can be used to force this trait to be /// implemented for any closed over variables passed to `catch_unwind`. -/// -/// [`AssertUnwindSafe`]: ./struct.AssertUnwindSafe.html #[stable(feature = "catch_unwind", since = "1.9.0")] #[rustc_on_unimplemented( message = "the type `{Self}` may not be safely transferred across an unwind boundary", @@ -116,9 +110,6 @@ pub auto trait UnwindSafe {} /// /// This is a "helper marker trait" used to provide impl blocks for the /// [`UnwindSafe`] trait, for more information see that documentation. -/// -/// [`UnsafeCell`]: ../cell/struct.UnsafeCell.html -/// [`UnwindSafe`]: ./trait.UnwindSafe.html #[stable(feature = "catch_unwind", since = "1.9.0")] #[rustc_on_unimplemented( message = "the type `{Self}` may contain interior mutability and a reference may not be safely \ @@ -138,7 +129,6 @@ pub auto trait RefUnwindSafe {} /// account. This wrapper struct is useful for a quick and lightweight /// annotation that a variable is indeed unwind safe. /// -/// [`catch_unwind`]: ./fn.catch_unwind.html /// # Examples /// /// One way to use `AssertUnwindSafe` is to assert that the entire closure @@ -352,8 +342,6 @@ impl<F: Future> Future for AssertUnwindSafe<F> { /// can fail on a regular basis. Additionally, this function is not guaranteed /// to catch all panics, see the "Notes" section below. /// -/// [`Result`]: ../result/enum.Result.html -/// /// The closure provided is required to adhere to the [`UnwindSafe`] trait to ensure /// that all captured variables are safe to cross this boundary. The purpose of /// this bound is to encode the concept of [exception safety][rfc] in the type @@ -362,9 +350,6 @@ impl<F: Future> Future for AssertUnwindSafe<F> { /// becomes a problem the [`AssertUnwindSafe`] wrapper struct can be used to quickly /// assert that the usage here is indeed unwind safe. /// -/// [`AssertUnwindSafe`]: ./struct.AssertUnwindSafe.html -/// [`UnwindSafe`]: ./trait.UnwindSafe.html -/// /// [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1236-stabilize-catch-panic.md /// /// # Notes @@ -399,8 +384,6 @@ pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> { /// This is designed to be used in conjunction with [`catch_unwind`] to, for /// example, carry a panic across a layer of C code. /// -/// [`catch_unwind`]: ./fn.catch_unwind.html -/// /// # Notes /// /// Note that panics in Rust are not always implemented via unwinding, but they diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 61261e82147..21874853839 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -204,7 +204,7 @@ target | std | host | notes `thumbv4t-none-eabi` | * | | ARMv4T T32 `x86_64-apple-ios-macabi` | ✓[^apple] | | Apple Catalyst `x86_64-apple-tvos` | *[^apple] | | x86 64-bit tvOS -`x86_64-linux-kernel` | ? | | Linux kernel modules +`x86_64-linux-kernel` | * | | Linux kernel modules `x86_64-pc-solaris` | ? | | `x86_64-pc-windows-msvc` | ✓ | | 64-bit Windows XP support `x86_64-unknown-cloudabi` | ✓ | | 64-bit CloudABI diff --git a/src/librustc_ast/lib.rs b/src/librustc_ast/lib.rs index fb5ce311826..b556c1a446b 100644 --- a/src/librustc_ast/lib.rs +++ b/src/librustc_ast/lib.rs @@ -51,6 +51,8 @@ pub mod token; pub mod tokenstream; pub mod visit; +pub use self::ast::*; + use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; /// Requirements for a `StableHashingContext` to be used in this crate. diff --git a/src/librustc_ast_lowering/expr.rs b/src/librustc_ast_lowering/expr.rs index f9e54903a66..df452825bba 100644 --- a/src/librustc_ast_lowering/expr.rs +++ b/src/librustc_ast_lowering/expr.rs @@ -1,8 +1,8 @@ use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs}; -use rustc_ast::ast::*; use rustc_ast::attr; use rustc_ast::ptr::P as AstP; +use rustc_ast::*; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::thin_vec::ThinVec; @@ -449,7 +449,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // `::std::ops::Try::from_ok($tail_expr)` block.expr = Some(this.wrap_in_try_constructor( - sym::from_ok, + hir::LangItem::TryFromOk, try_span, tail_expr, ok_wrapped_span, @@ -461,14 +461,13 @@ impl<'hir> LoweringContext<'_, 'hir> { fn wrap_in_try_constructor( &mut self, - method: Symbol, + lang_item: hir::LangItem, method_span: Span, expr: &'hir hir::Expr<'hir>, overall_span: Span, ) -> &'hir hir::Expr<'hir> { - let path = &[sym::ops, sym::Try, method]; let constructor = - self.arena.alloc(self.expr_std_path(method_span, path, None, ThinVec::new())); + self.arena.alloc(self.expr_lang_item_path(method_span, lang_item, ThinVec::new())); self.expr_call(overall_span, constructor, std::slice::from_ref(expr)) } @@ -558,12 +557,8 @@ impl<'hir> LoweringContext<'_, 'hir> { // `future::from_generator`: let unstable_span = self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone()); - let gen_future = self.expr_std_path( - unstable_span, - &[sym::future, sym::from_generator], - None, - ThinVec::new(), - ); + let gen_future = + self.expr_lang_item_path(unstable_span, hir::LangItem::FromGenerator, ThinVec::new()); // `future::from_generator(generator)`: hir::ExprKind::Call(self.arena.alloc(gen_future), arena_vec![self; generator]) @@ -630,23 +625,19 @@ impl<'hir> LoweringContext<'_, 'hir> { // Use of `await` outside of an async context, we cannot use `task_context` here. self.expr_err(span) }; - let pin_ty_id = self.next_id(); - let new_unchecked_expr_kind = self.expr_call_std_assoc_fn( - pin_ty_id, + let new_unchecked = self.expr_call_lang_item_fn_mut( span, - &[sym::pin, sym::Pin], - "new_unchecked", + hir::LangItem::PinNewUnchecked, arena_vec![self; ref_mut_pinned], ); - let new_unchecked = self.expr(span, new_unchecked_expr_kind, ThinVec::new()); - let get_context = self.expr_call_std_path_mut( + let get_context = self.expr_call_lang_item_fn_mut( gen_future_span, - &[sym::future, sym::get_context], + hir::LangItem::GetContext, arena_vec![self; task_context], ); - let call = self.expr_call_std_path( + let call = self.expr_call_lang_item_fn( span, - &[sym::future, sym::Future, sym::poll], + hir::LangItem::FuturePoll, arena_vec![self; new_unchecked, get_context], ); self.arena.alloc(self.expr_unsafe(call)) @@ -659,11 +650,8 @@ impl<'hir> LoweringContext<'_, 'hir> { let x_ident = Ident::with_dummy_span(sym::result); let (x_pat, x_pat_hid) = self.pat_ident(span, x_ident); let x_expr = self.expr_ident(span, x_ident, x_pat_hid); - let ready_pat = self.pat_std_enum( - span, - &[sym::task, sym::Poll, sym::Ready], - arena_vec![self; x_pat], - ); + let ready_field = self.single_pat_field(span, x_pat); + let ready_pat = self.pat_lang_item_variant(span, hir::LangItem::PollReady, ready_field); let break_x = self.with_loop_scope(loop_node_id, move |this| { let expr_break = hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr)); @@ -674,7 +662,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // `::std::task::Poll::Pending => {}` let pending_arm = { - let pending_pat = self.pat_std_enum(span, &[sym::task, sym::Poll, sym::Pending], &[]); + let pending_pat = self.pat_lang_item_variant(span, hir::LangItem::PollPending, &[]); let empty_block = self.expr_block_empty(span); self.arm(pending_pat, empty_block) }; @@ -842,16 +830,12 @@ impl<'hir> LoweringContext<'_, 'hir> { /// Desugar `<start>..=<end>` into `std::ops::RangeInclusive::new(<start>, <end>)`. fn lower_expr_range_closed(&mut self, span: Span, e1: &Expr, e2: &Expr) -> hir::ExprKind<'hir> { - let id = self.next_id(); let e1 = self.lower_expr_mut(e1); let e2 = self.lower_expr_mut(e2); - self.expr_call_std_assoc_fn( - id, - span, - &[sym::ops, sym::RangeInclusive], - "new", - arena_vec![self; e1, e2], - ) + let fn_path = hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, span); + let fn_expr = + self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), ThinVec::new())); + hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2]) } fn lower_expr_range( @@ -861,14 +845,14 @@ impl<'hir> LoweringContext<'_, 'hir> { e2: Option<&Expr>, lims: RangeLimits, ) -> hir::ExprKind<'hir> { - use rustc_ast::ast::RangeLimits::*; - - let path = match (e1, e2, lims) { - (None, None, HalfOpen) => sym::RangeFull, - (Some(..), None, HalfOpen) => sym::RangeFrom, - (None, Some(..), HalfOpen) => sym::RangeTo, - (Some(..), Some(..), HalfOpen) => sym::Range, - (None, Some(..), Closed) => sym::RangeToInclusive, + use rustc_ast::RangeLimits::*; + + let lang_item = match (e1, e2, lims) { + (None, None, HalfOpen) => hir::LangItem::RangeFull, + (Some(..), None, HalfOpen) => hir::LangItem::RangeFrom, + (None, Some(..), HalfOpen) => hir::LangItem::RangeTo, + (Some(..), Some(..), HalfOpen) => hir::LangItem::Range, + (None, Some(..), Closed) => hir::LangItem::RangeToInclusive, (Some(..), Some(..), Closed) => unreachable!(), (_, None, Closed) => { self.diagnostic().span_fatal(span, "inclusive range with no end").raise() @@ -883,16 +867,7 @@ impl<'hir> LoweringContext<'_, 'hir> { }), ); - let is_unit = fields.is_empty(); - let struct_path = [sym::ops, path]; - let struct_path = self.std_path(span, &struct_path, None, is_unit); - let struct_path = hir::QPath::Resolved(None, struct_path); - - if is_unit { - hir::ExprKind::Path(struct_path) - } else { - hir::ExprKind::Struct(self.arena.alloc(struct_path), fields, None) - } + hir::ExprKind::Struct(self.arena.alloc(hir::QPath::LangItem(lang_item, span)), fields, None) } fn lower_loop_destination(&mut self, destination: Option<(NodeId, Label)>) -> hir::Destination { @@ -1412,9 +1387,11 @@ impl<'hir> LoweringContext<'_, 'hir> { let match_expr = { let iter = self.expr_ident(desugared_span, iter, iter_pat_nid); let ref_mut_iter = self.expr_mut_addr_of(desugared_span, iter); - let next_path = &[sym::iter, sym::Iterator, sym::next]; - let next_expr = - self.expr_call_std_path(desugared_span, next_path, arena_vec![self; ref_mut_iter]); + let next_expr = self.expr_call_lang_item_fn( + desugared_span, + hir::LangItem::IteratorNext, + arena_vec![self; ref_mut_iter], + ); let arms = arena_vec![self; pat_arm, break_arm]; self.expr_match(desugared_span, next_expr, arms, hir::MatchSource::ForLoopDesugar) @@ -1472,8 +1449,11 @@ impl<'hir> LoweringContext<'_, 'hir> { // `match ::std::iter::IntoIterator::into_iter(<head>) { ... }` let into_iter_expr = { - let into_iter_path = &[sym::iter, sym::IntoIterator, sym::into_iter]; - self.expr_call_std_path(into_iter_span, into_iter_path, arena_vec![self; head]) + self.expr_call_lang_item_fn( + into_iter_span, + hir::LangItem::IntoIterIntoIter, + arena_vec![self; head], + ) }; let match_expr = self.arena.alloc(self.expr_match( @@ -1521,8 +1501,11 @@ impl<'hir> LoweringContext<'_, 'hir> { // expand <expr> let sub_expr = self.lower_expr_mut(sub_expr); - let path = &[sym::ops, sym::Try, sym::into_result]; - self.expr_call_std_path(unstable_span, path, arena_vec![self; sub_expr]) + self.expr_call_lang_item_fn( + unstable_span, + hir::LangItem::TryIntoResult, + arena_vec![self; sub_expr], + ) }; // `#[allow(unreachable_code)]` @@ -1558,12 +1541,19 @@ impl<'hir> LoweringContext<'_, 'hir> { let err_ident = Ident::with_dummy_span(sym::err); let (err_local, err_local_nid) = self.pat_ident(try_span, err_ident); let from_expr = { - let from_path = &[sym::convert, sym::From, sym::from]; let err_expr = self.expr_ident_mut(try_span, err_ident, err_local_nid); - self.expr_call_std_path(try_span, from_path, arena_vec![self; err_expr]) + self.expr_call_lang_item_fn( + try_span, + hir::LangItem::FromFrom, + arena_vec![self; err_expr], + ) }; - let from_err_expr = - self.wrap_in_try_constructor(sym::from_error, unstable_span, from_expr, try_span); + let from_err_expr = self.wrap_in_try_constructor( + hir::LangItem::TryFromError, + unstable_span, + from_expr, + try_span, + ); let thin_attrs = ThinVec::from(attrs); let catch_scope = self.catch_scopes.last().copied(); let ret_expr = if let Some(catch_node) = catch_scope { @@ -1674,63 +1664,32 @@ impl<'hir> LoweringContext<'_, 'hir> { self.arena.alloc(self.expr_call_mut(span, e, args)) } - // Note: associated functions must use `expr_call_std_path`. - fn expr_call_std_path_mut( + fn expr_call_lang_item_fn_mut( &mut self, span: Span, - path_components: &[Symbol], + lang_item: hir::LangItem, args: &'hir [hir::Expr<'hir>], ) -> hir::Expr<'hir> { - let path = - self.arena.alloc(self.expr_std_path(span, path_components, None, ThinVec::new())); + let path = self.arena.alloc(self.expr_lang_item_path(span, lang_item, ThinVec::new())); self.expr_call_mut(span, path, args) } - fn expr_call_std_path( + fn expr_call_lang_item_fn( &mut self, span: Span, - path_components: &[Symbol], + lang_item: hir::LangItem, args: &'hir [hir::Expr<'hir>], ) -> &'hir hir::Expr<'hir> { - self.arena.alloc(self.expr_call_std_path_mut(span, path_components, args)) - } - - // Create an expression calling an associated function of an std type. - // - // Associated functions cannot be resolved through the normal `std_path` function, - // as they are resolved differently and so cannot use `expr_call_std_path`. - // - // This function accepts the path component (`ty_path_components`) separately from - // the name of the associated function (`assoc_fn_name`) in order to facilitate - // separate resolution of the type and creation of a path referring to its associated - // function. - fn expr_call_std_assoc_fn( - &mut self, - ty_path_id: hir::HirId, - span: Span, - ty_path_components: &[Symbol], - assoc_fn_name: &str, - args: &'hir [hir::Expr<'hir>], - ) -> hir::ExprKind<'hir> { - let ty_path = self.std_path(span, ty_path_components, None, false); - let ty = - self.arena.alloc(self.ty_path(ty_path_id, span, hir::QPath::Resolved(None, ty_path))); - let fn_seg = self.arena.alloc(hir::PathSegment::from_ident(Ident::from_str(assoc_fn_name))); - let fn_path = hir::QPath::TypeRelative(ty, fn_seg); - let fn_expr = - self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), ThinVec::new())); - hir::ExprKind::Call(fn_expr, args) + self.arena.alloc(self.expr_call_lang_item_fn_mut(span, lang_item, args)) } - fn expr_std_path( + fn expr_lang_item_path( &mut self, span: Span, - components: &[Symbol], - params: Option<&'hir hir::GenericArgs<'hir>>, + lang_item: hir::LangItem, attrs: AttrVec, ) -> hir::Expr<'hir> { - let path = self.std_path(span, components, params, true); - self.expr(span, hir::ExprKind::Path(hir::QPath::Resolved(None, path)), attrs) + self.expr(span, hir::ExprKind::Path(hir::QPath::LangItem(lang_item, span)), attrs) } pub(super) fn expr_ident( diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index 699f5c9778a..473fb7ccc70 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -2,10 +2,10 @@ use super::{AnonymousLifetimeMode, LoweringContext, ParamMode}; use super::{ImplTraitContext, ImplTraitPosition}; use crate::Arena; -use rustc_ast::ast::*; use rustc_ast::node_id::NodeMap; use rustc_ast::ptr::P; use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor}; +use rustc_ast::*; use rustc_data_structures::fx::FxHashSet; use rustc_errors::struct_span_err; use rustc_hir as hir; diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 7cfde3fc6d2..31eedeaed0a 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -35,13 +35,12 @@ #![feature(or_patterns)] #![recursion_limit = "256"] -use rustc_ast::ast; -use rustc_ast::ast::*; use rustc_ast::node_id::NodeMap; use rustc_ast::token::{self, DelimToken, Nonterminal, Token}; use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree}; use rustc_ast::visit::{self, AssocCtxt, Visitor}; use rustc_ast::walk_list; +use rustc_ast::{self as ast, *}; use rustc_ast_pretty::pprust; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; @@ -85,8 +84,6 @@ const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF; rustc_hir::arena_types!(rustc_arena::declare_arena, [], 'tcx); struct LoweringContext<'a, 'hir: 'a> { - crate_root: Option<Symbol>, - /// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes. sess: &'a Session, @@ -189,16 +186,6 @@ pub trait ResolverAstLowering { /// This should only return `None` during testing. fn definitions(&mut self) -> &mut Definitions; - /// Given suffix `["b", "c", "d"]`, creates an AST path for `[::crate_root]::b::c::d` and - /// resolves it based on `is_value`. - fn resolve_str_path( - &mut self, - span: Span, - crate_root: Option<Symbol>, - components: &[Symbol], - ns: Namespace, - ) -> (ast::Path, Res<NodeId>); - fn lint_buffer(&mut self) -> &mut LintBuffer; fn next_node_id(&mut self) -> NodeId; @@ -305,7 +292,6 @@ pub fn lower_crate<'a, 'hir>( let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering"); LoweringContext { - crate_root: sess.parse_sess.injected_crate_name.get().copied(), sess, resolver, nt_to_tokenstream, @@ -2064,23 +2050,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }; // "<Output = T>" - let future_params = self.arena.alloc(hir::GenericArgs { + let future_args = self.arena.alloc(hir::GenericArgs { args: &[], bindings: arena_vec![self; self.output_ty_binding(span, output_ty)], parenthesized: false, }); - // ::std::future::Future<future_params> - let future_path = - self.std_path(span, &[sym::future, sym::Future], Some(future_params), false); - - hir::GenericBound::Trait( - hir::PolyTraitRef { - trait_ref: hir::TraitRef { path: future_path, hir_ref_id: self.next_id() }, - bound_generic_params: &[], - span, - }, - hir::TraitBoundModifier::None, + hir::GenericBound::LangItemTrait( + // ::std::future::Future<future_params> + hir::LangItem::FutureTraitLangItem, + span, + self.next_id(), + future_args, ) } @@ -2480,35 +2461,47 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } fn pat_ok(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> { - self.pat_std_enum(span, &[sym::result, sym::Result, sym::Ok], arena_vec![self; pat]) + let field = self.single_pat_field(span, pat); + self.pat_lang_item_variant(span, hir::LangItem::ResultOk, field) } fn pat_err(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> { - self.pat_std_enum(span, &[sym::result, sym::Result, sym::Err], arena_vec![self; pat]) + let field = self.single_pat_field(span, pat); + self.pat_lang_item_variant(span, hir::LangItem::ResultErr, field) } fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> { - self.pat_std_enum(span, &[sym::option, sym::Option, sym::Some], arena_vec![self; pat]) + let field = self.single_pat_field(span, pat); + self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field) } fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> { - self.pat_std_enum(span, &[sym::option, sym::Option, sym::None], &[]) + self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[]) } - fn pat_std_enum( + fn single_pat_field( &mut self, span: Span, - components: &[Symbol], - subpats: &'hir [&'hir hir::Pat<'hir>], - ) -> &'hir hir::Pat<'hir> { - let path = self.std_path(span, components, None, true); - let qpath = hir::QPath::Resolved(None, path); - let pt = if subpats.is_empty() { - hir::PatKind::Path(qpath) - } else { - hir::PatKind::TupleStruct(qpath, subpats, None) + pat: &'hir hir::Pat<'hir>, + ) -> &'hir [hir::FieldPat<'hir>] { + let field = hir::FieldPat { + hir_id: self.next_id(), + ident: Ident::new(sym::integer(0), span), + is_shorthand: false, + pat, + span, }; - self.pat(span, pt) + arena_vec![self; field] + } + + fn pat_lang_item_variant( + &mut self, + span: Span, + lang_item: hir::LangItem, + fields: &'hir [hir::FieldPat<'hir>], + ) -> &'hir hir::Pat<'hir> { + let qpath = hir::QPath::LangItem(lang_item, span); + self.pat(span, hir::PatKind::Struct(qpath, fields, false)) } fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, hir::HirId) { @@ -2541,42 +2534,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.arena.alloc(hir::Pat { hir_id: self.next_id(), kind, span }) } - /// Given a suffix `["b", "c", "d"]`, returns path `::std::b::c::d` when - /// `fld.cx.use_std`, and `::core::b::c::d` otherwise. - /// The path is also resolved according to `is_value`. - fn std_path( - &mut self, - span: Span, - components: &[Symbol], - params: Option<&'hir hir::GenericArgs<'hir>>, - is_value: bool, - ) -> &'hir hir::Path<'hir> { - let ns = if is_value { Namespace::ValueNS } else { Namespace::TypeNS }; - let (path, res) = self.resolver.resolve_str_path(span, self.crate_root, components, ns); - - let mut segments: Vec<_> = path - .segments - .iter() - .map(|segment| { - let res = self.expect_full_res(segment.id); - hir::PathSegment { - ident: segment.ident, - hir_id: Some(self.lower_node_id(segment.id)), - res: Some(self.lower_res(res)), - infer_args: true, - args: None, - } - }) - .collect(); - segments.last_mut().unwrap().args = params; - - self.arena.alloc(hir::Path { - span, - res: res.map_id(|_| panic!("unexpected `NodeId`")), - segments: self.arena.alloc_from_iter(segments), - }) - } - fn ty_path( &mut self, mut hir_id: hir::HirId, diff --git a/src/librustc_ast_lowering/pat.rs b/src/librustc_ast_lowering/pat.rs index 171856e7e63..cb7b7c0eb61 100644 --- a/src/librustc_ast_lowering/pat.rs +++ b/src/librustc_ast_lowering/pat.rs @@ -1,7 +1,7 @@ use super::{ImplTraitContext, LoweringContext, ParamMode}; -use rustc_ast::ast::*; use rustc_ast::ptr::P; +use rustc_ast::*; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::Applicability; use rustc_hir as hir; diff --git a/src/librustc_ast_lowering/path.rs b/src/librustc_ast_lowering/path.rs index 2541d6824fe..cf68dfb9ae1 100644 --- a/src/librustc_ast_lowering/path.rs +++ b/src/librustc_ast_lowering/path.rs @@ -1,7 +1,7 @@ use super::{AnonymousLifetimeMode, ImplTraitContext, LoweringContext, ParamMode}; use super::{GenericArgsCtor, ParenthesizedGenericArgs}; -use rustc_ast::ast::{self, *}; +use rustc_ast::{self as ast, *}; use rustc_errors::{struct_span_err, Applicability}; use rustc_hir as hir; use rustc_hir::def::{DefKind, PartialRes, Res}; diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index 3c2a063cf24..a01dd8c939c 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -7,10 +7,10 @@ // or type checking or some other kind of complex analysis. use itertools::{Either, Itertools}; -use rustc_ast::ast::*; use rustc_ast::ptr::P; use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor}; use rustc_ast::walk_list; +use rustc_ast::*; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{error_code, pluralize, struct_span_err, Applicability}; diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index ce39ceff8f3..b15792dfd4c 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -1,6 +1,7 @@ -use rustc_ast::ast::{self, AssocTyConstraint, AssocTyConstraintKind, NodeId}; -use rustc_ast::ast::{GenericParam, GenericParamKind, PatKind, RangeEnd, VariantData}; +use rustc_ast as ast; use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor}; +use rustc_ast::{AssocTyConstraint, AssocTyConstraintKind, NodeId}; +use rustc_ast::{GenericParam, GenericParamKind, PatKind, RangeEnd, VariantData}; use rustc_errors::struct_span_err; use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP}; use rustc_feature::{Features, GateIssue}; diff --git a/src/librustc_ast_passes/node_count.rs b/src/librustc_ast_passes/node_count.rs index 34db59b1b45..706dca2b7f4 100644 --- a/src/librustc_ast_passes/node_count.rs +++ b/src/librustc_ast_passes/node_count.rs @@ -1,7 +1,7 @@ // Simply gives a rough count of the number of nodes in an AST. -use rustc_ast::ast::*; use rustc_ast::visit::*; +use rustc_ast::*; use rustc_span::symbol::Ident; use rustc_span::Span; diff --git a/src/librustc_ast_passes/show_span.rs b/src/librustc_ast_passes/show_span.rs index 2366426d4dc..053aba86222 100644 --- a/src/librustc_ast_passes/show_span.rs +++ b/src/librustc_ast_passes/show_span.rs @@ -5,7 +5,7 @@ use std::str::FromStr; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::visit; use rustc_ast::visit::Visitor; diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs index 9d9ca78de55..cb48deb5886 100644 --- a/src/librustc_ast_pretty/pprust.rs +++ b/src/librustc_ast_pretty/pprust.rs @@ -1,11 +1,6 @@ use crate::pp::Breaks::{Consistent, Inconsistent}; use crate::pp::{self, Breaks}; -use rustc_ast::ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax}; -use rustc_ast::ast::{Attribute, GenericArg, MacArgs}; -use rustc_ast::ast::{GenericBound, SelfKind, TraitBoundModifier}; -use rustc_ast::ast::{InlineAsmOperand, InlineAsmRegOrRegClass}; -use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_ast::attr; use rustc_ast::ptr::P; use rustc_ast::token::{self, BinOpToken, CommentKind, DelimToken, Nonterminal, Token, TokenKind}; @@ -13,6 +8,11 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_ast::util::classify; use rustc_ast::util::comments::{gather_comments, Comment, CommentStyle}; use rustc_ast::util::parser::{self, AssocOp, Fixity}; +use rustc_ast::{self as ast, BlockCheckMode, PatKind, RangeEnd, RangeSyntax}; +use rustc_ast::{GenericArg, MacArgs}; +use rustc_ast::{GenericBound, SelfKind, TraitBoundModifier}; +use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass}; +use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_span::edition::Edition; use rustc_span::source_map::{SourceMap, Spanned}; use rustc_span::symbol::{kw, sym, Ident, IdentPrinter, Symbol}; @@ -902,7 +902,7 @@ impl<'a> State<'a> { } } - crate fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod, attrs: &[Attribute]) { + crate fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod, attrs: &[ast::Attribute]) { self.print_inner_attributes(attrs); for item in &nmod.items { self.print_foreign_item(item); @@ -1666,7 +1666,7 @@ impl<'a> State<'a> { } } - fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>], attrs: &[Attribute]) { + fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>], attrs: &[ast::Attribute]) { self.ibox(INDENT_UNIT); self.s.word("["); self.print_inner_attributes_inline(attrs); @@ -1679,7 +1679,7 @@ impl<'a> State<'a> { &mut self, element: &ast::Expr, count: &ast::AnonConst, - attrs: &[Attribute], + attrs: &[ast::Attribute], ) { self.ibox(INDENT_UNIT); self.s.word("["); @@ -1696,7 +1696,7 @@ impl<'a> State<'a> { path: &ast::Path, fields: &[ast::Field], wth: &Option<P<ast::Expr>>, - attrs: &[Attribute], + attrs: &[ast::Attribute], ) { self.print_path(path, true, 0); self.s.word("{"); @@ -1736,7 +1736,7 @@ impl<'a> State<'a> { self.s.word("}"); } - fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>], attrs: &[Attribute]) { + fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>], attrs: &[ast::Attribute]) { self.popen(); self.print_inner_attributes_inline(attrs); self.commasep_exprs(Inconsistent, &exprs[..]); diff --git a/src/librustc_ast_pretty/pprust/tests.rs b/src/librustc_ast_pretty/pprust/tests.rs index fdbd073255e..fdbf3feb900 100644 --- a/src/librustc_ast_pretty/pprust/tests.rs +++ b/src/librustc_ast_pretty/pprust/tests.rs @@ -1,6 +1,6 @@ use super::*; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_span::source_map::respan; use rustc_span::symbol::Ident; use rustc_span::with_default_session_globals; diff --git a/src/librustc_attr/builtin.rs b/src/librustc_attr/builtin.rs index 3ddabcc17f8..b8929fe0889 100644 --- a/src/librustc_attr/builtin.rs +++ b/src/librustc_attr/builtin.rs @@ -1,6 +1,6 @@ //! Parsing and validation of builtin attributes -use rustc_ast::ast::{self, Attribute, Lit, LitKind, MetaItem, MetaItemKind, NestedMetaItem}; +use rustc_ast::{self as ast, Attribute, Lit, LitKind, MetaItem, MetaItemKind, NestedMetaItem}; use rustc_ast_pretty::pprust; use rustc_errors::{struct_span_err, Applicability}; use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg}; diff --git a/src/librustc_builtin_macros/Cargo.toml b/src/librustc_builtin_macros/Cargo.toml index c612781153e..dee6fed317e 100644 --- a/src/librustc_builtin_macros/Cargo.toml +++ b/src/librustc_builtin_macros/Cargo.toml @@ -11,7 +11,7 @@ doctest = false [dependencies] rustc_parse_format = { path = "../librustc_parse_format" } -log = { package = "tracing", version = "0.1" } +tracing = "0.1" rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_builtin_macros/asm.rs b/src/librustc_builtin_macros/asm.rs index 52f86aa7e06..5dafd6b77ab 100644 --- a/src/librustc_builtin_macros/asm.rs +++ b/src/librustc_builtin_macros/asm.rs @@ -1,4 +1,4 @@ -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::ptr::P; use rustc_ast::token; use rustc_ast::tokenstream::TokenStream; diff --git a/src/librustc_builtin_macros/assert.rs b/src/librustc_builtin_macros/assert.rs index 166cd628350..25181715540 100644 --- a/src/librustc_builtin_macros/assert.rs +++ b/src/librustc_builtin_macros/assert.rs @@ -1,9 +1,9 @@ use rustc_errors::{Applicability, DiagnosticBuilder}; -use rustc_ast::ast::{self, *}; use rustc_ast::ptr::P; use rustc_ast::token::{self, TokenKind}; use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree}; +use rustc_ast::{self as ast, *}; use rustc_ast_pretty::pprust; use rustc_expand::base::*; use rustc_parse::parser::Parser; diff --git a/src/librustc_builtin_macros/cfg.rs b/src/librustc_builtin_macros/cfg.rs index 0247ca32991..4c00162b556 100644 --- a/src/librustc_builtin_macros/cfg.rs +++ b/src/librustc_builtin_macros/cfg.rs @@ -2,7 +2,7 @@ //! a literal `true` or `false` based on whether the given cfg matches the //! current compilation environment. -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::token; use rustc_ast::tokenstream::TokenStream; use rustc_attr as attr; diff --git a/src/librustc_builtin_macros/cfg_accessible.rs b/src/librustc_builtin_macros/cfg_accessible.rs index 7a91dde5a9d..75f4b077640 100644 --- a/src/librustc_builtin_macros/cfg_accessible.rs +++ b/src/librustc_builtin_macros/cfg_accessible.rs @@ -1,6 +1,6 @@ //! Implementation of the `#[cfg_accessible(path)]` attribute macro. -use rustc_ast::ast; +use rustc_ast as ast; use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier}; use rustc_feature::AttributeTemplate; use rustc_parse::validate_attr; diff --git a/src/librustc_builtin_macros/cmdline_attrs.rs b/src/librustc_builtin_macros/cmdline_attrs.rs index 093815dbbcd..34e2accc615 100644 --- a/src/librustc_builtin_macros/cmdline_attrs.rs +++ b/src/librustc_builtin_macros/cmdline_attrs.rs @@ -1,8 +1,8 @@ //! Attributes injected into the crate root from command line using `-Z crate-attr`. -use rustc_ast::ast::{self, AttrItem, AttrStyle}; use rustc_ast::attr::mk_attr; use rustc_ast::token; +use rustc_ast::{self as ast, AttrItem, AttrStyle}; use rustc_session::parse::ParseSess; use rustc_span::FileName; diff --git a/src/librustc_builtin_macros/concat.rs b/src/librustc_builtin_macros/concat.rs index 4980ba0d9d3..e5077d93674 100644 --- a/src/librustc_builtin_macros/concat.rs +++ b/src/librustc_builtin_macros/concat.rs @@ -1,4 +1,4 @@ -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::tokenstream::TokenStream; use rustc_expand::base::{self, DummyResult}; use rustc_span::symbol::Symbol; diff --git a/src/librustc_builtin_macros/concat_idents.rs b/src/librustc_builtin_macros/concat_idents.rs index fdf05ac3880..8223cdda072 100644 --- a/src/librustc_builtin_macros/concat_idents.rs +++ b/src/librustc_builtin_macros/concat_idents.rs @@ -1,4 +1,4 @@ -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::ptr::P; use rustc_ast::token::{self, Token}; use rustc_ast::tokenstream::{TokenStream, TokenTree}; diff --git a/src/librustc_builtin_macros/deriving/bounds.rs b/src/librustc_builtin_macros/deriving/bounds.rs index cef0da60a61..12ef166b8b0 100644 --- a/src/librustc_builtin_macros/deriving/bounds.rs +++ b/src/librustc_builtin_macros/deriving/bounds.rs @@ -2,7 +2,7 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::path_std; -use rustc_ast::ast::MetaItem; +use rustc_ast::MetaItem; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::Span; diff --git a/src/librustc_builtin_macros/deriving/clone.rs b/src/librustc_builtin_macros/deriving/clone.rs index b307ee26c91..957c8035399 100644 --- a/src/librustc_builtin_macros/deriving/clone.rs +++ b/src/librustc_builtin_macros/deriving/clone.rs @@ -2,8 +2,8 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::path_std; -use rustc_ast::ast::{self, Expr, GenericArg, Generics, ItemKind, MetaItem, VariantData}; use rustc_ast::ptr::P; +use rustc_ast::{self as ast, Expr, GenericArg, Generics, ItemKind, MetaItem, VariantData}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; diff --git a/src/librustc_builtin_macros/deriving/cmp/eq.rs b/src/librustc_builtin_macros/deriving/cmp/eq.rs index d1b799cd6a1..79f35ad5819 100644 --- a/src/librustc_builtin_macros/deriving/cmp/eq.rs +++ b/src/librustc_builtin_macros/deriving/cmp/eq.rs @@ -2,8 +2,8 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::path_std; -use rustc_ast::ast::{self, Expr, GenericArg, MetaItem}; use rustc_ast::ptr::P; +use rustc_ast::{self as ast, Expr, GenericArg, MetaItem}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; diff --git a/src/librustc_builtin_macros/deriving/cmp/ord.rs b/src/librustc_builtin_macros/deriving/cmp/ord.rs index 3bf3860d323..c1473e24093 100644 --- a/src/librustc_builtin_macros/deriving/cmp/ord.rs +++ b/src/librustc_builtin_macros/deriving/cmp/ord.rs @@ -2,8 +2,8 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::path_std; -use rustc_ast::ast::{self, Expr, MetaItem}; use rustc_ast::ptr::P; +use rustc_ast::{self as ast, Expr, MetaItem}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; diff --git a/src/librustc_builtin_macros/deriving/cmp/partial_eq.rs b/src/librustc_builtin_macros/deriving/cmp/partial_eq.rs index d8edd641acd..8e9f15743cc 100644 --- a/src/librustc_builtin_macros/deriving/cmp/partial_eq.rs +++ b/src/librustc_builtin_macros/deriving/cmp/partial_eq.rs @@ -2,8 +2,8 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::{path_local, path_std}; -use rustc_ast::ast::{BinOpKind, Expr, MetaItem}; use rustc_ast::ptr::P; +use rustc_ast::{BinOpKind, Expr, MetaItem}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::sym; use rustc_span::Span; diff --git a/src/librustc_builtin_macros/deriving/cmp/partial_ord.rs b/src/librustc_builtin_macros/deriving/cmp/partial_ord.rs index 39a747c8568..21174ca4c8b 100644 --- a/src/librustc_builtin_macros/deriving/cmp/partial_ord.rs +++ b/src/librustc_builtin_macros/deriving/cmp/partial_ord.rs @@ -4,8 +4,8 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::{path_local, path_std, pathvec_std}; -use rustc_ast::ast::{self, BinOpKind, Expr, MetaItem}; use rustc_ast::ptr::P; +use rustc_ast::{self as ast, BinOpKind, Expr, MetaItem}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; diff --git a/src/librustc_builtin_macros/deriving/debug.rs b/src/librustc_builtin_macros/deriving/debug.rs index 76e21bc43c5..120e859f2b1 100644 --- a/src/librustc_builtin_macros/deriving/debug.rs +++ b/src/librustc_builtin_macros/deriving/debug.rs @@ -2,9 +2,8 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::path_std; -use rustc_ast::ast; -use rustc_ast::ast::{Expr, MetaItem}; use rustc_ast::ptr::P; +use rustc_ast::{self as ast, Expr, MetaItem}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{sym, Ident}; use rustc_span::{Span, DUMMY_SP}; diff --git a/src/librustc_builtin_macros/deriving/decodable.rs b/src/librustc_builtin_macros/deriving/decodable.rs index ce8c2dfe4d5..df69f6c90d8 100644 --- a/src/librustc_builtin_macros/deriving/decodable.rs +++ b/src/librustc_builtin_macros/deriving/decodable.rs @@ -4,9 +4,8 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::pathvec_std; -use rustc_ast::ast; -use rustc_ast::ast::{Expr, MetaItem, Mutability}; use rustc_ast::ptr::P; +use rustc_ast::{self as ast, Expr, MetaItem, Mutability}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; diff --git a/src/librustc_builtin_macros/deriving/default.rs b/src/librustc_builtin_macros/deriving/default.rs index 2611855a3a1..980be3a0050 100644 --- a/src/librustc_builtin_macros/deriving/default.rs +++ b/src/librustc_builtin_macros/deriving/default.rs @@ -1,8 +1,8 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; -use rustc_ast::ast::{Expr, MetaItem}; use rustc_ast::ptr::P; +use rustc_ast::{Expr, MetaItem}; use rustc_errors::struct_span_err; use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt}; use rustc_span::symbol::{kw, sym}; diff --git a/src/librustc_builtin_macros/deriving/encodable.rs b/src/librustc_builtin_macros/deriving/encodable.rs index 7a880357a59..62aa1cbfbf2 100644 --- a/src/librustc_builtin_macros/deriving/encodable.rs +++ b/src/librustc_builtin_macros/deriving/encodable.rs @@ -89,8 +89,8 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::pathvec_std; -use rustc_ast::ast::{Expr, ExprKind, MetaItem, Mutability}; use rustc_ast::ptr::P; +use rustc_ast::{Expr, ExprKind, MetaItem, Mutability}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; diff --git a/src/librustc_builtin_macros/deriving/generic/mod.rs b/src/librustc_builtin_macros/deriving/generic/mod.rs index 908aabe9024..accb0b3c949 100644 --- a/src/librustc_builtin_macros/deriving/generic/mod.rs +++ b/src/librustc_builtin_macros/deriving/generic/mod.rs @@ -181,9 +181,9 @@ use std::cell::RefCell; use std::iter; use std::vec; -use rustc_ast::ast::{self, BinOpKind, EnumDef, Expr, Generics, PatKind}; -use rustc_ast::ast::{GenericArg, GenericParamKind, VariantData}; use rustc_ast::ptr::P; +use rustc_ast::{self as ast, BinOpKind, EnumDef, Expr, Generics, PatKind}; +use rustc_ast::{GenericArg, GenericParamKind, VariantData}; use rustc_attr as attr; use rustc_data_structures::map_in_place::MapInPlace; use rustc_expand::base::{Annotatable, ExtCtxt}; diff --git a/src/librustc_builtin_macros/deriving/generic/ty.rs b/src/librustc_builtin_macros/deriving/generic/ty.rs index 51314dbcffc..6b7d0e1f204 100644 --- a/src/librustc_builtin_macros/deriving/generic/ty.rs +++ b/src/librustc_builtin_macros/deriving/generic/ty.rs @@ -4,8 +4,8 @@ pub use PtrTy::*; pub use Ty::*; -use rustc_ast::ast::{self, Expr, GenericArg, GenericParamKind, Generics, SelfKind}; use rustc_ast::ptr::P; +use rustc_ast::{self as ast, Expr, GenericArg, GenericParamKind, Generics, SelfKind}; use rustc_expand::base::ExtCtxt; use rustc_span::source_map::{respan, DUMMY_SP}; use rustc_span::symbol::{kw, Ident, Symbol}; diff --git a/src/librustc_builtin_macros/deriving/hash.rs b/src/librustc_builtin_macros/deriving/hash.rs index d7195188085..868f863b990 100644 --- a/src/librustc_builtin_macros/deriving/hash.rs +++ b/src/librustc_builtin_macros/deriving/hash.rs @@ -2,8 +2,8 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::{self, path_std, pathvec_std}; -use rustc_ast::ast::{Expr, MetaItem, Mutability}; use rustc_ast::ptr::P; +use rustc_ast::{Expr, MetaItem, Mutability}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::sym; use rustc_span::Span; diff --git a/src/librustc_builtin_macros/deriving/mod.rs b/src/librustc_builtin_macros/deriving/mod.rs index 33c0edde98f..7e3fd131d44 100644 --- a/src/librustc_builtin_macros/deriving/mod.rs +++ b/src/librustc_builtin_macros/deriving/mod.rs @@ -1,7 +1,8 @@ //! The compiler code necessary to implement the `#[derive]` extensions. -use rustc_ast::ast::{self, ItemKind, MetaItem}; +use rustc_ast as ast; use rustc_ast::ptr::P; +use rustc_ast::{ItemKind, MetaItem}; use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier}; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; diff --git a/src/librustc_builtin_macros/env.rs b/src/librustc_builtin_macros/env.rs index b6f733ee93d..6de12acfb94 100644 --- a/src/librustc_builtin_macros/env.rs +++ b/src/librustc_builtin_macros/env.rs @@ -3,8 +3,8 @@ // interface. // -use rustc_ast::ast::{self, GenericArg}; use rustc_ast::tokenstream::TokenStream; +use rustc_ast::{self as ast, GenericArg}; use rustc_expand::base::{self, *}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; diff --git a/src/librustc_builtin_macros/format.rs b/src/librustc_builtin_macros/format.rs index 78cead02b7b..373277f525d 100644 --- a/src/librustc_builtin_macros/format.rs +++ b/src/librustc_builtin_macros/format.rs @@ -1,7 +1,7 @@ use ArgumentType::*; use Position::*; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::ptr::P; use rustc_ast::token; use rustc_ast::tokenstream::TokenStream; diff --git a/src/librustc_builtin_macros/global_allocator.rs b/src/librustc_builtin_macros/global_allocator.rs index ccff8aa90a8..c37adb7baa0 100644 --- a/src/librustc_builtin_macros/global_allocator.rs +++ b/src/librustc_builtin_macros/global_allocator.rs @@ -1,11 +1,11 @@ use crate::util::check_builtin_macro_attribute; -use rustc_ast::ast::{self, Attribute, Expr, FnHeader, FnSig, Generics, Param}; -use rustc_ast::ast::{ItemKind, Mutability, Stmt, Ty, TyKind, Unsafe}; use rustc_ast::expand::allocator::{ AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS, }; use rustc_ast::ptr::P; +use rustc_ast::{self as ast, Attribute, Expr, FnHeader, FnSig, Generics, Param}; +use rustc_ast::{ItemKind, Mutability, Stmt, Ty, TyKind, Unsafe}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; diff --git a/src/librustc_builtin_macros/global_asm.rs b/src/librustc_builtin_macros/global_asm.rs index 2729239f62b..2465f33622e 100644 --- a/src/librustc_builtin_macros/global_asm.rs +++ b/src/librustc_builtin_macros/global_asm.rs @@ -8,7 +8,7 @@ //! LLVM's `module asm "some assembly here"`. All of LLVM's caveats //! therefore apply. -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::ptr::P; use rustc_ast::token; use rustc_ast::tokenstream::TokenStream; diff --git a/src/librustc_builtin_macros/llvm_asm.rs b/src/librustc_builtin_macros/llvm_asm.rs index 77fd71d58ef..db73fdbe24f 100644 --- a/src/librustc_builtin_macros/llvm_asm.rs +++ b/src/librustc_builtin_macros/llvm_asm.rs @@ -2,10 +2,11 @@ // use State::*; -use rustc_ast::ast::{self, LlvmAsmDialect}; +use rustc_ast as ast; use rustc_ast::ptr::P; use rustc_ast::token::{self, Token}; use rustc_ast::tokenstream::{self, TokenStream}; +use rustc_ast::LlvmAsmDialect; use rustc_errors::{struct_span_err, DiagnosticBuilder, PResult}; use rustc_expand::base::*; use rustc_parse::parser::Parser; diff --git a/src/librustc_builtin_macros/proc_macro_harness.rs b/src/librustc_builtin_macros/proc_macro_harness.rs index 4f2f066e652..0c6769906f3 100644 --- a/src/librustc_builtin_macros/proc_macro_harness.rs +++ b/src/librustc_builtin_macros/proc_macro_harness.rs @@ -1,9 +1,9 @@ use std::mem; -use rustc_ast::ast::{self, NodeId}; use rustc_ast::attr; use rustc_ast::ptr::P; use rustc_ast::visit::{self, Visitor}; +use rustc_ast::{self as ast, NodeId}; use rustc_ast_pretty::pprust; use rustc_expand::base::{ExtCtxt, ResolverExpand}; use rustc_expand::expand::{AstFragment, ExpansionConfig}; diff --git a/src/librustc_builtin_macros/source_util.rs b/src/librustc_builtin_macros/source_util.rs index e46cf67e64d..70753208af3 100644 --- a/src/librustc_builtin_macros/source_util.rs +++ b/src/librustc_builtin_macros/source_util.rs @@ -1,4 +1,4 @@ -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::ptr::P; use rustc_ast::token; use rustc_ast::tokenstream::TokenStream; diff --git a/src/librustc_builtin_macros/standard_library_imports.rs b/src/librustc_builtin_macros/standard_library_imports.rs index 52759fede75..e801b5c7b0c 100644 --- a/src/librustc_builtin_macros/standard_library_imports.rs +++ b/src/librustc_builtin_macros/standard_library_imports.rs @@ -1,4 +1,4 @@ -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::ptr::P; use rustc_expand::base::{ExtCtxt, ResolverExpand}; use rustc_expand::expand::ExpansionConfig; diff --git a/src/librustc_builtin_macros/test.rs b/src/librustc_builtin_macros/test.rs index 16a95288ee8..8e56e80bba2 100644 --- a/src/librustc_builtin_macros/test.rs +++ b/src/librustc_builtin_macros/test.rs @@ -2,7 +2,7 @@ /// Ideally, this code would be in libtest but for efficiency and error messages it lives here. use crate::util::check_builtin_macro_attribute; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::attr; use rustc_ast_pretty::pprust; use rustc_expand::base::*; @@ -299,7 +299,7 @@ pub fn expand_test_or_bench( // extern crate test let test_extern = cx.item(sp, test_id, vec![], ast::ItemKind::ExternCrate(None)); - log::debug!("synthetic test item:\n{}\n", pprust::item_to_string(&test_const)); + tracing::debug!("synthetic test item:\n{}\n", pprust::item_to_string(&test_const)); vec![ // Access to libtest under a hygienic name diff --git a/src/librustc_builtin_macros/test_harness.rs b/src/librustc_builtin_macros/test_harness.rs index b21a7c1e4d5..277cd8389e3 100644 --- a/src/librustc_builtin_macros/test_harness.rs +++ b/src/librustc_builtin_macros/test_harness.rs @@ -1,7 +1,6 @@ // Code that generates a test runner to run all the tests in a crate -use log::debug; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::attr; use rustc_ast::entry::EntryPointType; use rustc_ast::mut_visit::{ExpectOne, *}; @@ -16,6 +15,7 @@ use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::spec::PanicStrategy; use smallvec::{smallvec, SmallVec}; +use tracing::debug; use std::{iter, mem}; diff --git a/src/librustc_builtin_macros/util.rs b/src/librustc_builtin_macros/util.rs index 3ee6cd73964..01ea80c4c8a 100644 --- a/src/librustc_builtin_macros/util.rs +++ b/src/librustc_builtin_macros/util.rs @@ -1,4 +1,4 @@ -use rustc_ast::ast::MetaItem; +use rustc_ast::MetaItem; use rustc_expand::base::ExtCtxt; use rustc_feature::AttributeTemplate; use rustc_parse::validate_attr; diff --git a/src/librustc_codegen_llvm/Cargo.toml b/src/librustc_codegen_llvm/Cargo.toml index ec4dfabdcc2..2e4b9f22f81 100644 --- a/src/librustc_codegen_llvm/Cargo.toml +++ b/src/librustc_codegen_llvm/Cargo.toml @@ -15,7 +15,7 @@ bitflags = "1.0" flate2 = "1.0" libc = "0.2" measureme = "0.7.1" -log = { package = "tracing", version = "0.1" } +tracing = "0.1" rustc_middle = { path = "../librustc_middle" } rustc-demangle = "0.1" rustc_attr = { path = "../librustc_attr" } diff --git a/src/librustc_codegen_llvm/asm.rs b/src/librustc_codegen_llvm/asm.rs index fb2e1c43524..a6062de6bf8 100644 --- a/src/librustc_codegen_llvm/asm.rs +++ b/src/librustc_codegen_llvm/asm.rs @@ -5,8 +5,8 @@ use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; -use rustc_ast::ast::LlvmAsmDialect; -use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece}; +use rustc_ast::LlvmAsmDialect; +use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_codegen_ssa::mir::operand::OperandValue; use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::*; @@ -19,7 +19,7 @@ use rustc_target::abi::*; use rustc_target::asm::*; use libc::{c_char, c_uint}; -use log::debug; +use tracing::debug; impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { fn codegen_llvm_inline_asm( diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index 6b02b5e8120..7c710a1cb3d 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -4,7 +4,6 @@ use crate::back::write::{ use crate::llvm::archive_ro::ArchiveRO; use crate::llvm::{self, False, True}; use crate::{LlvmCodegenBackend, ModuleLlvm}; -use log::{debug, info}; use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared}; use rustc_codegen_ssa::back::symbol_export; use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, ModuleConfig}; @@ -18,6 +17,7 @@ use rustc_middle::dep_graph::WorkProduct; use rustc_middle::middle::exported_symbols::SymbolExportLevel; use rustc_session::cgu_reuse_tracker::CguReuse; use rustc_session::config::{self, CrateType, Lto}; +use tracing::{debug, info}; use std::ffi::{CStr, CString}; use std::fs::File; diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index 1a5794d1133..6f386c1287c 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -11,7 +11,6 @@ use crate::llvm_util; use crate::type_::Type; use crate::LlvmCodegenBackend; use crate::ModuleLlvm; -use log::debug; use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, ModuleConfig}; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::{CompiledModule, ModuleCodegen}; @@ -26,6 +25,7 @@ use rustc_session::Session; use rustc_span::symbol::sym; use rustc_span::InnerSpan; use rustc_target::spec::{CodeModel, RelocModel}; +use tracing::debug; use libc::{c_char, c_int, c_uint, c_void, size_t}; use std::ffi::CString; diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index a0f4311b33a..4737c73d57f 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -6,7 +6,6 @@ use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; use libc::{c_char, c_uint}; -use log::debug; use rustc_codegen_ssa::base::to_immediate; use rustc_codegen_ssa::common::{IntPredicate, RealPredicate, TypeKind}; use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; @@ -26,6 +25,7 @@ use std::ffi::CStr; use std::iter::TrustedLen; use std::ops::{Deref, Range}; use std::ptr; +use tracing::debug; // All Builders must have an llfn associated with them #[must_use] @@ -303,8 +303,8 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { lhs: Self::Value, rhs: Self::Value, ) -> (Self::Value, Self::Value) { - use rustc_ast::ast::IntTy::*; - use rustc_ast::ast::UintTy::*; + use rustc_ast::IntTy::*; + use rustc_ast::UintTy::*; use rustc_middle::ty::{Int, Uint}; let new_kind = match ty.kind { diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs index afdc8dc6187..4afd906fce7 100644 --- a/src/librustc_codegen_llvm/callee.rs +++ b/src/librustc_codegen_llvm/callee.rs @@ -9,8 +9,8 @@ use crate::attributes; use crate::context::CodegenCx; use crate::llvm; use crate::value::Value; -use log::debug; use rustc_codegen_ssa::traits::*; +use tracing::debug; use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt}; use rustc_middle::ty::{self, Instance, TypeFoldable}; diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index 2a50d4a46d2..0b1cf03fa7e 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -9,7 +9,7 @@ use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; -use rustc_ast::ast::Mutability; +use rustc_ast::Mutability; use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::*; use rustc_middle::bug; @@ -19,7 +19,7 @@ use rustc_span::symbol::Symbol; use rustc_target::abi::{self, AddressSpace, HasDataLayout, LayoutOf, Pointer, Size}; use libc::{c_char, c_uint}; -use log::debug; +use tracing::debug; /* * A note on nomenclature of linking: "extern", "foreign", and "upcall". diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index 0c749657001..86a5ec59254 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -6,7 +6,6 @@ use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; use libc::c_uint; -use log::debug; use rustc_codegen_ssa::traits::*; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -21,6 +20,7 @@ use rustc_middle::{bug, span_bug}; use rustc_span::symbol::sym; use rustc_span::Span; use rustc_target::abi::{AddressSpace, Align, HasDataLayout, LayoutOf, Primitive, Scalar, Size}; +use tracing::debug; use std::ffi::CStr; diff --git a/src/librustc_codegen_llvm/coverageinfo/mapgen.rs b/src/librustc_codegen_llvm/coverageinfo/mapgen.rs index b50b3b6d975..a39234c0b7f 100644 --- a/src/librustc_codegen_llvm/coverageinfo/mapgen.rs +++ b/src/librustc_codegen_llvm/coverageinfo/mapgen.rs @@ -3,11 +3,11 @@ use crate::coverageinfo; use crate::llvm; use llvm::coverageinfo::CounterMappingRegion; -use log::debug; use rustc_codegen_ssa::coverageinfo::map::{Counter, CounterExpression, Region}; use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods}; use rustc_data_structures::fx::FxIndexSet; use rustc_llvm::RustString; +use tracing::debug; use std::ffi::CString; diff --git a/src/librustc_codegen_llvm/coverageinfo/mod.rs b/src/librustc_codegen_llvm/coverageinfo/mod.rs index da567293d7b..54570920219 100644 --- a/src/librustc_codegen_llvm/coverageinfo/mod.rs +++ b/src/librustc_codegen_llvm/coverageinfo/mod.rs @@ -5,7 +5,6 @@ use crate::common::CodegenCx; use libc::c_uint; use llvm::coverageinfo::CounterMappingRegion; -use log::debug; use rustc_codegen_ssa::coverageinfo::map::{CounterExpression, ExprKind, FunctionCoverage, Region}; use rustc_codegen_ssa::traits::{ BaseTypeMethods, CoverageInfoBuilderMethods, CoverageInfoMethods, MiscMethods, StaticMethods, @@ -13,6 +12,7 @@ use rustc_codegen_ssa::traits::{ use rustc_data_structures::fx::FxHashMap; use rustc_llvm::RustString; use rustc_middle::ty::Instance; +use tracing::debug; use std::cell::RefCell; use std::ffi::CString; diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 9d6b15ec4af..9d92d53775c 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -18,8 +18,7 @@ use crate::llvm::debuginfo::{ }; use crate::value::Value; -use log::debug; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_codegen_ssa::traits::*; use rustc_data_structures::const_cstr; use rustc_data_structures::fingerprint::Fingerprint; @@ -43,6 +42,7 @@ use rustc_span::{self, SourceFile, SourceFileHash, Span}; use rustc_target::abi::{Abi, Align, HasDataLayout, Integer, LayoutOf, TagEncoding}; use rustc_target::abi::{Int, Pointer, F32, F64}; use rustc_target::abi::{Primitive, Size, VariantIdx, Variants}; +use tracing::debug; use libc::{c_longlong, c_uint}; use std::collections::hash_map::Entry; diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index a01b8553721..b414426af8c 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -33,9 +33,9 @@ use rustc_span::{self, BytePos, Span}; use rustc_target::abi::{LayoutOf, Primitive, Size}; use libc::c_uint; -use log::debug; use smallvec::SmallVec; use std::cell::RefCell; +use tracing::debug; mod create_scope_map; pub mod gdb; diff --git a/src/librustc_codegen_llvm/declare.rs b/src/librustc_codegen_llvm/declare.rs index 26ab46bde38..ec42bd4a039 100644 --- a/src/librustc_codegen_llvm/declare.rs +++ b/src/librustc_codegen_llvm/declare.rs @@ -18,9 +18,9 @@ use crate::llvm; use crate::llvm::AttributePlace::Function; use crate::type_::Type; use crate::value::Value; -use log::debug; use rustc_codegen_ssa::traits::*; use rustc_middle::ty::Ty; +use tracing::debug; /// Declare a function. /// diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 14aec1ff5e1..f1977946ee9 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -7,9 +7,7 @@ use crate::type_of::LayoutLlvmExt; use crate::va_arg::emit_va_arg; use crate::value::Value; -use log::debug; - -use rustc_ast::ast; +use rustc_ast as ast; use rustc_codegen_ssa::base::{compare_simd_types, to_immediate, wants_msvc_seh}; use rustc_codegen_ssa::common::span_invalid_monomorphization_error; use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; @@ -28,6 +26,7 @@ use rustc_middle::{bug, span_bug}; use rustc_span::{sym, symbol::kw, Span, Symbol}; use rustc_target::abi::{self, HasDataLayout, LayoutOf, Primitive}; use rustc_target::spec::PanicStrategy; +use tracing::debug; use std::cmp::Ordering; use std::iter; diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 63b0aa64bd3..32822eba930 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -389,10 +389,10 @@ pub enum AsmDialect { } impl AsmDialect { - pub fn from_generic(asm: rustc_ast::ast::LlvmAsmDialect) -> Self { + pub fn from_generic(asm: rustc_ast::LlvmAsmDialect) -> Self { match asm { - rustc_ast::ast::LlvmAsmDialect::Att => AsmDialect::Att, - rustc_ast::ast::LlvmAsmDialect::Intel => AsmDialect::Intel, + rustc_ast::LlvmAsmDialect::Att => AsmDialect::Att, + rustc_ast::LlvmAsmDialect::Intel => AsmDialect::Intel, } } } diff --git a/src/librustc_codegen_llvm/metadata.rs b/src/librustc_codegen_llvm/metadata.rs index 6d0612ca075..9036428c04b 100644 --- a/src/librustc_codegen_llvm/metadata.rs +++ b/src/librustc_codegen_llvm/metadata.rs @@ -4,10 +4,10 @@ use crate::llvm::{mk_section_iter, False, ObjectFile}; use rustc_middle::middle::cstore::MetadataLoader; use rustc_target::spec::Target; -use log::debug; use rustc_codegen_ssa::METADATA_FILENAME; use rustc_data_structures::owning_ref::OwningRef; use rustc_data_structures::rustc_erase_owner; +use tracing::debug; use rustc_fs_util::path_to_c_string; use std::path::Path; diff --git a/src/librustc_codegen_llvm/mono_item.rs b/src/librustc_codegen_llvm/mono_item.rs index 0936deb7bb5..992e83d08fc 100644 --- a/src/librustc_codegen_llvm/mono_item.rs +++ b/src/librustc_codegen_llvm/mono_item.rs @@ -4,7 +4,6 @@ use crate::base; use crate::context::CodegenCx; use crate::llvm; use crate::type_of::LayoutLlvmExt; -use log::debug; use rustc_codegen_ssa::traits::*; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; pub use rustc_middle::mir::mono::MonoItem; @@ -12,6 +11,7 @@ use rustc_middle::mir::mono::{Linkage, Visibility}; use rustc_middle::ty::layout::FnAbiExt; use rustc_middle::ty::{self, Instance, TypeFoldable}; use rustc_target::abi::LayoutOf; +use tracing::debug; impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn predefine_static( diff --git a/src/librustc_codegen_llvm/type_.rs b/src/librustc_codegen_llvm/type_.rs index 05e364884f6..3b53b4fe77b 100644 --- a/src/librustc_codegen_llvm/type_.rs +++ b/src/librustc_codegen_llvm/type_.rs @@ -7,7 +7,7 @@ use crate::llvm; use crate::llvm::{Bool, False, True}; use crate::type_of::LayoutLlvmExt; use crate::value::Value; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_codegen_ssa::common::TypeKind; use rustc_codegen_ssa::traits::*; use rustc_data_structures::small_c_str::SmallCStr; diff --git a/src/librustc_codegen_llvm/type_of.rs b/src/librustc_codegen_llvm/type_of.rs index 1d0adc5783f..40870c66475 100644 --- a/src/librustc_codegen_llvm/type_of.rs +++ b/src/librustc_codegen_llvm/type_of.rs @@ -1,7 +1,6 @@ use crate::abi::FnAbi; use crate::common::*; use crate::type_::Type; -use log::debug; use rustc_codegen_ssa::traits::*; use rustc_middle::bug; use rustc_middle::ty::layout::{FnAbiExt, TyAndLayout}; @@ -10,6 +9,7 @@ use rustc_middle::ty::{self, Ty, TypeFoldable}; use rustc_target::abi::{Abi, AddressSpace, Align, FieldsShape}; use rustc_target::abi::{Int, Pointer, F32, F64}; use rustc_target::abi::{LayoutOf, PointeeInfo, Scalar, Size, TyAndLayoutMethods, Variants}; +use tracing::debug; use std::fmt::Write; diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml index ff9dac372ab..5707d3cd0ed 100644 --- a/src/librustc_codegen_ssa/Cargo.toml +++ b/src/librustc_codegen_ssa/Cargo.toml @@ -14,7 +14,7 @@ bitflags = "1.2.1" cc = "1.0.1" num_cpus = "1.0" memmap = "0.7" -log = { package = "tracing", version = "0.1" } +tracing = "0.1" libc = "0.2.50" jobserver = "0.1.11" tempfile = "3.1" diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 5100ef8ad4f..0ddf8bd316f 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -266,7 +266,7 @@ impl<'a> GccLinker<'a> { if let Some(implib_name) = implib_name { let implib = out_filename.parent().map(|dir| dir.join(&implib_name)); if let Some(implib) = implib { - self.linker_arg(&format!("--out-implib,{}", (*implib).to_str().unwrap())); + self.linker_arg(&format!("--out-implib={}", (*implib).to_str().unwrap())); } } } diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index 6bfbda0f1d7..73e33369175 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -19,7 +19,7 @@ #[macro_use] extern crate rustc_macros; #[macro_use] -extern crate log; +extern crate tracing; #[macro_use] extern crate rustc_middle; diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index e8270b4fa0a..371e1274d8d 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -9,7 +9,7 @@ use crate::meth; use crate::traits::*; use crate::MemFlags; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_hir::lang_items; use rustc_index::vec::Idx; use rustc_middle::mir; diff --git a/src/librustc_codegen_ssa/traits/asm.rs b/src/librustc_codegen_ssa/traits/asm.rs index b6b57744f95..69931935c49 100644 --- a/src/librustc_codegen_ssa/traits/asm.rs +++ b/src/librustc_codegen_ssa/traits/asm.rs @@ -1,7 +1,7 @@ use super::BackendTypes; use crate::mir::operand::OperandRef; use crate::mir::place::PlaceRef; -use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece}; +use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_hir::def_id::DefId; use rustc_hir::{GlobalAsm, LlvmInlineAsmInner}; use rustc_middle::ty::Instance; diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml index 1926dbf06e7..988bb733f9f 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/src/librustc_data_structures/Cargo.toml @@ -12,7 +12,7 @@ doctest = false [dependencies] ena = "0.14" indexmap = "1.5.1" -log = { package = "tracing", version = "0.1" } +tracing = "0.1" jobserver_crate = { version = "0.1.13", package = "jobserver" } lazy_static = "1" once_cell = { version = "1", features = ["parking_lot"] } @@ -30,7 +30,7 @@ rustc_index = { path = "../librustc_index", package = "rustc_index" } bitflags = "1.2.1" measureme = "0.7.1" libc = "0.2" -stacker = "0.1.9" +stacker = "0.1.11" tempfile = "3.0.5" [dependencies.parking_lot] diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 017511cc50d..1937f615e70 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -26,7 +26,7 @@ #![allow(rustc::default_hash_types)] #[macro_use] -extern crate log; +extern crate tracing; #[macro_use] extern crate cfg_if; #[macro_use] diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index cd94ccc7ad7..09f5b22cc63 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -15,7 +15,7 @@ extern crate lazy_static; pub extern crate rustc_plugin_impl as plugin; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_codegen_ssa::{traits::CodegenBackend, CodegenResults}; use rustc_data_structures::profiling::print_time_passes_entry; use rustc_data_structures::sync::SeqCst; diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 2864e46cadc..b0fbf1e03f5 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -1,6 +1,6 @@ //! The various pretty-printing routines. -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast_pretty::pprust; use rustc_errors::ErrorReported; use rustc_hir as hir; diff --git a/src/librustc_error_codes/error_codes/E0754.md b/src/librustc_error_codes/error_codes/E0754.md index abdc01ed21a..57620bcd65c 100644 --- a/src/librustc_error_codes/error_codes/E0754.md +++ b/src/librustc_error_codes/error_codes/E0754.md @@ -1,31 +1,25 @@ An non-ascii identifier was used in an invalid context. -Erroneous code example: +Erroneous code examples: ```compile_fail,E0754 # #![feature(non_ascii_idents)] -mod řųśť; -// ^ error! -fn main() {} -``` - -```compile_fail,E0754 -# #![feature(non_ascii_idents)] +mod řųśť; // error! #[no_mangle] -fn řųśť() {} -// ^ error! +fn řųśť() {} // error! + fn main() {} ``` -Non-ascii can be used as module names if it is inline -or a #\[path\] attribute is specified. For example: +Non-ascii can be used as module names if it is inlined or if a `#[path]` +attribute is specified. For example: ``` # #![feature(non_ascii_idents)] -mod řųśť { +mod řųśť { // ok! const IS_GREAT: bool = true; } diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs index cd4b5d56f36..870f7b81e21 100644 --- a/src/librustc_errors/diagnostic.rs +++ b/src/librustc_errors/diagnostic.rs @@ -127,14 +127,15 @@ impl Diagnostic { } /// Adds a span/label to be included in the resulting snippet. - /// This label will be shown together with the original span/label used when creating the - /// diagnostic, *not* a span added by one of the `span_*` methods. /// - /// This is pushed onto the `MultiSpan` that was created when the - /// diagnostic was first built. If you don't call this function at - /// all, and you just supplied a `Span` to create the diagnostic, - /// then the snippet will just include that `Span`, which is - /// called the primary span. + /// This is pushed onto the [`MultiSpan`] that was created when the diagnostic + /// was first built. That means it will be shown together with the original + /// span/label, *not* a span added by one of the `span_{note,warn,help,suggestions}` methods. + /// + /// This span is *not* considered a ["primary span"][`MultiSpan`]; only + /// the `Span` supplied when creating the diagnostic is primary. + /// + /// [`MultiSpan`]: ../rustc_span/struct.MultiSpan.html pub fn span_label<T: Into<String>>(&mut self, span: Span, label: T) -> &mut Self { self.span.push_span_label(span, label.into()); self diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index dc52e29fa9b..d1ff6f721c4 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -184,11 +184,15 @@ impl<'a> DiagnosticBuilder<'a> { } /// Adds a span/label to be included in the resulting snippet. - /// This is pushed onto the `MultiSpan` that was created when the - /// diagnostic was first built. If you don't call this function at - /// all, and you just supplied a `Span` to create the diagnostic, - /// then the snippet will just include that `Span`, which is - /// called the primary span. + /// + /// This is pushed onto the [`MultiSpan`] that was created when the diagnostic + /// was first built. That means it will be shown together with the original + /// span/label, *not* a span added by one of the `span_{note,warn,help,suggestions}` methods. + /// + /// This span is *not* considered a ["primary span"][`MultiSpan`]; only + /// the `Span` supplied when creating the diagnostic is primary. + /// + /// [`MultiSpan`]: ../rustc_span/struct.MultiSpan.html pub fn span_label(&mut self, span: Span, label: impl Into<String>) -> &mut Self { self.0.diagnostic.span_label(span, label); self diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs index 5a36df8299c..0a5e1f76d10 100644 --- a/src/librustc_expand/base.rs +++ b/src/librustc_expand/base.rs @@ -1,12 +1,12 @@ use crate::expand::{self, AstFragment, Invocation}; use crate::module::DirectoryOwnership; -use rustc_ast::ast::{self, Attribute, NodeId, PatKind}; use rustc_ast::mut_visit::{self, MutVisitor}; use rustc_ast::ptr::P; use rustc_ast::token; use rustc_ast::tokenstream::{self, TokenStream}; use rustc_ast::visit::{AssocCtxt, Visitor}; +use rustc_ast::{self as ast, Attribute, NodeId, PatKind}; use rustc_attr::{self as attr, Deprecation, HasAttrs, Stability}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{self, Lrc}; diff --git a/src/librustc_expand/build.rs b/src/librustc_expand/build.rs index 81ff4b31578..7f4737a38ab 100644 --- a/src/librustc_expand/build.rs +++ b/src/librustc_expand/build.rs @@ -1,8 +1,8 @@ use crate::base::ExtCtxt; -use rustc_ast::ast::{self, AttrVec, BlockCheckMode, Expr, PatKind, UnOp}; use rustc_ast::attr; use rustc_ast::ptr::P; +use rustc_ast::{self as ast, AttrVec, BlockCheckMode, Expr, PatKind, UnOp}; use rustc_span::source_map::{respan, Spanned}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; diff --git a/src/librustc_expand/config.rs b/src/librustc_expand/config.rs index f6ddcd35068..afd1e606402 100644 --- a/src/librustc_expand/config.rs +++ b/src/librustc_expand/config.rs @@ -1,9 +1,9 @@ //! Conditional compilation stripping. -use rustc_ast::ast::{self, AttrItem, Attribute, MetaItem}; use rustc_ast::attr::HasAttrs; use rustc_ast::mut_visit::*; use rustc_ast::ptr::P; +use rustc_ast::{self as ast, AttrItem, Attribute, MetaItem}; use rustc_attr as attr; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::map_in_place::MapInPlace; diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index 8da56dc67e5..7a21caf255a 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -7,13 +7,13 @@ use crate::module::{parse_external_mod, push_directory, Directory, DirectoryOwne use crate::placeholders::{placeholder, PlaceholderExpander}; use crate::proc_macro::collect_derives; -use rustc_ast::ast::{self, AttrItem, Block, LitKind, NodeId, PatKind, Path}; -use rustc_ast::ast::{ItemKind, MacArgs, MacStmtStyle, StmtKind}; use rustc_ast::mut_visit::*; use rustc_ast::ptr::P; use rustc_ast::token; use rustc_ast::tokenstream::TokenStream; use rustc_ast::visit::{self, AssocCtxt, Visitor}; +use rustc_ast::{self as ast, AttrItem, Block, LitKind, NodeId, PatKind, Path}; +use rustc_ast::{ItemKind, MacArgs, MacStmtStyle, StmtKind}; use rustc_ast_pretty::pprust; use rustc_attr::{self as attr, is_builtin_attr, HasAttrs}; use rustc_data_structures::map_in_place::MapInPlace; diff --git a/src/librustc_expand/mbe/macro_check.rs b/src/librustc_expand/mbe/macro_check.rs index ca3e68fa670..6b419dae3f6 100644 --- a/src/librustc_expand/mbe/macro_check.rs +++ b/src/librustc_expand/mbe/macro_check.rs @@ -106,8 +106,8 @@ //! bound. use crate::mbe::{KleeneToken, TokenTree}; -use rustc_ast::ast::{NodeId, DUMMY_NODE_ID}; use rustc_ast::token::{DelimToken, Token, TokenKind}; +use rustc_ast::{NodeId, DUMMY_NODE_ID}; use rustc_data_structures::fx::FxHashMap; use rustc_session::lint::builtin::META_VARIABLE_MISUSE; use rustc_session::parse::ParseSess; diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs index 808d77842cb..48a622d13ef 100644 --- a/src/librustc_expand/mbe/macro_rules.rs +++ b/src/librustc_expand/mbe/macro_rules.rs @@ -8,7 +8,7 @@ use crate::mbe::macro_parser::{Error, ErrorReported, Failure, Success}; use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq}; use crate::mbe::transcribe::transcribe; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::token::{self, NonterminalKind, NtTT, Token, TokenKind::*}; use rustc_ast::tokenstream::{DelimSpan, TokenStream}; use rustc_ast_pretty::pprust; diff --git a/src/librustc_expand/mbe/quoted.rs b/src/librustc_expand/mbe/quoted.rs index 774cc84afde..01b11bb979d 100644 --- a/src/librustc_expand/mbe/quoted.rs +++ b/src/librustc_expand/mbe/quoted.rs @@ -1,9 +1,9 @@ use crate::mbe::macro_parser; use crate::mbe::{Delimited, KleeneOp, KleeneToken, SequenceRepetition, TokenTree}; -use rustc_ast::ast::{NodeId, DUMMY_NODE_ID}; use rustc_ast::token::{self, Token}; use rustc_ast::tokenstream; +use rustc_ast::{NodeId, DUMMY_NODE_ID}; use rustc_ast_pretty::pprust; use rustc_session::parse::ParseSess; use rustc_span::symbol::{kw, Ident}; diff --git a/src/librustc_expand/mbe/transcribe.rs b/src/librustc_expand/mbe/transcribe.rs index e2d3d5c4d64..b908a12c1fc 100644 --- a/src/librustc_expand/mbe/transcribe.rs +++ b/src/librustc_expand/mbe/transcribe.rs @@ -2,10 +2,10 @@ use crate::base::ExtCtxt; use crate::mbe; use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, NamedMatch}; -use rustc_ast::ast::MacCall; use rustc_ast::mut_visit::{self, MutVisitor}; use rustc_ast::token::{self, NtTT, Token}; use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint}; +use rustc_ast::MacCall; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; use rustc_errors::{pluralize, PResult}; diff --git a/src/librustc_expand/module.rs b/src/librustc_expand/module.rs index 12fe49ed585..1e123a2e145 100644 --- a/src/librustc_expand/module.rs +++ b/src/librustc_expand/module.rs @@ -1,5 +1,4 @@ -use rustc_ast::ast::{Attribute, Mod}; -use rustc_ast::token; +use rustc_ast::{token, Attribute, Mod}; use rustc_errors::{struct_span_err, PResult}; use rustc_parse::new_parser_from_file; use rustc_session::parse::ParseSess; diff --git a/src/librustc_expand/mut_visit/tests.rs b/src/librustc_expand/mut_visit/tests.rs index 0608ccfffb8..38ff594b6e9 100644 --- a/src/librustc_expand/mut_visit/tests.rs +++ b/src/librustc_expand/mut_visit/tests.rs @@ -1,6 +1,6 @@ use crate::tests::{matches_codepattern, string_to_crate}; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::mut_visit::{self, MutVisitor}; use rustc_ast_pretty::pprust; use rustc_span::symbol::Ident; diff --git a/src/librustc_expand/parse/tests.rs b/src/librustc_expand/parse/tests.rs index 5c9116b2f13..643305f153c 100644 --- a/src/librustc_expand/parse/tests.rs +++ b/src/librustc_expand/parse/tests.rs @@ -1,10 +1,10 @@ use crate::tests::{matches_codepattern, string_to_stream, with_error_checking_parse}; -use rustc_ast::ast::{self, PatKind}; use rustc_ast::ptr::P; use rustc_ast::token::{self, Token}; use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree}; use rustc_ast::visit; +use rustc_ast::{self as ast, PatKind}; use rustc_ast_pretty::pprust::item_to_string; use rustc_errors::PResult; use rustc_parse::new_parser_from_source_str; diff --git a/src/librustc_expand/placeholders.rs b/src/librustc_expand/placeholders.rs index b4ffd714fef..0788823b0e7 100644 --- a/src/librustc_expand/placeholders.rs +++ b/src/librustc_expand/placeholders.rs @@ -1,7 +1,7 @@ use crate::base::ExtCtxt; use crate::expand::{AstFragment, AstFragmentKind}; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::mut_visit::*; use rustc_ast::ptr::P; use rustc_span::source_map::{dummy_spanned, DUMMY_SP}; diff --git a/src/librustc_expand/proc_macro.rs b/src/librustc_expand/proc_macro.rs index 85fbf3bc0d0..4e865c20d6f 100644 --- a/src/librustc_expand/proc_macro.rs +++ b/src/librustc_expand/proc_macro.rs @@ -1,9 +1,9 @@ use crate::base::{self, *}; use crate::proc_macro_server; -use rustc_ast::ast::{self, ItemKind, MetaItemKind, NestedMetaItem}; use rustc_ast::token; use rustc_ast::tokenstream::{TokenStream, TokenTree}; +use rustc_ast::{self as ast, *}; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, ErrorReported}; use rustc_parse::nt_to_tokenstream; diff --git a/src/librustc_expand/proc_macro_server.rs b/src/librustc_expand/proc_macro_server.rs index 83a650443bc..33e35cd0404 100644 --- a/src/librustc_expand/proc_macro_server.rs +++ b/src/librustc_expand/proc_macro_server.rs @@ -1,6 +1,6 @@ use crate::base::ExtCtxt; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::token; use rustc_ast::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint}; use rustc_ast_pretty::pprust; diff --git a/src/librustc_expand/tests.rs b/src/librustc_expand/tests.rs index b562a690f83..6993ce58fa6 100644 --- a/src/librustc_expand/tests.rs +++ b/src/librustc_expand/tests.rs @@ -1,4 +1,4 @@ -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::tokenstream::TokenStream; use rustc_parse::{new_parser_from_source_str, parser::Parser, source_file_to_stream}; use rustc_session::parse::ParseSess; diff --git a/src/librustc_hir/arena.rs b/src/librustc_hir/arena.rs index 6ba39666607..85ab7906d25 100644 --- a/src/librustc_hir/arena.rs +++ b/src/librustc_hir/arena.rs @@ -15,8 +15,8 @@ macro_rules! arena_types { [few] hir_krate: rustc_hir::Crate<$tcx>, [] arm: rustc_hir::Arm<$tcx>, [] asm_operand: rustc_hir::InlineAsmOperand<$tcx>, - [] asm_template: rustc_ast::ast::InlineAsmTemplatePiece, - [] attribute: rustc_ast::ast::Attribute, + [] asm_template: rustc_ast::InlineAsmTemplatePiece, + [] attribute: rustc_ast::Attribute, [] block: rustc_hir::Block<$tcx>, [] bare_fn_ty: rustc_hir::BareFnTy<$tcx>, [few] global_asm: rustc_hir::GlobalAsm, diff --git a/src/librustc_hir/def.rs b/src/librustc_hir/def.rs index c4877be3f64..fb7fced27c2 100644 --- a/src/librustc_hir/def.rs +++ b/src/librustc_hir/def.rs @@ -1,8 +1,8 @@ use crate::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use crate::hir; -use rustc_ast::ast; -use rustc_ast::ast::NodeId; +use rustc_ast as ast; +use rustc_ast::NodeId; use rustc_macros::HashStable_Generic; use rustc_span::hygiene::MacroKind; diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 928235adac3..cf356763130 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -1,19 +1,19 @@ use crate::def::{DefKind, Namespace, Res}; use crate::def_id::DefId; crate use crate::hir_id::HirId; -use crate::itemlikevisit; +use crate::{itemlikevisit, LangItem}; -use rustc_ast::ast::{self, CrateSugar, LlvmAsmDialect}; -use rustc_ast::ast::{AttrVec, Attribute, FloatTy, IntTy, Label, LitKind, StrStyle, UintTy}; -pub use rustc_ast::ast::{BorrowKind, ImplPolarity, IsAuto}; -pub use rustc_ast::ast::{CaptureBy, Movability, Mutability}; -use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_ast::node_id::NodeMap; use rustc_ast::util::parser::ExprPrecedence; +use rustc_ast::{self as ast, CrateSugar, LlvmAsmDialect}; +use rustc_ast::{AttrVec, Attribute, FloatTy, IntTy, Label, LitKind, StrStyle, UintTy}; +pub use rustc_ast::{BorrowKind, ImplPolarity, IsAuto}; +pub use rustc_ast::{CaptureBy, Movability, Mutability}; +use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_data_structures::sync::{par_for_each_in, Send, Sync}; use rustc_macros::HashStable_Generic; use rustc_span::def_id::LocalDefId; -use rustc_span::source_map::{SourceMap, Spanned}; +use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{MultiSpan, Span, DUMMY_SP}; use rustc_target::asm::InlineAsmRegOrRegClass; @@ -363,6 +363,8 @@ pub enum TraitBoundModifier { #[derive(Debug, HashStable_Generic)] pub enum GenericBound<'hir> { Trait(PolyTraitRef<'hir>, TraitBoundModifier), + // FIXME(davidtwco): Introduce `PolyTraitRef::LangItem` + LangItemTrait(LangItem, Span, HirId, &'hir GenericArgs<'hir>), Outlives(Lifetime), } @@ -377,6 +379,7 @@ impl GenericBound<'_> { pub fn span(&self) -> Span { match self { &GenericBound::Trait(ref t, ..) => t.span, + &GenericBound::LangItemTrait(_, span, ..) => span, &GenericBound::Outlives(ref l) => l.span, } } @@ -1419,10 +1422,10 @@ impl Expr<'_> { self.is_place_expr(|_| true) } - // Whether this is a place expression. - // `allow_projections_from` should return `true` if indexing a field or - // index expression based on the given expression should be considered a - // place expression. + /// Whether this is a place expression. + /// + /// `allow_projections_from` should return `true` if indexing a field or index expression based + /// on the given expression should be considered a place expression. pub fn is_place_expr(&self, mut allow_projections_from: impl FnMut(&Self) -> bool) -> bool { match self.kind { ExprKind::Path(QPath::Resolved(_, ref path)) => match path.res { @@ -1441,6 +1444,9 @@ impl Expr<'_> { allow_projections_from(base) || base.is_place_expr(allow_projections_from) } + // Lang item paths cannot currently be local variables or statics. + ExprKind::Path(QPath::LangItem(..)) => false, + // Partially qualified paths in expressions can only legally // refer to associated items which are always rvalues. ExprKind::Path(QPath::TypeRelative(..)) @@ -1489,58 +1495,28 @@ impl Expr<'_> { /// Checks if the specified expression is a built-in range literal. /// (See: `LoweringContext::lower_expr()`). -/// -/// FIXME(#60607): This function is a hack. If and when we have `QPath::Lang(...)`, -/// we can use that instead as simpler, more reliable mechanism, as opposed to using `SourceMap`. -pub fn is_range_literal(sm: &SourceMap, expr: &Expr<'_>) -> bool { - // Returns whether the given path represents a (desugared) range, - // either in std or core, i.e. has either a `::std::ops::Range` or - // `::core::ops::Range` prefix. - fn is_range_path(path: &Path<'_>) -> bool { - let segs: Vec<_> = path.segments.iter().map(|seg| seg.ident.to_string()).collect(); - let segs: Vec<_> = segs.iter().map(|seg| &**seg).collect(); - - // "{{root}}" is the equivalent of `::` prefix in `Path`. - if let ["{{root}}", std_core, "ops", range] = segs.as_slice() { - (*std_core == "std" || *std_core == "core") && range.starts_with("Range") - } else { - false - } - }; - - // Check whether a span corresponding to a range expression is a - // range literal, rather than an explicit struct or `new()` call. - fn is_lit(sm: &SourceMap, span: &Span) -> bool { - sm.span_to_snippet(*span).map(|range_src| range_src.contains("..")).unwrap_or(false) - }; - +pub fn is_range_literal(expr: &Expr<'_>) -> bool { match expr.kind { // All built-in range literals but `..=` and `..` desugar to `Struct`s. - ExprKind::Struct(ref qpath, _, _) => { - if let QPath::Resolved(None, ref path) = **qpath { - return is_range_path(&path) && is_lit(sm, &expr.span); - } - } - - // `..` desugars to its struct path. - ExprKind::Path(QPath::Resolved(None, ref path)) => { - return is_range_path(&path) && is_lit(sm, &expr.span); - } + ExprKind::Struct(ref qpath, _, _) => matches!( + **qpath, + QPath::LangItem( + LangItem::Range + | LangItem::RangeTo + | LangItem::RangeFrom + | LangItem::RangeFull + | LangItem::RangeToInclusive, + _, + ) + ), // `..=` desugars into `::std::ops::RangeInclusive::new(...)`. ExprKind::Call(ref func, _) => { - if let ExprKind::Path(QPath::TypeRelative(ref ty, ref segment)) = func.kind { - if let TyKind::Path(QPath::Resolved(None, ref path)) = ty.kind { - let new_call = segment.ident.name == sym::new; - return is_range_path(&path) && is_lit(sm, &expr.span) && new_call; - } - } + matches!(func.kind, ExprKind::Path(QPath::LangItem(LangItem::RangeInclusiveNew, _))) } - _ => {} + _ => false, } - - false } #[derive(Debug, HashStable_Generic)] @@ -1677,6 +1653,40 @@ pub enum QPath<'hir> { /// `<Vec>::new`, and `T::X::Y::method` into `<<<T>::X>::Y>::method`, /// the `X` and `Y` nodes each being a `TyKind::Path(QPath::TypeRelative(..))`. TypeRelative(&'hir Ty<'hir>, &'hir PathSegment<'hir>), + + /// Reference to a `#[lang = "foo"]` item. + LangItem(LangItem, Span), +} + +impl<'hir> QPath<'hir> { + /// Returns the span of this `QPath`. + pub fn span(&self) -> Span { + match *self { + QPath::Resolved(_, path) => path.span, + QPath::TypeRelative(_, ps) => ps.ident.span, + QPath::LangItem(_, span) => span, + } + } + + /// Returns the span of the qself of this `QPath`. For example, `()` in + /// `<() as Trait>::method`. + pub fn qself_span(&self) -> Span { + match *self { + QPath::Resolved(_, path) => path.span, + QPath::TypeRelative(qself, _) => qself.span, + QPath::LangItem(_, span) => span, + } + } + + /// Returns the span of the last segment of this `QPath`. For example, `method` in + /// `<() as Trait>::method`. + pub fn last_segment_span(&self) -> Span { + match *self { + QPath::Resolved(_, path) => path.segments.last().unwrap().ident.span, + QPath::TypeRelative(_, segment) => segment.ident.span, + QPath::LangItem(_, span) => span, + } + } } /// Hints at the original code for a let statement. diff --git a/src/librustc_hir/intravisit.rs b/src/librustc_hir/intravisit.rs index 23d642731da..76cf6bd4776 100644 --- a/src/librustc_hir/intravisit.rs +++ b/src/librustc_hir/intravisit.rs @@ -34,8 +34,8 @@ use crate::hir::*; use crate::hir_id::CRATE_HIR_ID; use crate::itemlikevisit::{ItemLikeVisitor, ParItemLikeVisitor}; -use rustc_ast::ast::{Attribute, Label}; use rustc_ast::walk_list; +use rustc_ast::{Attribute, Label}; use rustc_span::symbol::{Ident, Symbol}; use rustc_span::Span; @@ -724,6 +724,7 @@ pub fn walk_qpath<'v, V: Visitor<'v>>( visitor.visit_ty(qself); visitor.visit_path_segment(span, segment); } + QPath::LangItem(..) => {} } } @@ -838,6 +839,10 @@ pub fn walk_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v GenericB GenericBound::Trait(ref typ, modifier) => { visitor.visit_poly_trait_ref(typ, modifier); } + GenericBound::LangItemTrait(_, span, hir_id, args) => { + visitor.visit_id(hir_id); + visitor.visit_generic_args(span, args); + } GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime), } } diff --git a/src/librustc_hir/lang_items.rs b/src/librustc_hir/lang_items.rs index b09657bd9b4..c00d861350d 100644 --- a/src/librustc_hir/lang_items.rs +++ b/src/librustc_hir/lang_items.rs @@ -10,9 +10,9 @@ pub use self::LangItem::*; use crate::def_id::DefId; -use crate::Target; +use crate::{MethodKind, Target}; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_macros::HashStable_Generic; @@ -307,4 +307,38 @@ language_item_table! { CountCodeRegionFnLangItem, sym::count_code_region, count_code_region_fn, Target::Fn; CoverageCounterAddFnLangItem, sym::coverage_counter_add, coverage_counter_add_fn, Target::Fn; CoverageCounterSubtractFnLangItem, sym::coverage_counter_subtract, coverage_counter_subtract_fn, Target::Fn; + + // Language items from AST lowering + TryFromError, sym::from_error, from_error_fn, Target::Method(MethodKind::Trait { body: false }); + TryFromOk, sym::from_ok, from_ok_fn, Target::Method(MethodKind::Trait { body: false }); + TryIntoResult, sym::into_result, into_result_fn, Target::Method(MethodKind::Trait { body: false }); + + PollReady, sym::Ready, poll_ready_variant, Target::Variant; + PollPending, sym::Pending, poll_pending_variant, Target::Variant; + + FromGenerator, sym::from_generator, from_generator_fn, Target::Fn; + GetContext, sym::get_context, get_context_fn, Target::Fn; + + FuturePoll, sym::poll, future_poll_fn, Target::Method(MethodKind::Trait { body: false }); + + FromFrom, sym::from, from_fn, Target::Method(MethodKind::Trait { body: false }); + + OptionSome, sym::Some, option_some_variant, Target::Variant; + OptionNone, sym::None, option_none_variant, Target::Variant; + + ResultOk, sym::Ok, result_ok_variant, Target::Variant; + ResultErr, sym::Err, result_err_variant, Target::Variant; + + IntoIterIntoIter, sym::into_iter, into_iter_fn, Target::Method(MethodKind::Trait { body: false }); + IteratorNext, sym::next, next_fn, Target::Method(MethodKind::Trait { body: false}); + + PinNewUnchecked, sym::new_unchecked, new_unchecked_fn, Target::Method(MethodKind::Inherent); + + RangeFrom, sym::RangeFrom, range_from_struct, Target::Struct; + RangeFull, sym::RangeFull, range_full_struct, Target::Struct; + RangeInclusiveStruct, sym::RangeInclusive, range_inclusive_struct, Target::Struct; + RangeInclusiveNew, sym::range_inclusive_new, range_inclusive_new_method, Target::Method(MethodKind::Inherent); + Range, sym::Range, range_struct, Target::Struct; + RangeToInclusive, sym::RangeToInclusive, range_to_inclusive_struct, Target::Struct; + RangeTo, sym::RangeTo, range_to_struct, Target::Struct; } diff --git a/src/librustc_hir/target.rs b/src/librustc_hir/target.rs index 3a4485a1b17..1efc8bc3124 100644 --- a/src/librustc_hir/target.rs +++ b/src/librustc_hir/target.rs @@ -29,6 +29,7 @@ pub enum Target { TyAlias, OpaqueTy, Enum, + Variant, Struct, Union, Trait, @@ -62,6 +63,7 @@ impl Display for Target { Target::TyAlias => "type alias", Target::OpaqueTy => "opaque type", Target::Enum => "enum", + Target::Variant => "enum variant", Target::Struct => "struct", Target::Union => "union", Target::Trait => "trait", diff --git a/src/librustc_hir/weak_lang_items.rs b/src/librustc_hir/weak_lang_items.rs index fd64361cb35..76b95c696f7 100644 --- a/src/librustc_hir/weak_lang_items.rs +++ b/src/librustc_hir/weak_lang_items.rs @@ -3,7 +3,7 @@ use crate::def_id::DefId; use crate::{lang_items, LangItem, LanguageItems}; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_data_structures::fx::FxHashMap; use rustc_span::symbol::{sym, Symbol}; diff --git a/src/librustc_hir_pretty/lib.rs b/src/librustc_hir_pretty/lib.rs index 2298a80ae4f..f6e4b1fb418 100644 --- a/src/librustc_hir_pretty/lib.rs +++ b/src/librustc_hir_pretty/lib.rs @@ -1,7 +1,7 @@ #![feature(or_patterns)] #![recursion_limit = "256"] -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::util::parser::{self, AssocOp, Fixity}; use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent}; use rustc_ast_pretty::pp::{self, Breaks}; @@ -1729,6 +1729,11 @@ impl<'a> State<'a> { colons_before_params, ) } + hir::QPath::LangItem(lang_item, span) => { + self.s.word("#[lang = \""); + self.print_ident(Ident::new(lang_item.name(), span)); + self.s.word("\"]"); + } } } @@ -2142,6 +2147,11 @@ impl<'a> State<'a> { } self.print_poly_trait_ref(tref); } + GenericBound::LangItemTrait(lang_item, span, ..) => { + self.s.word("#[lang = \""); + self.print_ident(Ident::new(lang_item.name(), *span)); + self.s.word("\"]"); + } GenericBound::Outlives(lt) => { self.print_lifetime(lt); } diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs index df602d8bd1b..e17396422f1 100644 --- a/src/librustc_incremental/assert_dep_graph.rs +++ b/src/librustc_incremental/assert_dep_graph.rs @@ -33,7 +33,7 @@ //! fn baz() { foo(); } //! ``` -use rustc_ast::ast; +use rustc_ast as ast; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::graph::implementation::{Direction, NodeIndex, INCOMING, OUTGOING}; use rustc_graphviz as dot; diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs index ed04a947485..80448c01a26 100644 --- a/src/librustc_incremental/assert_module_sources.rs +++ b/src/librustc_incremental/assert_module_sources.rs @@ -21,7 +21,7 @@ //! allows for doing a more fine-grained check to see if pre- or post-lto data //! was re-used. -use rustc_ast::ast; +use rustc_ast as ast; use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::mir::mono::CodegenUnitNameBuilder; use rustc_middle::ty::TyCtxt; diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index 0f254aee8e3..f0a10885550 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -13,7 +13,7 @@ //! Errors are reported if we are in the suitable configuration but //! the required condition is not met. -use rustc_ast::ast::{self, Attribute, NestedMetaItem}; +use rustc_ast::{self as ast, Attribute, NestedMetaItem}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; diff --git a/src/librustc_infer/infer/combine.rs b/src/librustc_infer/infer/combine.rs index 133c4bf2db5..3a54a647530 100644 --- a/src/librustc_infer/infer/combine.rs +++ b/src/librustc_infer/infer/combine.rs @@ -34,7 +34,7 @@ use super::{InferCtxt, MiscVariable, TypeTrace}; use crate::traits::{Obligation, PredicateObligations}; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_hir::def_id::DefId; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::error::TypeError; diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index 122d6e3543c..4d84462c42b 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -1,8 +1,8 @@ pub use crate::passes::BoxedResolver; use crate::util; -use rustc_ast::ast::{self, MetaItemKind}; use rustc_ast::token; +use rustc_ast::{self as ast, MetaItemKind}; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index daa7444fb9e..007dbfb9fdd 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -4,7 +4,7 @@ use crate::util; use once_cell::sync::Lazy; use rustc_ast::mut_visit::MutVisitor; -use rustc_ast::{self, ast, visit}; +use rustc_ast::{self as ast, visit}; use rustc_codegen_ssa::back::link::emit_metadata; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::sync::{par_iter, Lrc, OnceCell, ParallelIterator, WorkerLocal}; diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 2f32737cca0..8b82217a91a 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -1,7 +1,7 @@ use crate::interface::{Compiler, Result}; use crate::passes::{self, BoxedResolver, QueryContext}; -use rustc_ast::{self, ast}; +use rustc_ast as ast; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal}; use rustc_errors::ErrorReported; diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 36eaad16079..8816ba198cf 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -1,8 +1,7 @@ -use rustc_ast::ast::{AttrVec, BlockCheckMode}; use rustc_ast::mut_visit::{visit_clobber, MutVisitor, *}; use rustc_ast::ptr::P; use rustc_ast::util::lev_distance::find_best_match_for_name; -use rustc_ast::{self, ast}; +use rustc_ast::{self as ast, AttrVec, BlockCheckMode}; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 3859d0f163a..36eb272cdfc 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -23,10 +23,10 @@ use crate::{ types::CItemKind, EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext, }; -use rustc_ast::ast::{self, Expr}; use rustc_ast::attr::{self, HasAttrs}; use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_ast::visit::{FnCtxt, FnKind}; +use rustc_ast::{self as ast, *}; use rustc_ast_pretty::pprust::{self, expr_to_string}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString}; @@ -1057,7 +1057,7 @@ impl TypeAliasBounds { _ => false, } } - hir::QPath::Resolved(..) => false, + hir::QPath::Resolved(..) | hir::QPath::LangItem(..) => false, } } @@ -1287,7 +1287,7 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns { return; } - use self::ast::{PatKind, RangeEnd, RangeSyntax::DotDotDot}; + use self::ast::{PatKind, RangeSyntax::DotDotDot}; /// If `pat` is a `...` pattern, return the start and end of the range, as well as the span /// corresponding to the ellipsis. @@ -1860,7 +1860,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { /// Test if this constant is all-0. fn is_zero(expr: &hir::Expr<'_>) -> bool { use hir::ExprKind::*; - use rustc_ast::ast::LitKind::*; + use rustc_ast::LitKind::*; match &expr.kind { Lit(lit) => { if let Int(i, _) = lit.node { diff --git a/src/librustc_lint/context.rs b/src/librustc_lint/context.rs index 31d30a264a5..a6784ffffcd 100644 --- a/src/librustc_lint/context.rs +++ b/src/librustc_lint/context.rs @@ -18,7 +18,7 @@ use self::TargetLint::*; use crate::levels::LintLevelsBuilder; use crate::passes::{EarlyLintPassObject, LateLintPassObject}; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::util::lev_distance::find_best_match_for_name; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync; @@ -703,7 +703,7 @@ impl<'tcx> LateContext<'tcx> { pub fn qpath_res(&self, qpath: &hir::QPath<'_>, id: hir::HirId) -> Res { match *qpath { hir::QPath::Resolved(_, ref path) => path.res, - hir::QPath::TypeRelative(..) => self + hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self .maybe_typeck_results() .and_then(|typeck_results| typeck_results.type_dependent_def(id)) .map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)), diff --git a/src/librustc_lint/early.rs b/src/librustc_lint/early.rs index 017d4e31e4a..998676d44d2 100644 --- a/src/librustc_lint/early.rs +++ b/src/librustc_lint/early.rs @@ -16,7 +16,7 @@ use crate::context::{EarlyContext, LintContext, LintStore}; use crate::passes::{EarlyLintPass, EarlyLintPassObject}; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::visit as ast_visit; use rustc_session::lint::{BufferedEarlyLint, LintBuffer, LintPass}; use rustc_session::Session; diff --git a/src/librustc_lint/internal.rs b/src/librustc_lint/internal.rs index 30fae324392..100e555f299 100644 --- a/src/librustc_lint/internal.rs +++ b/src/librustc_lint/internal.rs @@ -2,7 +2,7 @@ //! Clippy. use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; -use rustc_ast::ast::{Item, ItemKind}; +use rustc_ast::{Item, ItemKind}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; use rustc_hir::{GenericArg, HirId, MutTy, Mutability, Path, PathSegment, QPath, Ty, TyKind}; diff --git a/src/librustc_lint/late.rs b/src/librustc_lint/late.rs index 6c497d02285..a6c04fb0b4c 100644 --- a/src/librustc_lint/late.rs +++ b/src/librustc_lint/late.rs @@ -15,7 +15,7 @@ //! for all lint attributes. use crate::{passes::LateLintPassObject, LateContext, LateLintPass, LintStore}; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::walk_list; use rustc_data_structures::sync::{join, par_iter, ParallelIterator}; use rustc_hir as hir; diff --git a/src/librustc_lint/levels.rs b/src/librustc_lint/levels.rs index 145a07d8dc8..48254dcee82 100644 --- a/src/librustc_lint/levels.rs +++ b/src/librustc_lint/levels.rs @@ -1,6 +1,6 @@ use crate::context::{CheckLintNameResult, LintStore}; use crate::late::unerased_lint_store; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::attr; use rustc_ast::unwrap_or; use rustc_ast_pretty::pprust; diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 1f17c7dcba4..0a14b16e274 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -55,7 +55,7 @@ mod redundant_semicolon; mod types; mod unused; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_middle::ty::query::Providers; diff --git a/src/librustc_lint/non_ascii_idents.rs b/src/librustc_lint/non_ascii_idents.rs index ab1658b2229..2f0b2a8d680 100644 --- a/src/librustc_lint/non_ascii_idents.rs +++ b/src/librustc_lint/non_ascii_idents.rs @@ -1,5 +1,5 @@ use crate::{EarlyContext, EarlyLintPass, LintContext}; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_data_structures::fx::FxHashMap; use rustc_span::symbol::Symbol; diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs index 5ca6f461048..f23e8c5e208 100644 --- a/src/librustc_lint/nonstandard_style.rs +++ b/src/librustc_lint/nonstandard_style.rs @@ -1,5 +1,5 @@ use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_attr as attr; use rustc_errors::Applicability; use rustc_hir as hir; diff --git a/src/librustc_lint/passes.rs b/src/librustc_lint/passes.rs index 75e50f74a81..159286c13a4 100644 --- a/src/librustc_lint/passes.rs +++ b/src/librustc_lint/passes.rs @@ -1,6 +1,6 @@ use crate::context::{EarlyContext, LateContext}; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_data_structures::sync; use rustc_hir as hir; use rustc_session::lint::builtin::HardwiredLints; diff --git a/src/librustc_lint/redundant_semicolon.rs b/src/librustc_lint/redundant_semicolon.rs index 0f807cd497e..d4aa4968f25 100644 --- a/src/librustc_lint/redundant_semicolon.rs +++ b/src/librustc_lint/redundant_semicolon.rs @@ -1,5 +1,5 @@ use crate::{EarlyContext, EarlyLintPass, LintContext}; -use rustc_ast::ast::{Block, StmtKind}; +use rustc_ast::{Block, StmtKind}; use rustc_errors::Applicability; use rustc_span::Span; diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 5891abcfd9c..4ca5f23ebfe 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -1,7 +1,7 @@ #![allow(non_snake_case)] use crate::{LateContext, LateLintPass, LintContext}; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_attr as attr; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; @@ -195,8 +195,8 @@ fn report_bin_hex_error( // // No suggestion for: `isize`, `usize`. fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<&'static str> { - use rustc_ast::ast::IntTy::*; - use rustc_ast::ast::UintTy::*; + use rustc_ast::IntTy::*; + use rustc_ast::UintTy::*; macro_rules! find_fit { ($ty:expr, $val:expr, $negative:expr, $($type:ident => [$($utypes:expr),*] => [$($itypes:expr),*]),+) => { @@ -258,7 +258,7 @@ fn lint_int_literal<'tcx>( let par_id = cx.tcx.hir().get_parent_node(e.hir_id); if let Node::Expr(par_e) = cx.tcx.hir().get(par_id) { if let hir::ExprKind::Struct(..) = par_e.kind { - if is_range_literal(cx.sess().source_map(), par_e) + if is_range_literal(par_e) && lint_overflowing_range_endpoint(cx, lit, v, max, e, par_e, t.name_str()) { // The overflowing literal lint was overridden. @@ -317,7 +317,7 @@ fn lint_uint_literal<'tcx>( return; } } - hir::ExprKind::Struct(..) if is_range_literal(cx.sess().source_map(), par_e) => { + hir::ExprKind::Struct(..) if is_range_literal(par_e) => { let t = t.name_str(); if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, par_e, t) { // The overflowing literal lint was overridden. diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 95e51b47be3..c793e81ebe3 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -1,8 +1,8 @@ use crate::Lint; use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; -use rustc_ast::ast; -use rustc_ast::ast::{ExprKind, StmtKind}; +use rustc_ast as ast; use rustc_ast::util::parser; +use rustc_ast::{ExprKind, StmtKind}; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{pluralize, Applicability}; @@ -526,7 +526,7 @@ trait UnusedDelimLint { } fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) { - use rustc_ast::ast::ExprKind::*; + use rustc_ast::ExprKind::*; let (value, ctx, followed_by_block, left_pos, right_pos) = match e.kind { // Do not lint `unused_braces` in `if let` expressions. If(ref cond, ref block, ..) diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 9827b222331..f8446d83d2b 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -5,7 +5,7 @@ use crate::locator::{CrateError, CrateLocator, CratePaths}; use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob}; use rustc_ast::expand::allocator::AllocatorKind; -use rustc_ast::{ast, visit}; +use rustc_ast::{self as ast, *}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::Lrc; diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index bdd20a4bf6f..8fa14a44f52 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -685,13 +685,19 @@ impl<'a> CrateLocator<'a> { && file.ends_with(&self.target.options.dll_suffix) { // Make sure there's at most one rlib and at most one dylib. - let loc = fs::canonicalize(&loc).unwrap_or_else(|_| loc.clone()); + // Note to take care and match against the non-canonicalized name: + // some systems save build artifacts into content-addressed stores + // that do not preserve extensions, and then link to them using + // e.g. symbolic links. If we canonicalize too early, we resolve + // the symlink, the file type is lost and we might treat rlibs and + // rmetas as dylibs. + let loc_canon = fs::canonicalize(&loc).unwrap_or_else(|_| loc.clone()); if loc.file_name().unwrap().to_str().unwrap().ends_with(".rlib") { - rlibs.insert(loc, PathKind::ExternFlag); + rlibs.insert(loc_canon, PathKind::ExternFlag); } else if loc.file_name().unwrap().to_str().unwrap().ends_with(".rmeta") { - rmetas.insert(loc, PathKind::ExternFlag); + rmetas.insert(loc_canon, PathKind::ExternFlag); } else { - dylibs.insert(loc, PathKind::ExternFlag); + dylibs.insert(loc_canon, PathKind::ExternFlag); } } else { self.rejected_via_filename diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index 1e4556f5fc8..10f5b671748 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -4,7 +4,7 @@ use crate::creader::CrateMetadataRef; use crate::rmeta::table::{FixedSizeEncoding, Table}; use crate::rmeta::*; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_attr as attr; use rustc_data_structures::captures::Captures; use rustc_data_structures::fingerprint::{Fingerprint, FingerprintDecoder}; diff --git a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs index 10b89cdd15a..74d29b3df01 100644 --- a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs +++ b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs @@ -4,7 +4,7 @@ use crate::link_args; use crate::native_libs; use crate::rmeta::{self, encoder}; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::expand::allocator::AllocatorKind; use rustc_data_structures::svh::Svh; use rustc_hir as hir; diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 0343fbeb0fa..cb3bf10926b 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -1,7 +1,7 @@ use crate::rmeta::table::{FixedSizeEncoding, TableBuilder}; use crate::rmeta::*; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_data_structures::fingerprint::{Fingerprint, FingerprintEncoder}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_data_structures::stable_hasher::StableHasher; diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs index b15c20e515f..ac1ac360701 100644 --- a/src/librustc_metadata/rmeta/mod.rs +++ b/src/librustc_metadata/rmeta/mod.rs @@ -1,7 +1,7 @@ use decoder::Metadata; use table::{Table, TableBuilder}; -use rustc_ast::ast::{self, MacroDef}; +use rustc_ast::{self as ast, MacroDef}; use rustc_attr as attr; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::MetadataRef; diff --git a/src/librustc_middle/arena.rs b/src/librustc_middle/arena.rs index 99889c74da0..f6570cc95d2 100644 --- a/src/librustc_middle/arena.rs +++ b/src/librustc_middle/arena.rs @@ -81,7 +81,7 @@ macro_rules! arena_types { [] upvars_mentioned: rustc_data_structures::fx::FxIndexMap<rustc_hir::HirId, rustc_hir::Upvar>, [] object_safety_violations: rustc_middle::traits::ObjectSafetyViolation, [] codegen_unit: rustc_middle::mir::mono::CodegenUnit<$tcx>, - [] attribute: rustc_ast::ast::Attribute, + [] attribute: rustc_ast::Attribute, [] name_set: rustc_data_structures::fx::FxHashSet<rustc_span::symbol::Symbol>, [] hir_id_set: rustc_hir::HirIdSet, @@ -98,7 +98,7 @@ macro_rules! arena_types { // Note that this deliberately duplicates items in the `rustc_hir::arena`, // since we need to allocate this type on both the `rustc_hir` arena // (during lowering) and the `librustc_middle` arena (for decoding MIR) - [decode] asm_template: rustc_ast::ast::InlineAsmTemplatePiece, + [decode] asm_template: rustc_ast::InlineAsmTemplatePiece, // This is used to decode the &'tcx [Span] for InlineAsm's line_spans. [decode] span: rustc_span::Span, diff --git a/src/librustc_middle/hir/map/blocks.rs b/src/librustc_middle/hir/map/blocks.rs index a2e4372f017..6f572a4875f 100644 --- a/src/librustc_middle/hir/map/blocks.rs +++ b/src/librustc_middle/hir/map/blocks.rs @@ -12,7 +12,7 @@ //! for the `Code` associated with a particular NodeId. use crate::hir::map::Map; -use rustc_ast::ast::Attribute; +use rustc_ast::Attribute; use rustc_hir as hir; use rustc_hir::intravisit::FnKind; use rustc_hir::{Expr, FnDecl, Node}; diff --git a/src/librustc_middle/hir/map/mod.rs b/src/librustc_middle/hir/map/mod.rs index 0794caca1ba..a6cc7cbc920 100644 --- a/src/librustc_middle/hir/map/mod.rs +++ b/src/librustc_middle/hir/map/mod.rs @@ -3,7 +3,7 @@ use self::collector::NodeCollector; use crate::hir::{Owner, OwnerNodes}; use crate::ty::query::Providers; use crate::ty::TyCtxt; -use rustc_ast::ast::{self}; +use rustc_ast as ast; use rustc_data_structures::svh::Svh; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; diff --git a/src/librustc_middle/ich/hcx.rs b/src/librustc_middle/ich/hcx.rs index 19a7d2ec221..084fe4cfa16 100644 --- a/src/librustc_middle/ich/hcx.rs +++ b/src/librustc_middle/ich/hcx.rs @@ -2,7 +2,7 @@ use crate::ich; use crate::middle::cstore::CrateStore; use crate::ty::{fast_reject, TyCtxt}; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::Lrc; diff --git a/src/librustc_middle/ich/impls_syntax.rs b/src/librustc_middle/ich/impls_syntax.rs index 300aac19e51..e3d4655831b 100644 --- a/src/librustc_middle/ich/impls_syntax.rs +++ b/src/librustc_middle/ich/impls_syntax.rs @@ -3,7 +3,7 @@ use crate::ich::StableHashingContext; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_span::SourceFile; diff --git a/src/librustc_middle/middle/cstore.rs b/src/librustc_middle/middle/cstore.rs index 6a8f6c3e202..6759ad61d3a 100644 --- a/src/librustc_middle/middle/cstore.rs +++ b/src/librustc_middle/middle/cstore.rs @@ -4,7 +4,7 @@ use crate::ty::TyCtxt; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::expand::allocator::AllocatorKind; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::{self, MetadataRef}; diff --git a/src/librustc_middle/middle/limits.rs b/src/librustc_middle/middle/limits.rs index e9820539484..def9e5ebb52 100644 --- a/src/librustc_middle/middle/limits.rs +++ b/src/librustc_middle/middle/limits.rs @@ -6,7 +6,7 @@ //! just peeks and looks for that attribute. use crate::bug; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_data_structures::sync::OnceCell; use rustc_session::{Limit, Session}; use rustc_span::symbol::{sym, Symbol}; diff --git a/src/librustc_middle/middle/stability.rs b/src/librustc_middle/middle/stability.rs index b913d7dd4ad..b32eebbb11e 100644 --- a/src/librustc_middle/middle/stability.rs +++ b/src/librustc_middle/middle/stability.rs @@ -4,7 +4,7 @@ pub use self::StabilityLevel::*; use crate::ty::{self, TyCtxt}; -use rustc_ast::ast::CRATE_NODE_ID; +use rustc_ast::CRATE_NODE_ID; use rustc_attr::{self as attr, ConstStability, Deprecation, Stability}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{Applicability, DiagnosticBuilder}; diff --git a/src/librustc_middle/mir/interpret/allocation.rs b/src/librustc_middle/mir/interpret/allocation.rs index bee8d13c762..505939d56ed 100644 --- a/src/librustc_middle/mir/interpret/allocation.rs +++ b/src/librustc_middle/mir/interpret/allocation.rs @@ -5,7 +5,7 @@ use std::convert::TryFrom; use std::iter; use std::ops::{Deref, DerefMut, Range}; -use rustc_ast::ast::Mutability; +use rustc_ast::Mutability; use rustc_data_structures::sorted_map::SortedMap; use rustc_target::abi::{Align, HasDataLayout, Size}; diff --git a/src/librustc_middle/mir/interpret/mod.rs b/src/librustc_middle/mir/interpret/mod.rs index e607da29ce4..fb7269f648f 100644 --- a/src/librustc_middle/mir/interpret/mod.rs +++ b/src/librustc_middle/mir/interpret/mod.rs @@ -102,7 +102,7 @@ use std::num::NonZeroU32; use std::sync::atomic::{AtomicU32, Ordering}; use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt}; -use rustc_ast::ast::LitKind; +use rustc_ast::LitKind; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{HashMapExt, Lock}; use rustc_data_structures::tiny_list::TinyList; diff --git a/src/librustc_middle/mir/mod.rs b/src/librustc_middle/mir/mod.rs index 6a2b1d11584..1faed87f8ff 100644 --- a/src/librustc_middle/mir/mod.rs +++ b/src/librustc_middle/mir/mod.rs @@ -19,7 +19,7 @@ use rustc_hir::{self, GeneratorKind}; use rustc_target::abi::VariantIdx; use polonius_engine::Atom; -pub use rustc_ast::ast::Mutability; +pub use rustc_ast::Mutability; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::graph::dominators::{dominators, Dominators}; use rustc_data_structures::graph::{self, GraphSuccessors}; diff --git a/src/librustc_middle/mir/terminator/mod.rs b/src/librustc_middle/mir/terminator/mod.rs index 0ab78381224..e8fe3a97a10 100644 --- a/src/librustc_middle/mir/terminator/mod.rs +++ b/src/librustc_middle/mir/terminator/mod.rs @@ -1,12 +1,12 @@ use crate::mir::interpret::Scalar; use crate::ty::{self, Ty, TyCtxt}; -use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece}; +use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use super::{ AssertMessage, BasicBlock, InlineAsmOperand, Operand, Place, SourceInfo, Successors, SuccessorsMut, }; -pub use rustc_ast::ast::Mutability; +pub use rustc_ast::Mutability; use rustc_macros::HashStable; use rustc_span::Span; use std::borrow::Cow; diff --git a/src/librustc_middle/ty/cast.rs b/src/librustc_middle/ty/cast.rs index 3a3caa55f60..79a3008c364 100644 --- a/src/librustc_middle/ty/cast.rs +++ b/src/librustc_middle/ty/cast.rs @@ -3,7 +3,7 @@ use crate::ty::{self, Ty}; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_macros::HashStable; /// Types that are represented as ints. diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs index d7eeaafbf46..e6b05fe4094 100644 --- a/src/librustc_middle/ty/context.rs +++ b/src/librustc_middle/ty/context.rs @@ -24,7 +24,7 @@ use crate::ty::{ ProjectionTy, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, }; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::expand::allocator::AllocatorKind; use rustc_attr as attr; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -452,7 +452,7 @@ impl<'tcx> TypeckResults<'tcx> { pub fn qpath_res(&self, qpath: &hir::QPath<'_>, id: hir::HirId) -> Res { match *qpath { hir::QPath::Resolved(_, ref path) => path.res, - hir::QPath::TypeRelative(..) => self + hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self .type_dependent_def(id) .map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)), } diff --git a/src/librustc_middle/ty/error.rs b/src/librustc_middle/ty/error.rs index 438da832226..1963881626e 100644 --- a/src/librustc_middle/ty/error.rs +++ b/src/librustc_middle/ty/error.rs @@ -1,7 +1,7 @@ use crate::traits::{ObligationCause, ObligationCauseCode}; use crate::ty::diagnostics::suggest_constraining_type_param; use crate::ty::{self, BoundRegion, Region, Ty, TyCtxt}; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_errors::Applicability::{MachineApplicable, MaybeIncorrect}; use rustc_errors::{pluralize, DiagnosticBuilder}; use rustc_hir as hir; diff --git a/src/librustc_middle/ty/fast_reject.rs b/src/librustc_middle/ty/fast_reject.rs index 7456020ee9b..1bee2d60f75 100644 --- a/src/librustc_middle/ty/fast_reject.rs +++ b/src/librustc_middle/ty/fast_reject.rs @@ -1,6 +1,6 @@ use crate::ich::StableHashingContext; use crate::ty::{self, Ty, TyCtxt}; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_hir::def_id::DefId; use std::fmt::Debug; diff --git a/src/librustc_middle/ty/layout.rs b/src/librustc_middle/ty/layout.rs index 16e65d2cca4..928cba324d5 100644 --- a/src/librustc_middle/ty/layout.rs +++ b/src/librustc_middle/ty/layout.rs @@ -4,7 +4,7 @@ use crate::mir::{GeneratorLayout, GeneratorSavedLocal}; use crate::ty::subst::Subst; use crate::ty::{self, subst::SubstsRef, ReprOptions, Ty, TyCtxt, TypeFoldable}; -use rustc_ast::ast::{self, IntTy, UintTy}; +use rustc_ast::{self as ast, IntTy, UintTy}; use rustc_attr as attr; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_hir as hir; diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index 3c79fe12255..02fd18ef968 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -17,7 +17,7 @@ use crate::traits::{self, Reveal}; use crate::ty; use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef}; use crate::ty::util::{Discr, IntTypeExt}; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_attr as attr; use rustc_data_structures::captures::Captures; use rustc_data_structures::fingerprint::Fingerprint; diff --git a/src/librustc_middle/ty/print/pretty.rs b/src/librustc_middle/ty/print/pretty.rs index fc444d4cc5b..999a1d52a26 100644 --- a/src/librustc_middle/ty/print/pretty.rs +++ b/src/librustc_middle/ty/print/pretty.rs @@ -5,7 +5,7 @@ use crate::ty::subst::{GenericArg, GenericArgKind, Subst}; use crate::ty::{self, ConstInt, DefIdTree, ParamConst, Ty, TyCtxt, TypeFoldable}; use rustc_apfloat::ieee::{Double, Single}; use rustc_apfloat::Float; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_attr::{SignedInt, UnsignedInt}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Namespace}; diff --git a/src/librustc_middle/ty/query/mod.rs b/src/librustc_middle/ty/query/mod.rs index 4d820f75c56..f220c4fb072 100644 --- a/src/librustc_middle/ty/query/mod.rs +++ b/src/librustc_middle/ty/query/mod.rs @@ -50,7 +50,7 @@ use rustc_session::utils::NativeLibKind; use rustc_session::CrateDisambiguator; use rustc_target::spec::PanicStrategy; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_attr as attr; use rustc_span::symbol::Symbol; use rustc_span::{Span, DUMMY_SP}; diff --git a/src/librustc_middle/ty/query/on_disk_cache.rs b/src/librustc_middle/ty/query/on_disk_cache.rs index 007b46b1176..dcfb8d31430 100644 --- a/src/librustc_middle/ty/query/on_disk_cache.rs +++ b/src/librustc_middle/ty/query/on_disk_cache.rs @@ -766,9 +766,7 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [(ty::Predicate<'tcx> } } -impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> - for &'tcx [rustc_ast::ast::InlineAsmTemplatePiece] -{ +impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [rustc_ast::InlineAsmTemplatePiece] { fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> { RefDecodable::decode(d) } diff --git a/src/librustc_middle/ty/structural_impls.rs b/src/librustc_middle/ty/structural_impls.rs index dfa9e38a466..ffa5df6ef2d 100644 --- a/src/librustc_middle/ty/structural_impls.rs +++ b/src/librustc_middle/ty/structural_impls.rs @@ -274,10 +274,10 @@ CloneTypeFoldableAndLiftImpls! { u64, String, crate::middle::region::Scope, - ::rustc_ast::ast::FloatTy, - ::rustc_ast::ast::InlineAsmOptions, - ::rustc_ast::ast::InlineAsmTemplatePiece, - ::rustc_ast::ast::NodeId, + ::rustc_ast::FloatTy, + ::rustc_ast::InlineAsmOptions, + ::rustc_ast::InlineAsmTemplatePiece, + ::rustc_ast::NodeId, ::rustc_span::symbol::Symbol, ::rustc_hir::def::Res, ::rustc_hir::def_id::DefId, diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs index 82160681ee8..176bad6277f 100644 --- a/src/librustc_middle/ty/sty.rs +++ b/src/librustc_middle/ty/sty.rs @@ -12,7 +12,7 @@ use crate::ty::{ }; use crate::ty::{DelaySpanBugEmitted, List, ParamEnv, TyS}; use polonius_engine::Atom; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_data_structures::captures::Captures; use rustc_hir as hir; use rustc_hir::def_id::DefId; diff --git a/src/librustc_middle/ty/util.rs b/src/librustc_middle/ty/util.rs index 5c5fe9dbd7a..63d4dcca080 100644 --- a/src/librustc_middle/ty/util.rs +++ b/src/librustc_middle/ty/util.rs @@ -10,7 +10,7 @@ use crate::ty::subst::{GenericArgKind, InternalSubsts, Subst, SubstsRef}; use crate::ty::TyKind::*; use crate::ty::{self, DefIdTree, GenericParamDefKind, List, Ty, TyCtxt, TypeFoldable}; use rustc_apfloat::Float as _; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_attr::{self as attr, SignedInt, UnsignedInt}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; diff --git a/src/librustc_mir/const_eval/machine.rs b/src/librustc_mir/const_eval/machine.rs index 2d0e68d5894..b0357c508a3 100644 --- a/src/librustc_mir/const_eval/machine.rs +++ b/src/librustc_mir/const_eval/machine.rs @@ -7,7 +7,7 @@ use std::hash::Hash; use rustc_data_structures::fx::FxHashMap; -use rustc_ast::ast::Mutability; +use rustc_ast::Mutability; use rustc_hir::def_id::DefId; use rustc_middle::mir::AssertMessage; use rustc_session::Limit; diff --git a/src/librustc_mir/dataflow/framework/engine.rs b/src/librustc_mir/dataflow/framework/engine.rs index 89e2d7088f7..b703852b1de 100644 --- a/src/librustc_mir/dataflow/framework/engine.rs +++ b/src/librustc_mir/dataflow/framework/engine.rs @@ -4,7 +4,7 @@ use std::ffi::OsString; use std::fs; use std::path::PathBuf; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_data_structures::work_queue::WorkQueue; use rustc_graphviz as dot; use rustc_hir::def_id::DefId; diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index fdec5729a54..a0c24636059 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -1,4 +1,4 @@ -use rustc_ast::ast::{self, MetaItem}; +use rustc_ast::{self as ast, MetaItem}; use rustc_middle::ty; use rustc_session::Session; use rustc_span::symbol::{sym, Symbol}; diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 78f149f6451..501a5bcddb3 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -2,7 +2,7 @@ use std::convert::TryFrom; use rustc_apfloat::ieee::{Double, Single}; use rustc_apfloat::{Float, FloatConvert}; -use rustc_ast::ast::FloatTy; +use rustc_ast::FloatTy; use rustc_attr as attr; use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar}; use rustc_middle::mir::CastKind; diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 6c8ee72bc66..9959c38e5c7 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -9,7 +9,7 @@ use rustc_hir as hir; use rustc_middle::mir::interpret::InterpResult; use rustc_middle::ty::{self, query::TyCtxtAt, Ty}; -use rustc_ast::ast::Mutability; +use rustc_ast::Mutability; use super::{AllocId, Allocation, InterpCx, MPlaceTy, Machine, MemoryKind, Scalar, ValueVisitor}; diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index b45045716d1..2c0a42a9bf3 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -329,9 +329,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.write_scalar(offset_ptr, dest)?; } sym::ptr_guaranteed_eq | sym::ptr_guaranteed_ne => { - // FIXME: return `true` for at least some comparisons where we can reliably - // determine the result of runtime (in)equality tests at compile-time. - self.write_scalar(Scalar::from_bool(false), dest)?; + let a = self.read_immediate(args[0])?.to_scalar()?; + let b = self.read_immediate(args[1])?.to_scalar()?; + let cmp = if intrinsic_name == sym::ptr_guaranteed_eq { + self.guaranteed_eq(a, b) + } else { + self.guaranteed_ne(a, b) + }; + self.write_scalar(Scalar::from_bool(cmp), dest)?; } sym::ptr_offset_from => { let a = self.read_immediate(args[0])?.to_scalar()?; @@ -448,6 +453,37 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(true) } + fn guaranteed_eq(&mut self, a: Scalar<M::PointerTag>, b: Scalar<M::PointerTag>) -> bool { + match (a, b) { + // Comparisons between integers are always known. + (Scalar::Raw { .. }, Scalar::Raw { .. }) => a == b, + // Equality with integers can never be known for sure. + (Scalar::Raw { .. }, Scalar::Ptr(_)) | (Scalar::Ptr(_), Scalar::Raw { .. }) => false, + // FIXME: return `true` for when both sides are the same pointer, *except* that + // some things (like functions and vtables) do not have stable addresses + // so we need to be careful around them. + (Scalar::Ptr(_), Scalar::Ptr(_)) => false, + } + } + + fn guaranteed_ne(&mut self, a: Scalar<M::PointerTag>, b: Scalar<M::PointerTag>) -> bool { + match (a, b) { + // Comparisons between integers are always known. + (Scalar::Raw { .. }, Scalar::Raw { .. }) => a != b, + // Comparisons of abstract pointers with null pointers are known if the pointer + // is in bounds, because if they are in bounds, the pointer can't be null. + (Scalar::Raw { data: 0, .. }, Scalar::Ptr(ptr)) + | (Scalar::Ptr(ptr), Scalar::Raw { data: 0, .. }) => !self.memory.ptr_may_be_null(ptr), + // Inequality with integers other than null can never be known for sure. + (Scalar::Raw { .. }, Scalar::Ptr(_)) | (Scalar::Ptr(_), Scalar::Raw { .. }) => false, + // FIXME: return `true` for at least some comparisons where we can reliably + // determine the result of runtime inequality tests at compile-time. + // Examples include comparison of addresses in static items, for these we can + // give reliable results. + (Scalar::Ptr(_), Scalar::Ptr(_)) => false, + } + } + pub fn exact_div( &mut self, a: ImmTy<'tcx, M::PointerTag>, diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index 5cab4ba37e3..3718da1723b 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -122,6 +122,10 @@ pub trait Machine<'mir, 'tcx>: Sized { /// Whether memory accesses should be alignment-checked. fn enforce_alignment(memory_extra: &Self::MemoryExtra) -> bool; + /// Whether, when checking alignment, we should `force_int` and thus support + /// custom alignment logic based on whatever the integer address happens to be. + fn force_int_for_alignment_check(memory_extra: &Self::MemoryExtra) -> bool; + /// Whether to enforce the validity invariant fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool; @@ -376,6 +380,12 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) { } #[inline(always)] + fn force_int_for_alignment_check(_memory_extra: &Self::MemoryExtra) -> bool { + // We do not support `force_int`. + false + } + + #[inline(always)] fn enforce_validity(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool { false // for now, we don't enforce validity } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 49d97ff7cec..d4be2ce0568 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -8,11 +8,11 @@ use std::borrow::Cow; use std::collections::VecDeque; -use std::convert::TryFrom; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::ptr; -use rustc_ast::ast::Mutability; +use rustc_ast::Mutability; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_middle::ty::{Instance, ParamEnv, TyCtxt}; use rustc_target::abi::{Align, HasDataLayout, Size, TargetDataLayout}; @@ -380,7 +380,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // if this is already a `Pointer` we want to do the bounds checks! sptr } else { - // A "real" access, we must get a pointer. + // A "real" access, we must get a pointer to be able to check the bounds. Scalar::from(self.force_ptr(sptr)?) }; Ok(match normalized.to_bits_or_ptr(self.pointer_size(), self) { @@ -411,15 +411,18 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // Test align. Check this last; if both bounds and alignment are violated // we want the error to be about the bounds. if let Some(align) = align { - if alloc_align.bytes() < align.bytes() { - // The allocation itself is not aligned enough. - // FIXME: Alignment check is too strict, depending on the base address that - // got picked we might be aligned even if this check fails. - // We instead have to fall back to converting to an integer and checking - // the "real" alignment. - throw_ub!(AlignmentCheckFailed { has: alloc_align, required: align }); + if M::force_int_for_alignment_check(&self.extra) { + let bits = self + .force_bits(ptr.into(), self.pointer_size()) + .expect("ptr-to-int cast for align check should never fail"); + check_offset_align(bits.try_into().unwrap(), align)?; + } else { + // Check allocation alignment and offset alignment. + if alloc_align.bytes() < align.bytes() { + throw_ub!(AlignmentCheckFailed { has: alloc_align, required: align }); + } + check_offset_align(ptr.offset.bytes(), align)?; } - check_offset_align(ptr.offset.bytes(), align)?; } // We can still be zero-sized in this branch, in which case we have to diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index 60712293534..30c40b8fde9 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -1,7 +1,7 @@ use std::convert::TryFrom; use rustc_apfloat::Float; -use rustc_ast::ast::FloatTy; +use rustc_ast::FloatTy; use rustc_middle::mir; use rustc_middle::mir::interpret::{InterpResult, Scalar}; use rustc_middle::ty::{self, layout::TyAndLayout, Ty}; diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index d2a5616b8ed..6aabc1941a6 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -228,7 +228,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { let base_ty = Place::ty_from(place.local, proj_base, self.body, self.tcx).ty; match base_ty.kind { ty::RawPtr(..) => self.require_unsafe( - UnsafetyViolationKind::General, + UnsafetyViolationKind::GeneralAndConstFn, UnsafetyViolationDetails::DerefOfRawPointer, ), ty::Adt(adt, _) => { diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 7e8a94f181f..be23fe7247e 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -3,7 +3,7 @@ use std::cell::Cell; -use rustc_ast::ast::Mutability; +use rustc_ast::Mutability; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def::DefKind; use rustc_hir::HirId; diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 94637bae44a..b2dda1caa54 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -12,7 +12,7 @@ //! initialization and can otherwise silence errors, if //! move analysis runs after promotion on broken MIR. -use rustc_ast::ast::LitKind; +use rustc_ast::LitKind; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::mir::traversal::ReversePostorder; diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs index 729e22a94dc..00d269a4af8 100644 --- a/src/librustc_mir/transform/rustc_peek.rs +++ b/src/librustc_mir/transform/rustc_peek.rs @@ -1,4 +1,4 @@ -use rustc_ast::ast; +use rustc_ast as ast; use rustc_span::symbol::sym; use rustc_span::Span; use rustc_target::spec::abi::Abi; diff --git a/src/librustc_mir/transform/simplify_try.rs b/src/librustc_mir/transform/simplify_try.rs index 84082edd193..06829cc2f14 100644 --- a/src/librustc_mir/transform/simplify_try.rs +++ b/src/librustc_mir/transform/simplify_try.rs @@ -14,7 +14,7 @@ use itertools::Itertools as _; use rustc_index::{bit_set::BitSet, vec::IndexVec}; use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; -use rustc_middle::ty::{List, Ty, TyCtxt}; +use rustc_middle::ty::{self, List, Ty, TyCtxt}; use rustc_target::abi::VariantIdx; use std::iter::{Enumerate, Peekable}; use std::slice::Iter; @@ -527,21 +527,76 @@ fn match_variant_field_place<'tcx>(place: Place<'tcx>) -> Option<(Local, VarFiel pub struct SimplifyBranchSame; impl<'tcx> MirPass<'tcx> for SimplifyBranchSame { - fn run_pass(&self, _: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut Body<'tcx>) { - let mut did_remove_blocks = false; - let bbs = body.basic_blocks_mut(); - for bb_idx in bbs.indices() { - let targets = match &bbs[bb_idx].terminator().kind { - TerminatorKind::SwitchInt { targets, .. } => targets, - _ => continue, - }; + fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>) { + trace!("Running SimplifyBranchSame on {:?}", source); + let finder = SimplifyBranchSameOptimizationFinder { body, tcx }; + let opts = finder.find(); + + let did_remove_blocks = opts.len() > 0; + for opt in opts.iter() { + trace!("SUCCESS: Applying optimization {:?}", opt); + // Replace `SwitchInt(..) -> [bb_first, ..];` with a `goto -> bb_first;`. + body.basic_blocks_mut()[opt.bb_to_opt_terminator].terminator_mut().kind = + TerminatorKind::Goto { target: opt.bb_to_goto }; + } + + if did_remove_blocks { + // We have dead blocks now, so remove those. + simplify::remove_dead_blocks(body); + } + } +} + +#[derive(Debug)] +struct SimplifyBranchSameOptimization { + /// All basic blocks are equal so go to this one + bb_to_goto: BasicBlock, + /// Basic block where the terminator can be simplified to a goto + bb_to_opt_terminator: BasicBlock, +} + +struct SimplifyBranchSameOptimizationFinder<'a, 'tcx> { + body: &'a Body<'tcx>, + tcx: TyCtxt<'tcx>, +} - let mut iter_bbs_reachable = targets - .iter() - .map(|idx| (*idx, &bbs[*idx])) - .filter(|(_, bb)| { - // Reaching `unreachable` is UB so assume it doesn't happen. - bb.terminator().kind != TerminatorKind::Unreachable +impl<'a, 'tcx> SimplifyBranchSameOptimizationFinder<'a, 'tcx> { + fn find(&self) -> Vec<SimplifyBranchSameOptimization> { + self.body + .basic_blocks() + .iter_enumerated() + .filter_map(|(bb_idx, bb)| { + let (discr_switched_on, targets) = match &bb.terminator().kind { + TerminatorKind::SwitchInt { targets, discr, .. } => (discr, targets), + _ => return None, + }; + + // find the adt that has its discriminant read + // assuming this must be the last statement of the block + let adt_matched_on = match &bb.statements.last()?.kind { + StatementKind::Assign(box (place, rhs)) + if Some(*place) == discr_switched_on.place() => + { + match rhs { + Rvalue::Discriminant(adt_place) if adt_place.ty(self.body, self.tcx).ty.is_enum() => adt_place, + _ => { + trace!("NO: expected a discriminant read of an enum instead of: {:?}", rhs); + return None; + } + } + } + other => { + trace!("NO: expected an assignment of a discriminant read to a place. Found: {:?}", other); + return None + }, + }; + + let mut iter_bbs_reachable = targets + .iter() + .map(|idx| (*idx, &self.body.basic_blocks()[*idx])) + .filter(|(_, bb)| { + // Reaching `unreachable` is UB so assume it doesn't happen. + bb.terminator().kind != TerminatorKind::Unreachable // But `asm!(...)` could abort the program, // so we cannot assume that the `unreachable` terminator itself is reachable. // FIXME(Centril): use a normalization pass instead of a check. @@ -549,30 +604,162 @@ impl<'tcx> MirPass<'tcx> for SimplifyBranchSame { StatementKind::LlvmInlineAsm(..) => true, _ => false, }) - }) - .peekable(); - - // We want to `goto -> bb_first`. - let bb_first = iter_bbs_reachable.peek().map(|(idx, _)| *idx).unwrap_or(targets[0]); - - // All successor basic blocks should have the exact same form. - let all_successors_equivalent = - iter_bbs_reachable.map(|(_, bb)| bb).tuple_windows().all(|(bb_l, bb_r)| { - bb_l.is_cleanup == bb_r.is_cleanup - && bb_l.terminator().kind == bb_r.terminator().kind - && bb_l.statements.iter().eq_by(&bb_r.statements, |x, y| x.kind == y.kind) - }); - - if all_successors_equivalent { - // Replace `SwitchInt(..) -> [bb_first, ..];` with a `goto -> bb_first;`. - bbs[bb_idx].terminator_mut().kind = TerminatorKind::Goto { target: bb_first }; - did_remove_blocks = true; + }) + .peekable(); + + let bb_first = iter_bbs_reachable.peek().map(|(idx, _)| *idx).unwrap_or(targets[0]); + let mut all_successors_equivalent = StatementEquality::TrivialEqual; + + // All successor basic blocks must be equal or contain statements that are pairwise considered equal. + for ((bb_l_idx,bb_l), (bb_r_idx,bb_r)) in iter_bbs_reachable.tuple_windows() { + let trivial_checks = bb_l.is_cleanup == bb_r.is_cleanup + && bb_l.terminator().kind == bb_r.terminator().kind; + let statement_check = || { + bb_l.statements.iter().zip(&bb_r.statements).try_fold(StatementEquality::TrivialEqual, |acc,(l,r)| { + let stmt_equality = self.statement_equality(*adt_matched_on, &l, bb_l_idx, &r, bb_r_idx); + if matches!(stmt_equality, StatementEquality::NotEqual) { + // short circuit + None + } else { + Some(acc.combine(&stmt_equality)) + } + }) + .unwrap_or(StatementEquality::NotEqual) + }; + if !trivial_checks { + all_successors_equivalent = StatementEquality::NotEqual; + break; + } + all_successors_equivalent = all_successors_equivalent.combine(&statement_check()); + }; + + match all_successors_equivalent{ + StatementEquality::TrivialEqual => { + // statements are trivially equal, so just take first + trace!("Statements are trivially equal"); + Some(SimplifyBranchSameOptimization { + bb_to_goto: bb_first, + bb_to_opt_terminator: bb_idx, + }) + } + StatementEquality::ConsideredEqual(bb_to_choose) => { + trace!("Statements are considered equal"); + Some(SimplifyBranchSameOptimization { + bb_to_goto: bb_to_choose, + bb_to_opt_terminator: bb_idx, + }) + } + StatementEquality::NotEqual => { + trace!("NO: not all successors of basic block {:?} were equivalent", bb_idx); + None + } + } + }) + .collect() + } + + /// Tests if two statements can be considered equal + /// + /// Statements can be trivially equal if the kinds match. + /// But they can also be considered equal in the following case A: + /// ``` + /// discriminant(_0) = 0; // bb1 + /// _0 = move _1; // bb2 + /// ``` + /// In this case the two statements are equal iff + /// 1: _0 is an enum where the variant index 0 is fieldless, and + /// 2: bb1 was targeted by a switch where the discriminant of _1 was switched on + fn statement_equality( + &self, + adt_matched_on: Place<'tcx>, + x: &Statement<'tcx>, + x_bb_idx: BasicBlock, + y: &Statement<'tcx>, + y_bb_idx: BasicBlock, + ) -> StatementEquality { + let helper = |rhs: &Rvalue<'tcx>, + place: &Box<Place<'tcx>>, + variant_index: &VariantIdx, + side_to_choose| { + let place_type = place.ty(self.body, self.tcx).ty; + let adt = match place_type.kind { + ty::Adt(adt, _) if adt.is_enum() => adt, + _ => return StatementEquality::NotEqual, + }; + let variant_is_fieldless = adt.variants[*variant_index].fields.is_empty(); + if !variant_is_fieldless { + trace!("NO: variant {:?} was not fieldless", variant_index); + return StatementEquality::NotEqual; + } + + match rhs { + Rvalue::Use(operand) if operand.place() == Some(adt_matched_on) => { + StatementEquality::ConsideredEqual(side_to_choose) + } + _ => { + trace!( + "NO: RHS of assignment was {:?}, but expected it to match the adt being matched on in the switch, which is {:?}", + rhs, + adt_matched_on + ); + StatementEquality::NotEqual + } + } + }; + match (&x.kind, &y.kind) { + // trivial case + (x, y) if x == y => StatementEquality::TrivialEqual, + + // check for case A + ( + StatementKind::Assign(box (_, rhs)), + StatementKind::SetDiscriminant { place, variant_index }, + ) => { + // choose basic block of x, as that has the assign + helper(rhs, place, variant_index, x_bb_idx) + } + ( + StatementKind::SetDiscriminant { place, variant_index }, + StatementKind::Assign(box (_, rhs)), + ) => { + // choose basic block of y, as that has the assign + helper(rhs, place, variant_index, y_bb_idx) + } + _ => { + trace!("NO: statements `{:?}` and `{:?}` not considered equal", x, y); + StatementEquality::NotEqual } } + } +} - if did_remove_blocks { - // We have dead blocks now, so remove those. - simplify::remove_dead_blocks(body); +#[derive(Copy, Clone, Eq, PartialEq)] +enum StatementEquality { + /// The two statements are trivially equal; same kind + TrivialEqual, + /// The two statements are considered equal, but may be of different kinds. The BasicBlock field is the basic block to jump to when performing the branch-same optimization. + /// For example, `_0 = _1` and `discriminant(_0) = discriminant(0)` are considered equal if 0 is a fieldless variant of an enum. But we don't want to jump to the basic block with the SetDiscriminant, as that is not legal if _1 is not the 0 variant index + ConsideredEqual(BasicBlock), + /// The two statements are not equal + NotEqual, +} + +impl StatementEquality { + fn combine(&self, other: &StatementEquality) -> StatementEquality { + use StatementEquality::*; + match (self, other) { + (TrivialEqual, TrivialEqual) => TrivialEqual, + (TrivialEqual, ConsideredEqual(b)) | (ConsideredEqual(b), TrivialEqual) => { + ConsideredEqual(*b) + } + (ConsideredEqual(b1), ConsideredEqual(b2)) => { + if b1 == b2 { + ConsideredEqual(*b1) + } else { + NotEqual + } + } + (_, NotEqual) | (NotEqual, _) => NotEqual, } } } diff --git a/src/librustc_mir_build/build/expr/into.rs b/src/librustc_mir_build/build/expr/into.rs index c3f54b39a3f..3d623abfa6e 100644 --- a/src/librustc_mir_build/build/expr/into.rs +++ b/src/librustc_mir_build/build/expr/into.rs @@ -3,7 +3,7 @@ use crate::build::expr::category::{Category, RvalueFunc}; use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; use crate::thir::*; -use rustc_ast::ast::InlineAsmOptions; +use rustc_ast::InlineAsmOptions; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir as hir; diff --git a/src/librustc_mir_build/thir/constant.rs b/src/librustc_mir_build/thir/constant.rs index e5af0b5bd6b..dd5515d39b0 100644 --- a/src/librustc_mir_build/thir/constant.rs +++ b/src/librustc_mir_build/thir/constant.rs @@ -1,4 +1,4 @@ -use rustc_ast::ast; +use rustc_ast as ast; use rustc_middle::mir::interpret::{ truncate, Allocation, ConstValue, LitToConstError, LitToConstInput, Scalar, }; diff --git a/src/librustc_mir_build/thir/cx/mod.rs b/src/librustc_mir_build/thir/cx/mod.rs index bb814ab8248..cf42fee873e 100644 --- a/src/librustc_mir_build/thir/cx/mod.rs +++ b/src/librustc_mir_build/thir/cx/mod.rs @@ -5,7 +5,7 @@ use crate::thir::util::UserAnnotatedTyHelpers; use crate::thir::*; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::Node; diff --git a/src/librustc_mir_build/thir/mod.rs b/src/librustc_mir_build/thir/mod.rs index b6ce7e0b41e..2837bfa040f 100644 --- a/src/librustc_mir_build/thir/mod.rs +++ b/src/librustc_mir_build/thir/mod.rs @@ -5,7 +5,7 @@ //! structures. use self::cx::Cx; -use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece}; +use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::infer::canonical::Canonical; diff --git a/src/librustc_mir_build/thir/pattern/check_match.rs b/src/librustc_mir_build/thir/pattern/check_match.rs index 1687286093d..4e7108667e1 100644 --- a/src/librustc_mir_build/thir/pattern/check_match.rs +++ b/src/librustc_mir_build/thir/pattern/check_match.rs @@ -4,7 +4,7 @@ use super::_match::{expand_pattern, is_useful, MatchCheckCtxt, Matrix, PatStack} use super::{PatCtxt, PatKind, PatternError}; use rustc_arena::TypedArena; -use rustc_ast::ast::Mutability; +use rustc_ast::Mutability; use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def::*; diff --git a/src/librustc_mir_build/thir/pattern/mod.rs b/src/librustc_mir_build/thir/pattern/mod.rs index daff10eb194..c163cb0e60c 100644 --- a/src/librustc_mir_build/thir/pattern/mod.rs +++ b/src/librustc_mir_build/thir/pattern/mod.rs @@ -8,7 +8,7 @@ pub(crate) use self::check_match::check_match; use crate::thir::util::UserAnnotatedTyHelpers; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; diff --git a/src/librustc_parse/lib.rs b/src/librustc_parse/lib.rs index 829e1a97b10..49deb3474d9 100644 --- a/src/librustc_parse/lib.rs +++ b/src/librustc_parse/lib.rs @@ -6,7 +6,7 @@ #![feature(try_blocks)] #![feature(or_patterns)] -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::token::{self, DelimToken, Nonterminal, Token}; use rustc_ast::tokenstream::{self, TokenStream, TokenTree}; use rustc_ast_pretty::pprust; diff --git a/src/librustc_parse/parser/attr.rs b/src/librustc_parse/parser/attr.rs index c942394fa7c..4e4429e461f 100644 --- a/src/librustc_parse/parser/attr.rs +++ b/src/librustc_parse/parser/attr.rs @@ -1,5 +1,5 @@ use super::{Parser, PathStyle}; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::attr; use rustc_ast::token::{self, Nonterminal}; use rustc_ast_pretty::pprust; diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index 27e1bb01d52..be01c7f8498 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -1,13 +1,13 @@ use super::ty::AllowPlus; use super::{BlockMode, Parser, PathStyle, SemiColonMode, SeqSep, TokenExpectType, TokenType}; -use rustc_ast::ast::{ - self, AngleBracketedArgs, AttrVec, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, - Item, ItemKind, Mutability, Param, Pat, PatKind, PathSegment, QSelf, Ty, TyKind, -}; use rustc_ast::ptr::P; use rustc_ast::token::{self, Lit, LitKind, TokenKind}; use rustc_ast::util::parser::AssocOp; +use rustc_ast::{ + self as ast, AngleBracketedArgs, AttrVec, BinOpKind, BindingMode, BlockCheckMode, Expr, + ExprKind, Item, ItemKind, Mutability, Param, Pat, PatKind, PathSegment, QSelf, Ty, TyKind, +}; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{pluralize, struct_span_err}; diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index 0ceb588b3af..e5c28f225c6 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -4,14 +4,14 @@ use super::{BlockMode, Parser, PathStyle, Restrictions, TokenType}; use super::{SemiColonMode, SeqSep, TokenExpectType}; use crate::maybe_recover_from_interpolated_ty_qpath; -use rustc_ast::ast::{self, AttrStyle, AttrVec, CaptureBy, Field, Lit, UnOp, DUMMY_NODE_ID}; -use rustc_ast::ast::{AnonConst, BinOp, BinOpKind, FnDecl, FnRetTy, MacCall, Param, Ty, TyKind}; -use rustc_ast::ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits}; use rustc_ast::ptr::P; use rustc_ast::token::{self, Token, TokenKind}; use rustc_ast::util::classify; use rustc_ast::util::literal::LitError; use rustc_ast::util::parser::{prec_let_scrutinee_needs_par, AssocOp, Fixity}; +use rustc_ast::{self as ast, AttrStyle, AttrVec, CaptureBy, Field, Lit, UnOp, DUMMY_NODE_ID}; +use rustc_ast::{AnonConst, BinOp, BinOpKind, FnDecl, FnRetTy, MacCall, Param, Ty, TyKind}; +use rustc_ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits}; use rustc_ast_pretty::pprust; use rustc_errors::{Applicability, DiagnosticBuilder, PResult}; use rustc_span::source_map::{self, Span, Spanned}; diff --git a/src/librustc_parse/parser/generics.rs b/src/librustc_parse/parser/generics.rs index be72ed6dffb..dd99a7587dd 100644 --- a/src/librustc_parse/parser/generics.rs +++ b/src/librustc_parse/parser/generics.rs @@ -1,7 +1,9 @@ use super::Parser; -use rustc_ast::ast::{self, Attribute, GenericBounds, GenericParam, GenericParamKind, WhereClause}; use rustc_ast::token; +use rustc_ast::{ + self as ast, Attribute, GenericBounds, GenericParam, GenericParamKind, WhereClause, +}; use rustc_errors::PResult; use rustc_span::symbol::{kw, sym}; diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index ce2dd15ab26..64479bc36e0 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -4,16 +4,16 @@ use super::{FollowedByType, Parser, PathStyle}; use crate::maybe_whole; -use rustc_ast::ast::{self, AttrStyle, AttrVec, Attribute, DUMMY_NODE_ID}; -use rustc_ast::ast::{AssocItem, AssocItemKind, ForeignItemKind, Item, ItemKind, Mod}; -use rustc_ast::ast::{Async, Const, Defaultness, IsAuto, Mutability, Unsafe, UseTree, UseTreeKind}; -use rustc_ast::ast::{BindingMode, Block, FnDecl, FnSig, Param, SelfKind}; -use rustc_ast::ast::{EnumDef, Generics, StructField, TraitRef, Ty, TyKind, Variant, VariantData}; -use rustc_ast::ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind}; -use rustc_ast::ast::{MacArgs, MacCall, MacDelimiter}; use rustc_ast::ptr::P; use rustc_ast::token::{self, TokenKind}; use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree}; +use rustc_ast::{self as ast, AttrStyle, AttrVec, Attribute, DUMMY_NODE_ID}; +use rustc_ast::{AssocItem, AssocItemKind, ForeignItemKind, Item, ItemKind, Mod}; +use rustc_ast::{Async, Const, Defaultness, IsAuto, Mutability, Unsafe, UseTree, UseTreeKind}; +use rustc_ast::{BindingMode, Block, FnDecl, FnSig, Param, SelfKind}; +use rustc_ast::{EnumDef, Generics, StructField, TraitRef, Ty, TyKind, Variant, VariantData}; +use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind}; +use rustc_ast::{MacArgs, MacCall, MacDelimiter}; use rustc_ast_pretty::pprust; use rustc_errors::{struct_span_err, Applicability, PResult, StashKey}; use rustc_span::edition::Edition; diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index a30131e4f7a..d67ed74bc99 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -13,14 +13,12 @@ use crate::lexer::UnmatchedBrace; use diagnostics::Error; pub use path::PathStyle; -use rustc_ast::ast::DUMMY_NODE_ID; -use rustc_ast::ast::{self, AttrStyle, AttrVec, Const, CrateSugar, Extern, Unsafe}; -use rustc_ast::ast::{ - Async, MacArgs, MacDelimiter, Mutability, StrLit, Visibility, VisibilityKind, -}; use rustc_ast::ptr::P; use rustc_ast::token::{self, DelimToken, Token, TokenKind}; use rustc_ast::tokenstream::{self, DelimSpan, TokenStream, TokenTree, TreeAndJoint}; +use rustc_ast::DUMMY_NODE_ID; +use rustc_ast::{self as ast, AttrStyle, AttrVec, Const, CrateSugar, Extern, Unsafe}; +use rustc_ast::{Async, MacArgs, MacDelimiter, Mutability, StrLit, Visibility, VisibilityKind}; use rustc_ast_pretty::pprust; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, FatalError, PResult}; use rustc_session::parse::ParseSess; diff --git a/src/librustc_parse/parser/pat.rs b/src/librustc_parse/parser/pat.rs index 6603d0afc02..1d8e6cc9bac 100644 --- a/src/librustc_parse/parser/pat.rs +++ b/src/librustc_parse/parser/pat.rs @@ -1,10 +1,10 @@ use super::{Parser, PathStyle}; use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole}; -use rustc_ast::ast::{self, AttrVec, Attribute, FieldPat, MacCall, Pat, PatKind, RangeEnd}; -use rustc_ast::ast::{BindingMode, Expr, ExprKind, Mutability, Path, QSelf, RangeSyntax}; use rustc_ast::mut_visit::{noop_visit_mac, noop_visit_pat, MutVisitor}; use rustc_ast::ptr::P; use rustc_ast::token; +use rustc_ast::{self as ast, AttrVec, Attribute, FieldPat, MacCall, Pat, PatKind, RangeEnd}; +use rustc_ast::{BindingMode, Expr, ExprKind, Mutability, Path, QSelf, RangeSyntax}; use rustc_ast_pretty::pprust; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, PResult}; use rustc_span::source_map::{respan, Span, Spanned}; diff --git a/src/librustc_parse/parser/path.rs b/src/librustc_parse/parser/path.rs index 0f2b46f7e16..54b4df8613f 100644 --- a/src/librustc_parse/parser/path.rs +++ b/src/librustc_parse/parser/path.rs @@ -1,11 +1,13 @@ use super::ty::{AllowPlus, RecoverQPath}; use super::{Parser, TokenType}; use crate::maybe_whole; -use rustc_ast::ast::{self, AngleBracketedArg, AngleBracketedArgs, GenericArg, ParenthesizedArgs}; -use rustc_ast::ast::{AnonConst, AssocTyConstraint, AssocTyConstraintKind, BlockCheckMode}; -use rustc_ast::ast::{Path, PathSegment, QSelf}; use rustc_ast::ptr::P; use rustc_ast::token::{self, Token}; +use rustc_ast::{ + self as ast, AngleBracketedArg, AngleBracketedArgs, GenericArg, ParenthesizedArgs, +}; +use rustc_ast::{AnonConst, AssocTyConstraint, AssocTyConstraintKind, BlockCheckMode}; +use rustc_ast::{Path, PathSegment, QSelf}; use rustc_errors::{pluralize, Applicability, PResult}; use rustc_span::source_map::{BytePos, Span}; use rustc_span::symbol::{kw, sym, Ident}; diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs index 5c3a5e99873..ac067cb0eab 100644 --- a/src/librustc_parse/parser/stmt.rs +++ b/src/librustc_parse/parser/stmt.rs @@ -6,12 +6,12 @@ use super::path::PathStyle; use super::{BlockMode, Parser, Restrictions, SemiColonMode}; use crate::maybe_whole; -use rustc_ast::ast; -use rustc_ast::ast::{AttrStyle, AttrVec, Attribute, MacCall, MacStmtStyle}; -use rustc_ast::ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt, StmtKind, DUMMY_NODE_ID}; +use rustc_ast as ast; use rustc_ast::ptr::P; use rustc_ast::token::{self, TokenKind}; use rustc_ast::util::classify; +use rustc_ast::{AttrStyle, AttrVec, Attribute, MacCall, MacStmtStyle}; +use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt, StmtKind, DUMMY_NODE_ID}; use rustc_errors::{Applicability, PResult}; use rustc_span::source_map::{BytePos, Span}; use rustc_span::symbol::{kw, sym}; diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs index cd66b917f23..4356850818e 100644 --- a/src/librustc_parse/parser/ty.rs +++ b/src/librustc_parse/parser/ty.rs @@ -2,11 +2,11 @@ use super::{Parser, PathStyle, TokenType}; use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole}; -use rustc_ast::ast::{self, BareFnTy, FnRetTy, GenericParam, Lifetime, MutTy, Ty, TyKind}; -use rustc_ast::ast::{GenericBound, GenericBounds, MacCall, Mutability}; -use rustc_ast::ast::{PolyTraitRef, TraitBoundModifier, TraitObjectSyntax}; use rustc_ast::ptr::P; use rustc_ast::token::{self, Token, TokenKind}; +use rustc_ast::{self as ast, BareFnTy, FnRetTy, GenericParam, Lifetime, MutTy, Ty, TyKind}; +use rustc_ast::{GenericBound, GenericBounds, MacCall, Mutability}; +use rustc_ast::{PolyTraitRef, TraitBoundModifier, TraitObjectSyntax}; use rustc_errors::{pluralize, struct_span_err, Applicability, PResult}; use rustc_span::source_map::Span; use rustc_span::symbol::{kw, sym}; diff --git a/src/librustc_parse/validate_attr.rs b/src/librustc_parse/validate_attr.rs index 2512878ec65..f4bb9610940 100644 --- a/src/librustc_parse/validate_attr.rs +++ b/src/librustc_parse/validate_attr.rs @@ -2,8 +2,8 @@ use crate::parse_in; -use rustc_ast::ast::{self, Attribute, MacArgs, MacDelimiter, MetaItem, MetaItemKind}; use rustc_ast::tokenstream::DelimSpan; +use rustc_ast::{self as ast, Attribute, MacArgs, MacDelimiter, MetaItem, MetaItemKind}; use rustc_errors::{Applicability, PResult}; use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP}; use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT; diff --git a/src/librustc_passes/check_attr.rs b/src/librustc_passes/check_attr.rs index d438fe35ff4..59edf21b733 100644 --- a/src/librustc_passes/check_attr.rs +++ b/src/librustc_passes/check_attr.rs @@ -8,7 +8,7 @@ use rustc_middle::hir::map::Map; use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; -use rustc_ast::ast::{Attribute, NestedMetaItem}; +use rustc_ast::{Attribute, NestedMetaItem}; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; diff --git a/src/librustc_passes/dead.rs b/src/librustc_passes/dead.rs index 29939c7cfaf..01da33ddd2e 100644 --- a/src/librustc_passes/dead.rs +++ b/src/librustc_passes/dead.rs @@ -15,7 +15,7 @@ use rustc_middle::middle::privacy; use rustc_middle::ty::{self, DefIdTree, TyCtxt}; use rustc_session::lint; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_span::symbol::{sym, Symbol}; // Any local node that may call something in its body block should be diff --git a/src/librustc_passes/diagnostic_items.rs b/src/librustc_passes/diagnostic_items.rs index fa59337b0f6..df0f9f157ae 100644 --- a/src/librustc_passes/diagnostic_items.rs +++ b/src/librustc_passes/diagnostic_items.rs @@ -9,7 +9,7 @@ //! //! * Compiler internal types like `Ty` and `TyCtxt` -use rustc_ast::ast; +use rustc_ast as ast; use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; diff --git a/src/librustc_passes/hir_stats.rs b/src/librustc_passes/hir_stats.rs index 139ffb9699a..9537321026e 100644 --- a/src/librustc_passes/hir_stats.rs +++ b/src/librustc_passes/hir_stats.rs @@ -2,8 +2,8 @@ // pieces of AST and HIR. The resulting numbers are good approximations but not // completely accurate (some things might be counted twice, others missed). -use rustc_ast::ast::{self, AttrId, NodeId}; use rustc_ast::visit as ast_visit; +use rustc_ast::{self as ast, AttrId, NodeId}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_hir::intravisit as hir_visit; diff --git a/src/librustc_passes/intrinsicck.rs b/src/librustc_passes/intrinsicck.rs index 931a8cb5f7d..ebe231009d3 100644 --- a/src/librustc_passes/intrinsicck.rs +++ b/src/librustc_passes/intrinsicck.rs @@ -1,4 +1,4 @@ -use rustc_ast::ast::{FloatTy, InlineAsmTemplatePiece, IntTy, UintTy}; +use rustc_ast::{FloatTy, InlineAsmTemplatePiece, IntTy, UintTy}; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; diff --git a/src/librustc_passes/lang_items.rs b/src/librustc_passes/lang_items.rs index 07415870549..0ae0c381a11 100644 --- a/src/librustc_passes/lang_items.rs +++ b/src/librustc_passes/lang_items.rs @@ -13,7 +13,7 @@ use crate::weak_lang_items; use rustc_middle::middle::cstore::ExternCrate; use rustc_middle::ty::TyCtxt; -use rustc_ast::ast::Attribute; +use rustc_ast::Attribute; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; @@ -30,7 +30,13 @@ struct LanguageItemCollector<'tcx> { impl ItemLikeVisitor<'v> for LanguageItemCollector<'tcx> { fn visit_item(&mut self, item: &hir::Item<'_>) { - self.check_for_lang(Target::from_item(item), item.hir_id, item.attrs) + self.check_for_lang(Target::from_item(item), item.hir_id, item.attrs); + + if let hir::ItemKind::Enum(def, ..) = &item.kind { + for variant in def.variants { + self.check_for_lang(Target::Variant, variant.id, variant.attrs); + } + } } fn visit_trait_item(&mut self, trait_item: &hir::TraitItem<'_>) { diff --git a/src/librustc_passes/layout_test.rs b/src/librustc_passes/layout_test.rs index 9450d75620a..504cbbfcb76 100644 --- a/src/librustc_passes/layout_test.rs +++ b/src/librustc_passes/layout_test.rs @@ -1,4 +1,4 @@ -use rustc_ast::ast::Attribute; +use rustc_ast::Attribute; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_hir::itemlikevisit::ItemLikeVisitor; diff --git a/src/librustc_passes/lib_features.rs b/src/librustc_passes/lib_features.rs index 9a4aa6a68a6..7c62a234dba 100644 --- a/src/librustc_passes/lib_features.rs +++ b/src/librustc_passes/lib_features.rs @@ -4,7 +4,7 @@ // and `#[unstable (..)]`), but are not declared in one single location // (unlike lang features), which means we need to collect them instead. -use rustc_ast::ast::{Attribute, MetaItem, MetaItemKind}; +use rustc_ast::{Attribute, MetaItem, MetaItemKind}; use rustc_errors::struct_span_err; use rustc_hir::def_id::LOCAL_CRATE; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; diff --git a/src/librustc_passes/liveness.rs b/src/librustc_passes/liveness.rs index 6477f8da008..de21f0b5e09 100644 --- a/src/librustc_passes/liveness.rs +++ b/src/librustc_passes/liveness.rs @@ -84,7 +84,7 @@ use self::LiveNodeKind::*; use self::VarKind::*; -use rustc_ast::ast::InlineAsmOptions; +use rustc_ast::InlineAsmOptions; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::Applicability; use rustc_hir as hir; @@ -526,7 +526,8 @@ fn visit_expr<'tcx>(ir: &mut IrMaps<'tcx>, expr: &'tcx Expr<'tcx>) { | hir::ExprKind::Yield(..) | hir::ExprKind::Type(..) | hir::ExprKind::Err - | hir::ExprKind::Path(hir::QPath::TypeRelative(..)) => { + | hir::ExprKind::Path(hir::QPath::TypeRelative(..)) + | hir::ExprKind::Path(hir::QPath::LangItem(..)) => { intravisit::walk_expr(ir, expr); } } @@ -1310,7 +1311,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { hir::ExprKind::Lit(..) | hir::ExprKind::Err - | hir::ExprKind::Path(hir::QPath::TypeRelative(..)) => succ, + | hir::ExprKind::Path(hir::QPath::TypeRelative(..)) + | hir::ExprKind::Path(hir::QPath::LangItem(..)) => succ, // Note that labels have been resolved, so we don't need to look // at the label ident diff --git a/src/librustc_passes/stability.rs b/src/librustc_passes/stability.rs index 1af77ae61c7..91edc7d9db7 100644 --- a/src/librustc_passes/stability.rs +++ b/src/librustc_passes/stability.rs @@ -1,7 +1,7 @@ //! A pass that annotates every item and method with its stability level, //! propagating default levels lexically from parent to children ast nodes. -use rustc_ast::ast::Attribute; +use rustc_ast::Attribute; use rustc_attr::{self as attr, ConstStability, Stability}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::struct_span_err; diff --git a/src/librustc_plugin_impl/load.rs b/src/librustc_plugin_impl/load.rs index 2f307302db0..687f7db221f 100644 --- a/src/librustc_plugin_impl/load.rs +++ b/src/librustc_plugin_impl/load.rs @@ -1,7 +1,7 @@ //! Used by `rustc` when loading a plugin. use crate::Registry; -use rustc_ast::ast::Crate; +use rustc_ast::Crate; use rustc_errors::struct_span_err; use rustc_metadata::locator; use rustc_middle::middle::cstore::MetadataLoader; diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index a3f2668691f..deb4277cb38 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1325,7 +1325,7 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> { Res::Def(kind, def_id) => Some((kind, def_id)), _ => None, }, - hir::QPath::TypeRelative(..) => self + hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self .maybe_typeck_results .and_then(|typeck_results| typeck_results.type_dependent_def(id)), }; @@ -1340,7 +1340,9 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> { let sess = self.tcx.sess; let sm = sess.source_map(); let name = match qpath { - hir::QPath::Resolved(_, path) => sm.span_to_snippet(path.span).ok(), + hir::QPath::Resolved(..) | hir::QPath::LangItem(..) => { + sm.span_to_snippet(qpath.span()).ok() + } hir::QPath::TypeRelative(_, segment) => Some(segment.ident.to_string()), }; let kind = kind.descr(def_id); diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index ddc16d18952..761724be57d 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -15,10 +15,10 @@ use crate::{ }; use crate::{Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, Segment, ToNameBinding}; -use rustc_ast::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId}; -use rustc_ast::ast::{AssocItem, AssocItemKind, MetaItemKind, StmtKind}; use rustc_ast::token::{self, Token}; use rustc_ast::visit::{self, AssocCtxt, Visitor}; +use rustc_ast::{self as ast, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId}; +use rustc_ast::{AssocItem, AssocItemKind, MetaItemKind, StmtKind}; use rustc_ast_lowering::ResolverAstLowering; use rustc_attr as attr; use rustc_data_structures::sync::Lrc; diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 1f36e1ed83d..5624a6b6acc 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -26,7 +26,7 @@ use crate::imports::ImportKind; use crate::Resolver; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::node_id::NodeMap; use rustc_ast::visit::{self, Visitor}; use rustc_ast_lowering::ResolverAstLowering; diff --git a/src/librustc_resolve/def_collector.rs b/src/librustc_resolve/def_collector.rs index 7dbf51aab28..5d5088de31b 100644 --- a/src/librustc_resolve/def_collector.rs +++ b/src/librustc_resolve/def_collector.rs @@ -1,8 +1,8 @@ use crate::Resolver; -use rustc_ast::ast::*; use rustc_ast::token::{self, Token}; use rustc_ast::visit::{self, FnKind}; use rustc_ast::walk_list; +use rustc_ast::*; use rustc_ast_lowering::ResolverAstLowering; use rustc_expand::expand::AstFragment; use rustc_hir::def_id::LocalDefId; diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 1e5e937db66..48e1068b8da 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -1,8 +1,8 @@ use std::cmp::Reverse; use std::ptr; -use rustc_ast::ast::{self, Path}; use rustc_ast::util::lev_distance::find_best_match_for_name; +use rustc_ast::{self as ast, Path}; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; diff --git a/src/librustc_resolve/imports.rs b/src/librustc_resolve/imports.rs index ef51a1c73af..b02fc427d60 100644 --- a/src/librustc_resolve/imports.rs +++ b/src/librustc_resolve/imports.rs @@ -9,9 +9,9 @@ use crate::{BindingKey, ModuleKind, ResolutionError, Resolver, Segment}; use crate::{CrateLint, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet, Weak}; use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBinding}; -use rustc_ast::ast::NodeId; use rustc_ast::unwrap_or; use rustc_ast::util::lev_distance::find_best_match_for_name; +use rustc_ast::NodeId; use rustc_ast_lowering::ResolverAstLowering; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::ptr_key::PtrKey; diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index 2f63257a982..0dbb6269d2e 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -11,9 +11,9 @@ use crate::{path_names_to_string, BindingError, CrateLint, LexicalScopeBinding}; use crate::{Module, ModuleOrUniformRoot, NameBindingKind, ParentScope, PathResult}; use crate::{ResolutionError, Resolver, Segment, UseError}; -use rustc_ast::ast::*; use rustc_ast::ptr::P; use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor}; +use rustc_ast::*; use rustc_ast::{unwrap_or, walk_list}; use rustc_ast_lowering::ResolverAstLowering; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index 2e606beca26..2549aee52ad 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -5,9 +5,9 @@ use crate::path_names_to_string; use crate::{CrateLint, Module, ModuleKind, ModuleOrUniformRoot}; use crate::{PathResult, PathSource, Segment}; -use rustc_ast::ast::{self, Expr, ExprKind, Item, ItemKind, NodeId, Path, Ty, TyKind}; use rustc_ast::util::lev_distance::find_best_match_for_name; use rustc_ast::visit::FnKind; +use rustc_ast::{self as ast, Expr, ExprKind, Item, ItemKind, NodeId, Path, Ty, TyKind}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; diff --git a/src/librustc_resolve/late/lifetimes.rs b/src/librustc_resolve/late/lifetimes.rs index e2f0d388f7e..31360d47473 100644 --- a/src/librustc_resolve/late/lifetimes.rs +++ b/src/librustc_resolve/late/lifetimes.rs @@ -941,6 +941,24 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } } + fn visit_param_bound(&mut self, bound: &'tcx hir::GenericBound<'tcx>) { + match bound { + hir::GenericBound::LangItemTrait { .. } if !self.trait_ref_hack => { + let scope = Scope::Binder { + lifetimes: FxHashMap::default(), + s: self.scope, + next_early_index: self.next_early_index(), + track_lifetime_uses: true, + opaque_type_parent: false, + }; + self.with(scope, |_, this| { + intravisit::walk_param_bound(this, bound); + }); + } + _ => intravisit::walk_param_bound(self, bound), + } + } + fn visit_poly_trait_ref( &mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>, @@ -2296,6 +2314,16 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { self.outer_index.shift_out(1); } + fn visit_param_bound(&mut self, bound: &hir::GenericBound<'_>) { + if let hir::GenericBound::LangItemTrait { .. } = bound { + self.outer_index.shift_in(1); + intravisit::walk_param_bound(self, bound); + self.outer_index.shift_out(1); + } else { + intravisit::walk_param_bound(self, bound); + } + } + fn visit_lifetime(&mut self, lifetime_ref: &hir::Lifetime) { if let Some(&lifetime) = self.map.defs.get(&lifetime_ref.hir_id) { match lifetime { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 339a5ae6675..36b7a430f78 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -20,12 +20,12 @@ pub use rustc_hir::def::{Namespace, PerNS}; use Determinacy::*; use rustc_arena::TypedArena; -use rustc_ast::ast::{self, FloatTy, IntTy, NodeId, UintTy}; -use rustc_ast::ast::{Crate, CRATE_NODE_ID}; -use rustc_ast::ast::{ItemKind, Path}; use rustc_ast::node_id::NodeMap; use rustc_ast::unwrap_or; use rustc_ast::visit::{self, Visitor}; +use rustc_ast::{self as ast, FloatTy, IntTy, NodeId, UintTy}; +use rustc_ast::{Crate, CRATE_NODE_ID}; +use rustc_ast::{ItemKind, Path}; use rustc_ast_lowering::ResolverAstLowering; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; @@ -1076,37 +1076,6 @@ impl ResolverAstLowering for Resolver<'_> { self.cstore().item_generics_num_lifetimes(def_id, sess) } - fn resolve_str_path( - &mut self, - span: Span, - crate_root: Option<Symbol>, - components: &[Symbol], - ns: Namespace, - ) -> (ast::Path, Res) { - let root = if crate_root.is_some() { kw::PathRoot } else { kw::Crate }; - let segments = iter::once(Ident::with_dummy_span(root)) - .chain( - crate_root - .into_iter() - .chain(components.iter().cloned()) - .map(Ident::with_dummy_span), - ) - .map(|i| self.new_ast_path_segment(i)) - .collect::<Vec<_>>(); - - let path = ast::Path { span, segments }; - - let parent_scope = &ParentScope::module(self.graph_root); - let res = match self.resolve_ast_path(&path, ns, parent_scope) { - Ok(res) => res, - Err((span, error)) => { - self.report_error(span, error); - Res::Err - } - }; - (path, res) - } - fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes> { self.partial_res_map.get(&id).cloned() } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 542025ac1f4..51518d63ae9 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -6,7 +6,7 @@ use crate::Namespace::*; use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy}; use crate::{CrateLint, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Weak}; use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding}; -use rustc_ast::ast::{self, NodeId}; +use rustc_ast::{self as ast, NodeId}; use rustc_ast_lowering::ResolverAstLowering; use rustc_ast_pretty::pprust; use rustc_attr::StabilityLevel; diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index f33d2f46aa2..77aecefe5a2 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -13,7 +13,7 @@ //! DumpVisitor walks the AST and processes it, and Dumper is used for //! recording the output. -use rustc_ast::ast::{self}; +use rustc_ast as ast; use rustc_ast::{token, walk_list}; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; @@ -702,14 +702,18 @@ impl<'tcx> DumpVisitor<'tcx> { // super-traits for super_bound in trait_refs.iter() { - let trait_ref = match *super_bound { - hir::GenericBound::Trait(ref trait_ref, _) => trait_ref, + let (def_id, sub_span) = match *super_bound { + hir::GenericBound::Trait(ref trait_ref, _) => ( + self.lookup_def_id(trait_ref.trait_ref.hir_ref_id), + trait_ref.trait_ref.path.segments.last().unwrap().ident.span, + ), + hir::GenericBound::LangItemTrait(lang_item, span, _, _) => { + (Some(self.tcx.require_lang_item(lang_item, Some(span))), span) + } hir::GenericBound::Outlives(..) => continue, }; - let trait_ref = &trait_ref.trait_ref; - if let Some(id) = self.lookup_def_id(trait_ref.hir_ref_id) { - let sub_span = trait_ref.path.segments.last().unwrap().ident.span; + if let Some(id) = def_id { if !self.span.filter_generated(sub_span) { let span = self.span_from_span(sub_span); self.dumper.dump_ref(Ref { @@ -762,11 +766,7 @@ impl<'tcx> DumpVisitor<'tcx> { } fn process_path(&mut self, id: hir::HirId, path: &hir::QPath<'tcx>) { - let span = match path { - hir::QPath::Resolved(_, path) => path.span, - hir::QPath::TypeRelative(_, segment) => segment.ident.span, - }; - if self.span.filter_generated(span) { + if self.span.filter_generated(path.span()) { return; } self.dump_path_ref(id, path); @@ -783,6 +783,7 @@ impl<'tcx> DumpVisitor<'tcx> { self.visit_ty(ty); std::slice::from_ref(*segment) } + hir::QPath::LangItem(..) => return, }; for seg in segments { if let Some(ref generic_args) = seg.args { @@ -1355,10 +1356,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> { } if let Some(id) = self.lookup_def_id(t.hir_id) { - let sub_span = match path { - hir::QPath::Resolved(_, path) => path.segments.last().unwrap().ident.span, - hir::QPath::TypeRelative(_, segment) => segment.ident.span, - }; + let sub_span = path.last_segment_span(); let span = self.span_from_span(sub_span); self.dumper.dump_ref(Ref { kind: RefKind::Type, diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index ca98ada4e57..629051c1820 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -9,7 +9,7 @@ mod dumper; mod span_utils; mod sig; -use rustc_ast::ast::{self}; +use rustc_ast as ast; use rustc_ast::util::comments::beautify_doc_string; use rustc_ast_pretty::pprust::attribute_to_string; use rustc_hir as hir; @@ -551,28 +551,22 @@ impl<'tcx> SaveContext<'tcx> { } } } - hir::ExprKind::Struct(qpath, ..) => { - let segment = match qpath { - hir::QPath::Resolved(_, path) => path.segments.last().unwrap(), - hir::QPath::TypeRelative(_, segment) => segment, - }; - match ty.kind { - ty::Adt(def, _) => { - let sub_span = segment.ident.span; - filter!(self.span_utils, sub_span); - let span = self.span_from_span(sub_span); - Some(Data::RefData(Ref { - kind: RefKind::Type, - span, - ref_id: id_from_def_id(def.did), - })) - } - _ => { - debug!("expected adt, found {:?}", ty); - None - } + hir::ExprKind::Struct(qpath, ..) => match ty.kind { + ty::Adt(def, _) => { + let sub_span = qpath.last_segment_span(); + filter!(self.span_utils, sub_span); + let span = self.span_from_span(sub_span); + Some(Data::RefData(Ref { + kind: RefKind::Type, + span, + ref_id: id_from_def_id(def.did), + })) } - } + _ => { + debug!("expected adt, found {:?}", ty); + None + } + }, hir::ExprKind::MethodCall(ref seg, ..) => { let method_id = match self.typeck_results().type_dependent_def_id(expr.hir_id) { Some(id) => id, @@ -636,7 +630,7 @@ impl<'tcx> SaveContext<'tcx> { }) | Node::Ty(&hir::Ty { kind: hir::TyKind::Path(ref qpath), .. }) => match qpath { hir::QPath::Resolved(_, path) => path.res, - hir::QPath::TypeRelative(..) => self + hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self .maybe_typeck_results .map_or(Res::Err, |typeck_results| typeck_results.qpath_res(qpath, hir_id)), }, @@ -653,6 +647,7 @@ impl<'tcx> SaveContext<'tcx> { let segment = match path { hir::QPath::Resolved(_, path) => path.segments.last(), hir::QPath::TypeRelative(_, segment) => Some(*segment), + hir::QPath::LangItem(..) => None, }; segment.and_then(|seg| { self.get_path_segment_data(seg).or_else(|| self.get_path_segment_data_with_id(seg, id)) diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs index 33355c4c558..b3003cc63d3 100644 --- a/src/librustc_save_analysis/sig.rs +++ b/src/librustc_save_analysis/sig.rs @@ -29,7 +29,7 @@ use crate::{id_from_def_id, id_from_hir_id, SaveContext}; use rls_data::{SigElement, Signature}; -use rustc_ast::ast::Mutability; +use rustc_ast::Mutability; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir_pretty::id_to_string; @@ -286,6 +286,9 @@ impl<'hir> Sig for hir::Ty<'hir> { refs: vec![SigElement { id, start, end }], }) } + hir::TyKind::Path(hir::QPath::LangItem(lang_item, _)) => { + Ok(text_sig(format!("#[lang = \"{}\"]", lang_item.name()))) + } hir::TyKind::TraitObject(bounds, ..) => { // FIXME recurse into bounds let bounds: Vec<hir::GenericBound<'_>> = bounds diff --git a/src/librustc_session/output.rs b/src/librustc_session/output.rs index e4bce435c4b..bf9c96c6c94 100644 --- a/src/librustc_session/output.rs +++ b/src/librustc_session/output.rs @@ -1,7 +1,7 @@ //! Related to out filenames of compilation (e.g. save analysis, binaries). use crate::config::{CrateType, Input, OutputFilenames, OutputType}; use crate::Session; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_span::symbol::sym; use rustc_span::Span; use std::path::{Path, PathBuf}; diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs index f10f9b2ce93..d7da2038b54 100644 --- a/src/librustc_session/session.rs +++ b/src/librustc_session/session.rs @@ -7,9 +7,9 @@ use crate::lint; use crate::parse::ParseSess; use crate::search_paths::{PathKind, SearchPath}; -pub use rustc_ast::ast::Attribute; pub use rustc_ast::attr::MarkedAttrs; pub use rustc_ast::crate_disambiguator::CrateDisambiguator; +pub use rustc_ast::Attribute; use rustc_data_structures::flock; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::jobserver::{self, Client}; diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index 7843c04f255..bc7efd26f46 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -706,6 +706,7 @@ symbols! { never_type, never_type_fallback, new, + new_unchecked, next, nll, no, @@ -828,6 +829,7 @@ symbols! { quad_precision_float, question_mark, quote, + range_inclusive_new, raw_dylib, raw_identifiers, raw_ref_op, diff --git a/src/librustc_symbol_mangling/v0.rs b/src/librustc_symbol_mangling/v0.rs index 56ee492de87..f01c3da8b5f 100644 --- a/src/librustc_symbol_mangling/v0.rs +++ b/src/librustc_symbol_mangling/v0.rs @@ -1,4 +1,4 @@ -use rustc_ast::ast::{FloatTy, IntTy, UintTy}; +use rustc_ast::{FloatTy, IntTy, UintTy}; use rustc_data_structures::base_n; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; diff --git a/src/librustc_trait_selection/traits/on_unimplemented.rs b/src/librustc_trait_selection/traits/on_unimplemented.rs index 7a9ed4b72dd..75822eadb2a 100644 --- a/src/librustc_trait_selection/traits/on_unimplemented.rs +++ b/src/librustc_trait_selection/traits/on_unimplemented.rs @@ -1,4 +1,4 @@ -use rustc_ast::ast::{MetaItem, NestedMetaItem}; +use rustc_ast::{MetaItem, NestedMetaItem}; use rustc_attr as attr; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{struct_span_err, ErrorReported}; diff --git a/src/librustc_traits/chalk/lowering.rs b/src/librustc_traits/chalk/lowering.rs index 75785076d9a..a043fa3f4c8 100644 --- a/src/librustc_traits/chalk/lowering.rs +++ b/src/librustc_traits/chalk/lowering.rs @@ -327,7 +327,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData<RustInterner<'tcx>>> impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> { fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::Ty<RustInterner<'tcx>> { use chalk_ir::TyData; - use rustc_ast::ast; + use rustc_ast as ast; use TyKind::*; let empty = || chalk_ir::Substitution::empty(interner); diff --git a/src/librustc_traits/chalk/mod.rs b/src/librustc_traits/chalk/mod.rs index 0c5d57551f9..f18b4ca65f6 100644 --- a/src/librustc_traits/chalk/mod.rs +++ b/src/librustc_traits/chalk/mod.rs @@ -101,7 +101,7 @@ crate fn evaluate_goal<'tcx>( match _data { chalk_ir::GenericArgData::Ty(_t) => { use chalk_ir::TyData; - use rustc_ast::ast; + use rustc_ast as ast; let _data = _t.data(&interner); let kind = match _data { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 5170a060c5f..86081b15071 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -8,7 +8,7 @@ use crate::collect::PlaceholderHirTyCollector; use crate::middle::resolve_lifetime as rl; use crate::require_c_abi_if_c_variadic; -use rustc_ast::{ast::ParamKindOrd, util::lev_distance::find_best_match_for_name}; +use rustc_ast::{util::lev_distance::find_best_match_for_name, ParamKindOrd}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::ErrorReported; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, FatalError}; @@ -1202,6 +1202,36 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) } + pub fn instantiate_lang_item_trait_ref( + &self, + lang_item: hir::LangItem, + span: Span, + hir_id: hir::HirId, + args: &GenericArgs<'_>, + self_ty: Ty<'tcx>, + bounds: &mut Bounds<'tcx>, + ) { + let trait_def_id = self.tcx().require_lang_item(lang_item, Some(span)); + + let (substs, assoc_bindings, _) = + self.create_substs_for_ast_path(span, trait_def_id, &[], args, false, Some(self_ty)); + let poly_trait_ref = ty::Binder::bind(ty::TraitRef::new(trait_def_id, substs)); + bounds.trait_bounds.push((poly_trait_ref, span, Constness::NotConst)); + + let mut dup_bindings = FxHashMap::default(); + for binding in assoc_bindings { + let _: Result<_, ErrorReported> = self.add_predicates_for_ast_type_binding( + hir_id, + poly_trait_ref, + &binding, + bounds, + false, + &mut dup_bindings, + span, + ); + } + } + fn ast_path_to_mono_trait_ref( &self, span: Span, @@ -1392,6 +1422,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { trait_bounds.push((b, Constness::NotConst)) } hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => {} + hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => self + .instantiate_lang_item_trait_ref( + lang_item, span, hir_id, args, param_ty, bounds, + ), hir::GenericBound::Outlives(ref l) => region_bounds.push(l), } } @@ -2960,6 +2994,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .map(|(ty, _, _)| ty) .unwrap_or_else(|_| tcx.ty_error()) } + hir::TyKind::Path(hir::QPath::LangItem(lang_item, span)) => { + let def_id = tcx.require_lang_item(lang_item, Some(span)); + let (substs, _, _) = self.create_substs_for_ast_path( + span, + def_id, + &[], + &GenericArgs::none(), + true, + None, + ); + self.normalize_ty(span, tcx.at(span).type_of(def_id).subst(tcx, substs)) + } hir::TyKind::Array(ref ty, ref length) => { let length_def_id = tcx.hir().local_def_id(length.hir_id); let length = ty::Const::from_anon_const(tcx, length_def_id); diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 418ea29b84f..34693a73217 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -32,7 +32,7 @@ use super::FnCtxt; use crate::hir::def_id::DefId; use crate::type_error_struct; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported}; use rustc_hir as hir; use rustc_hir::lang_items; diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 4ea76a4a9e2..aa92d8b8b2b 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -36,6 +36,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.suggest_missing_await(err, expr, expected, expr_ty); self.suggest_missing_parentheses(err, expr); self.note_need_for_fn_pointer(err, expected, expr_ty); + self.note_internal_mutation_in_method(err, expr, expected, expr_ty); } // Requires that the two types unify, and prints an error message if @@ -485,7 +486,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // parenthesize if needed (Issue #46756) hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true, // parenthesize borrows of range literals (Issue #54505) - _ if is_range_literal(self.tcx.sess.source_map(), expr) => true, + _ if is_range_literal(expr) => true, _ => false, }; let sugg_expr = if needs_parens { format!("({})", src) } else { src }; diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index e88f13a1f3a..ff0c788c18b 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -16,7 +16,7 @@ use crate::check::Needs; use crate::check::TupleArgumentsFlag::DontTupleArguments; use crate::type_error_struct; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::util::lev_distance::find_best_match_for_name; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; @@ -236,6 +236,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ExprKind::AddrOf(kind, mutbl, ref oprnd) => { self.check_expr_addr_of(kind, mutbl, oprnd, expected, expr) } + ExprKind::Path(QPath::LangItem(lang_item, _)) => { + self.check_lang_item_path(lang_item, expr) + } ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr), ExprKind::InlineAsm(asm) => self.check_expr_asm(asm), ExprKind::LlvmInlineAsm(ref asm) => { @@ -447,6 +450,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + fn check_lang_item_path( + &self, + lang_item: hir::LangItem, + expr: &'tcx hir::Expr<'tcx>, + ) -> Ty<'tcx> { + self.resolve_lang_item_path(lang_item, expr.span, expr.hir_id).1 + } + fn check_expr_path(&self, qpath: &hir::QPath<'_>, expr: &'tcx hir::Expr<'tcx>) -> Ty<'tcx> { let tcx = self.tcx; let (res, opt_ty, segs) = self.resolve_ty_and_res_ufcs(qpath, expr.hir_id, expr.span); @@ -1077,11 +1088,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return self.tcx.ty_error(); }; - let path_span = match *qpath { - QPath::Resolved(_, ref path) => path.span, - QPath::TypeRelative(ref qself, _) => qself.span, - }; - // Prohibit struct expressions when non-exhaustive flag is set. let adt = adt_ty.ty_adt_def().expect("`check_struct_path` returned non-ADT type"); if !adt.did.is_local() && variant.is_field_list_non_exhaustive() { @@ -1099,7 +1105,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { adt_ty, expected, expr.hir_id, - path_span, + qpath.span(), variant, fields, base_expr.is_none(), diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 9078dc40041..7ac6681be1a 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -7,7 +7,7 @@ use crate::check::FnCtxt; use crate::hir::def::DefKind; use crate::hir::def_id::DefId; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::util::lev_distance::{find_best_match_for_name, lev_distance}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lrc; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a625b5ea405..824e81a974c 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -88,7 +88,7 @@ pub mod writeback; use crate::astconv::{ AstConv, ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, PathSeg, }; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::util::parser::ExprPrecedence; use rustc_attr as attr; use rustc_data_structures::captures::Captures; @@ -122,10 +122,9 @@ use rustc_middle::ty::query::Providers; use rustc_middle::ty::subst::{self, InternalSubsts, Subst, SubstsRef}; use rustc_middle::ty::subst::{GenericArgKind, UserSelfTy, UserSubsts}; use rustc_middle::ty::util::{Discr, IntTypeExt, Representability}; -use rustc_middle::ty::{ - self, AdtKind, CanonicalUserType, Const, GenericParamDefKind, RegionKind, ToPolyTraitRef, - ToPredicate, Ty, TyCtxt, UserType, WithConstness, -}; +use rustc_middle::ty::WithConstness; +use rustc_middle::ty::{self, AdtKind, CanonicalUserType, Const, DefIdTree, GenericParamDefKind}; +use rustc_middle::ty::{RegionKind, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, UserType}; use rustc_session::config::{self, EntryFnType}; use rustc_session::lint; use rustc_session::parse::feature_err; @@ -4430,10 +4429,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { qpath: &QPath<'_>, hir_id: hir::HirId, ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> { - let path_span = match *qpath { - QPath::Resolved(_, ref path) => path.span, - QPath::TypeRelative(ref qself, _) => qself.span, - }; + let path_span = qpath.qself_span(); let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id); let variant = match def { Res::Err => { @@ -4511,9 +4507,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty) } + QPath::LangItem(lang_item, span) => { + self.resolve_lang_item_path(lang_item, span, hir_id) + } } } + fn resolve_lang_item_path( + &self, + lang_item: hir::LangItem, + span: Span, + hir_id: hir::HirId, + ) -> (Res, Ty<'tcx>) { + let def_id = self.tcx.require_lang_item(lang_item, Some(span)); + let def_kind = self.tcx.def_kind(def_id); + + let item_ty = if let DefKind::Variant = def_kind { + self.tcx.type_of(self.tcx.parent(def_id).expect("variant w/out parent")) + } else { + self.tcx.type_of(def_id) + }; + let substs = self.infcx.fresh_substs_for_item(span, def_id); + let ty = item_ty.subst(self.tcx, substs); + + self.write_resolution(hir_id, Ok((def_kind, def_id))); + self.add_required_obligations(span, def_id, &substs); + (Res::Def(def_kind, def_id), ty) + } + /// Resolves an associated value path into a base type and associated constant, or method /// resolution. The newly resolved definition is written into `type_dependent_defs`. pub fn resolve_ty_and_res_ufcs<'b>( @@ -4532,6 +4553,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } QPath::TypeRelative(ref qself, ref segment) => (self.to_ty(qself), qself, segment), + QPath::LangItem(..) => bug!("`resolve_ty_and_res_ufcs` called on `LangItem`"), }; if let Some(&cached_result) = self.typeck_results.borrow().type_dependent_defs().get(hir_id) { @@ -5176,6 +5198,51 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + fn note_internal_mutation_in_method( + &self, + err: &mut DiagnosticBuilder<'_>, + expr: &hir::Expr<'_>, + expected: Ty<'tcx>, + found: Ty<'tcx>, + ) { + if found != self.tcx.types.unit { + return; + } + if let ExprKind::MethodCall(path_segment, _, [rcvr, ..], _) = expr.kind { + if self + .typeck_results + .borrow() + .expr_ty_adjusted_opt(rcvr) + .map_or(true, |ty| expected.peel_refs() != ty.peel_refs()) + { + return; + } + let mut sp = MultiSpan::from_span(path_segment.ident.span); + sp.push_span_label( + path_segment.ident.span, + format!( + "this call modifies {} in-place", + match rcvr.kind { + ExprKind::Path(QPath::Resolved( + None, + hir::Path { segments: [segment], .. }, + )) => format!("`{}`", segment.ident), + _ => "its receiver".to_string(), + } + ), + ); + sp.push_span_label( + rcvr.span, + "you probably want to use this value after calling the method...".to_string(), + ); + err.span_note( + sp, + &format!("method `{}` modifies its receiver in-place", path_segment.ident), + ); + err.note(&format!("...instead of the `()` output of method `{}`", path_segment.ident)); + } + } + /// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`. fn suggest_calling_boxed_future_when_appropriate( &self, diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index 1c78bef9852..dc1ce2d89ba 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -1,5 +1,5 @@ use crate::check::FnCtxt; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_ast::util::lev_distance::find_best_match_for_name; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; @@ -947,13 +947,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // | // L | let A(()) = A(()); // | ^ ^ - [] => { - let qpath_span = match qpath { - hir::QPath::Resolved(_, path) => path.span, - hir::QPath::TypeRelative(_, ps) => ps.ident.span, - }; - (qpath_span.shrink_to_hi(), pat_span) - } + [] => (qpath.span().shrink_to_hi(), pat_span), // Easy case. Just take the "lo" of the first sub-pattern and the "hi" of the // last sub-pattern. In the case of `A(x)` the first and last may coincide. // This looks like: diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 2bde5d2c78c..d47a8273d07 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -1,7 +1,7 @@ use crate::check::{FnCtxt, Inherited}; use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter}; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index cd7429f166f..859d510dcbe 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -13,7 +13,7 @@ use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_middle::ty::{self, CrateInherentImpls, TyCtxt}; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_span::Span; /// On-demand query: yields a map containing all types mapped to their inherent impls. diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index da1f3ea62f2..7fb4026117b 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -18,8 +18,8 @@ use crate::astconv::{AstConv, Bounds, SizedByDefault}; use crate::check::intrinsic::intrinsic_operation_unsafety; use crate::constrained_generic_params as cgp; use crate::middle::resolve_lifetime as rl; -use rustc_ast::ast; -use rustc_ast::ast::MetaItemKind; +use rustc_ast as ast; +use rustc_ast::MetaItemKind; use rustc_attr::{list_contains_name, InlineAttr, OptimizeAttr}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; @@ -1959,6 +1959,20 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat predicates.extend(bounds.predicates(tcx, ty)); } + &hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => { + let mut bounds = Bounds::default(); + AstConv::instantiate_lang_item_trait_ref( + &icx, + lang_item, + span, + hir_id, + args, + ty, + &mut bounds, + ); + predicates.extend(bounds.predicates(tcx, ty)); + } + &hir::GenericBound::Outlives(ref lifetime) => { let region = AstConv::ast_region_to_region(&icx, lifetime, None); predicates.push(( @@ -2108,6 +2122,18 @@ fn predicates_from_bound<'tcx>( let _ = astconv.instantiate_poly_trait_ref(tr, constness, param_ty, &mut bounds); bounds.predicates(astconv.tcx(), param_ty) } + hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => { + let mut bounds = Bounds::default(); + astconv.instantiate_lang_item_trait_ref( + lang_item, + span, + hir_id, + args, + param_ty, + &mut bounds, + ); + bounds.predicates(astconv.tcx(), param_ty) + } hir::GenericBound::Outlives(ref lifetime) => { let region = astconv.ast_region_to_region(lifetime, None); let pred = ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(param_ty, region)) @@ -2657,7 +2683,7 @@ fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool { } fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<usize> { - use rustc_ast::ast::{Lit, LitIntType, LitKind}; + use rustc_ast::{Lit, LitIntType, LitKind}; let meta_item_list = attr.meta_item_list(); let meta_item_list: Option<&[ast::NestedMetaItem]> = meta_item_list.as_ref().map(Vec::as_ref); let sole_meta_list = match meta_item_list { diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 53979d27052..ab0b332ee19 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -7,7 +7,7 @@ use std::fmt::{self, Write}; use std::mem; use std::ops; -use rustc_ast::ast::{LitKind, MetaItem, MetaItemKind, NestedMetaItem}; +use rustc_ast::{LitKind, MetaItem, MetaItemKind, NestedMetaItem}; use rustc_feature::Features; use rustc_session::parse::ParseSess; use rustc_span::symbol::{sym, Symbol}; diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs index b4ced412e5e..96f0a1b7a7c 100644 --- a/src/librustdoc/clean/cfg/tests.rs +++ b/src/librustdoc/clean/cfg/tests.rs @@ -1,7 +1,7 @@ use super::*; -use rustc_ast::ast::*; use rustc_ast::attr; +use rustc_ast::Path; use rustc_span::symbol::{Ident, Symbol}; use rustc_span::with_default_session_globals; use rustc_span::DUMMY_SP; diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index cb7c62e3a5a..38fa8a402c4 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -2,7 +2,7 @@ use std::iter::once; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3ad357e583c..14e0fa7eabb 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -9,7 +9,7 @@ mod simplify; pub mod types; pub mod utils; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_attr as attr; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; @@ -17,6 +17,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX}; use rustc_index::vec::{Idx, IndexVec}; use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData}; +use rustc_middle::bug; use rustc_middle::middle::resolve_lifetime as rl; use rustc_middle::middle::stability; use rustc_middle::ty::fold::TypeFolder; @@ -291,6 +292,22 @@ impl Clean<GenericBound> for hir::GenericBound<'_> { fn clean(&self, cx: &DocContext<'_>) -> GenericBound { match *self { hir::GenericBound::Outlives(lt) => GenericBound::Outlives(lt.clean(cx)), + hir::GenericBound::LangItemTrait(lang_item, span, _, generic_args) => { + let def_id = cx.tcx.require_lang_item(lang_item, Some(span)); + + let trait_ref = ty::TraitRef::identity(cx.tcx, def_id); + + let generic_args = generic_args.clean(cx); + let bindings = match generic_args { + GenericArgs::AngleBracketed { bindings, .. } => bindings, + _ => bug!("clean: parenthesized `GenericBound::LangItemTrait`"), + }; + + GenericBound::TraitBound( + PolyTrait { trait_: (trait_ref, &*bindings).clean(cx), generic_params: vec![] }, + hir::TraitBoundModifier::None, + ) + } hir::GenericBound::Trait(ref t, modifier) => { GenericBound::TraitBound(t.clean(cx), modifier) } @@ -1504,6 +1521,9 @@ impl Clean<Type> for hir::Ty<'_> { trait_: box resolve_type(cx, trait_path.clean(cx), self.hir_id), } } + TyKind::Path(hir::QPath::LangItem(..)) => { + bug!("clean: requiring documentation of lang item") + } TyKind::TraitObject(ref bounds, ref lifetime) => { match bounds[0].clean(cx).trait_ { ResolvedPath { path, param_names: None, did, is_generic } => { diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 627f88df45c..914dc2e1b88 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -8,9 +8,9 @@ use std::rc::Rc; use std::sync::Arc; use std::{slice, vec}; -use rustc_ast::ast::{self, AttrStyle}; use rustc_ast::attr; use rustc_ast::util::comments::beautify_doc_string; +use rustc_ast::{self as ast, AttrStyle}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_hir::def::Res; @@ -420,7 +420,7 @@ pub struct Attributes { impl Attributes { /// Extracts the content from an attribute `#[doc(cfg(content))]`. pub fn extract_cfg(mi: &ast::MetaItem) -> Option<&ast::MetaItem> { - use rustc_ast::ast::NestedMetaItem::MetaItem; + use rustc_ast::NestedMetaItem::MetaItem; if let ast::MetaItemKind::List(ref nmis) = mi.kind { if nmis.len() == 1 { diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index a7d03fcabf5..a502a27948e 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -335,6 +335,7 @@ pub fn qpath_to_string(p: &hir::QPath<'_>) -> String { let segments = match *p { hir::QPath::Resolved(_, ref path) => &path.segments, hir::QPath::TypeRelative(_, ref segment) => return segment.ident.to_string(), + hir::QPath::LangItem(lang_item, ..) => return lang_item.name().to_string(), }; let mut s = String::new(); diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index 943729a74ab..98125adbdea 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -2,7 +2,7 @@ //! manner (and with prettier names) before cleaning. pub use self::StructType::*; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_span::hygiene::MacroKind; use rustc_span::{self, Span, Symbol}; diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index f7fc3579d67..d4d6a8119c3 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1,4 +1,4 @@ -use rustc_ast::ast; +use rustc_ast as ast; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_expand::base::SyntaxExtensionKind; use rustc_feature::UnstableFeatures; @@ -1204,20 +1204,20 @@ fn handle_variant( } const PRIMITIVES: &[(&str, Res)] = &[ - ("u8", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::ast::UintTy::U8))), - ("u16", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::ast::UintTy::U16))), - ("u32", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::ast::UintTy::U32))), - ("u64", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::ast::UintTy::U64))), - ("u128", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::ast::UintTy::U128))), - ("usize", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::ast::UintTy::Usize))), - ("i8", Res::PrimTy(hir::PrimTy::Int(rustc_ast::ast::IntTy::I8))), - ("i16", Res::PrimTy(hir::PrimTy::Int(rustc_ast::ast::IntTy::I16))), - ("i32", Res::PrimTy(hir::PrimTy::Int(rustc_ast::ast::IntTy::I32))), - ("i64", Res::PrimTy(hir::PrimTy::Int(rustc_ast::ast::IntTy::I64))), - ("i128", Res::PrimTy(hir::PrimTy::Int(rustc_ast::ast::IntTy::I128))), - ("isize", Res::PrimTy(hir::PrimTy::Int(rustc_ast::ast::IntTy::Isize))), - ("f32", Res::PrimTy(hir::PrimTy::Float(rustc_ast::ast::FloatTy::F32))), - ("f64", Res::PrimTy(hir::PrimTy::Float(rustc_ast::ast::FloatTy::F64))), + ("u8", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::U8))), + ("u16", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::U16))), + ("u32", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::U32))), + ("u64", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::U64))), + ("u128", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::U128))), + ("usize", Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::Usize))), + ("i8", Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::I8))), + ("i16", Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::I16))), + ("i32", Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::I32))), + ("i64", Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::I64))), + ("i128", Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::I128))), + ("isize", Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::Isize))), + ("f32", Res::PrimTy(hir::PrimTy::Float(rustc_ast::FloatTy::F32))), + ("f64", Res::PrimTy(hir::PrimTy::Float(rustc_ast::FloatTy::F64))), ("str", Res::PrimTy(hir::PrimTy::Str)), ("bool", Res::PrimTy(hir::PrimTy::Bool)), ("char", Res::PrimTy(hir::PrimTy::Char)), diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 62f52ea5213..693d5b9fb07 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -1,4 +1,4 @@ -use rustc_ast::ast; +use rustc_ast as ast; use rustc_data_structures::sync::Lrc; use rustc_errors::ErrorReported; use rustc_feature::UnstableFeatures; diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index be80193db8c..ac9f839600b 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -1,7 +1,7 @@ //! The Rust AST Visitor. Extracts useful information and massages it into a form //! usable for `clean`. -use rustc_ast::ast; +use rustc_ast as ast; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; diff --git a/src/test/mir-opt/simplify-arm.rs b/src/test/mir-opt/simplify-arm.rs index 20b4e67f53b..9d81b7f01cf 100644 --- a/src/test/mir-opt/simplify-arm.rs +++ b/src/test/mir-opt/simplify-arm.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z mir-opt-level=1 +// compile-flags: -Z mir-opt-level=2 // EMIT_MIR simplify_arm.id.SimplifyArmIdentity.diff // EMIT_MIR simplify_arm.id.SimplifyBranchSame.diff // EMIT_MIR simplify_arm.id_result.SimplifyArmIdentity.diff diff --git a/src/test/mir-opt/simplify_arm.id.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_arm.id.SimplifyArmIdentity.diff index 0cddcb061cf..ecb4384fc6f 100644 --- a/src/test/mir-opt/simplify_arm.id.SimplifyArmIdentity.diff +++ b/src/test/mir-opt/simplify_arm.id.SimplifyArmIdentity.diff @@ -8,7 +8,8 @@ let _3: u8; // in scope 0 at $DIR/simplify-arm.rs:11:14: 11:15 let mut _4: u8; // in scope 0 at $DIR/simplify-arm.rs:11:25: 11:26 scope 1 { - debug v => _3; // in scope 1 at $DIR/simplify-arm.rs:11:14: 11:15 +- debug v => _3; // in scope 1 at $DIR/simplify-arm.rs:11:14: 11:15 ++ debug v => ((_0 as Some).0: u8); // in scope 1 at $DIR/simplify-arm.rs:11:14: 11:15 } bb0: { @@ -26,14 +27,15 @@ } bb3: { - StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:11:14: 11:15 - _3 = ((_1 as Some).0: u8); // scope 0 at $DIR/simplify-arm.rs:11:14: 11:15 - StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:11:25: 11:26 - _4 = _3; // scope 1 at $DIR/simplify-arm.rs:11:25: 11:26 - ((_0 as Some).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:11:20: 11:27 - discriminant(_0) = 1; // scope 1 at $DIR/simplify-arm.rs:11:20: 11:27 - StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:11:26: 11:27 - StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:11:26: 11:27 +- StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:11:14: 11:15 +- _3 = ((_1 as Some).0: u8); // scope 0 at $DIR/simplify-arm.rs:11:14: 11:15 +- StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:11:25: 11:26 +- _4 = _3; // scope 1 at $DIR/simplify-arm.rs:11:25: 11:26 +- ((_0 as Some).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:11:20: 11:27 +- discriminant(_0) = 1; // scope 1 at $DIR/simplify-arm.rs:11:20: 11:27 +- StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:11:26: 11:27 +- StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:11:26: 11:27 ++ _0 = move _1; // scope 1 at $DIR/simplify-arm.rs:11:20: 11:27 goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:10:5: 13:6 } diff --git a/src/test/mir-opt/simplify_arm.id.SimplifyBranchSame.diff b/src/test/mir-opt/simplify_arm.id.SimplifyBranchSame.diff index cd5962c682a..eb1d6f656f4 100644 --- a/src/test/mir-opt/simplify_arm.id.SimplifyBranchSame.diff +++ b/src/test/mir-opt/simplify_arm.id.SimplifyBranchSame.diff @@ -8,36 +8,32 @@ let _3: u8; // in scope 0 at $DIR/simplify-arm.rs:11:14: 11:15 let mut _4: u8; // in scope 0 at $DIR/simplify-arm.rs:11:25: 11:26 scope 1 { - debug v => _3; // in scope 1 at $DIR/simplify-arm.rs:11:14: 11:15 + debug v => ((_0 as Some).0: u8); // in scope 1 at $DIR/simplify-arm.rs:11:14: 11:15 } bb0: { _2 = discriminant(_1); // scope 0 at $DIR/simplify-arm.rs:11:9: 11:16 - switchInt(move _2) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:11:9: 11:16 +- switchInt(move _2) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:11:9: 11:16 ++ goto -> bb1; // scope 0 at $DIR/simplify-arm.rs:11:9: 11:16 } bb1: { - discriminant(_0) = 0; // scope 0 at $DIR/simplify-arm.rs:12:17: 12:21 - goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:10:5: 13:6 +- discriminant(_0) = 0; // scope 0 at $DIR/simplify-arm.rs:12:17: 12:21 +- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:10:5: 13:6 +- } +- +- bb2: { +- unreachable; // scope 0 at $DIR/simplify-arm.rs:10:11: 10:12 +- } +- +- bb3: { + _0 = move _1; // scope 1 at $DIR/simplify-arm.rs:11:20: 11:27 +- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:10:5: 13:6 ++ goto -> bb2; // scope 0 at $DIR/simplify-arm.rs:10:5: 13:6 } - bb2: { - unreachable; // scope 0 at $DIR/simplify-arm.rs:10:11: 10:12 - } - - bb3: { - StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:11:14: 11:15 - _3 = ((_1 as Some).0: u8); // scope 0 at $DIR/simplify-arm.rs:11:14: 11:15 - StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:11:25: 11:26 - _4 = _3; // scope 1 at $DIR/simplify-arm.rs:11:25: 11:26 - ((_0 as Some).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:11:20: 11:27 - discriminant(_0) = 1; // scope 1 at $DIR/simplify-arm.rs:11:20: 11:27 - StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:11:26: 11:27 - StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:11:26: 11:27 - goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:10:5: 13:6 - } - - bb4: { +- bb4: { ++ bb2: { return; // scope 0 at $DIR/simplify-arm.rs:14:2: 14:2 } } diff --git a/src/test/mir-opt/simplify_arm.id_result.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_arm.id_result.SimplifyArmIdentity.diff index 642ccc1ab14..253e3236ff7 100644 --- a/src/test/mir-opt/simplify_arm.id_result.SimplifyArmIdentity.diff +++ b/src/test/mir-opt/simplify_arm.id_result.SimplifyArmIdentity.diff @@ -10,10 +10,12 @@ let _5: i32; // in scope 0 at $DIR/simplify-arm.rs:19:13: 19:14 let mut _6: i32; // in scope 0 at $DIR/simplify-arm.rs:19:23: 19:24 scope 1 { - debug x => _3; // in scope 1 at $DIR/simplify-arm.rs:18:12: 18:13 +- debug x => _3; // in scope 1 at $DIR/simplify-arm.rs:18:12: 18:13 ++ debug x => ((_0 as Ok).0: u8); // in scope 1 at $DIR/simplify-arm.rs:18:12: 18:13 } scope 2 { - debug y => _5; // in scope 2 at $DIR/simplify-arm.rs:19:13: 19:14 +- debug y => _5; // in scope 2 at $DIR/simplify-arm.rs:19:13: 19:14 ++ debug y => ((_0 as Err).0: i32); // in scope 2 at $DIR/simplify-arm.rs:19:13: 19:14 } bb0: { @@ -22,14 +24,15 @@ } bb1: { - StorageLive(_5); // scope 0 at $DIR/simplify-arm.rs:19:13: 19:14 - _5 = ((_1 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:19:13: 19:14 - StorageLive(_6); // scope 2 at $DIR/simplify-arm.rs:19:23: 19:24 - _6 = _5; // scope 2 at $DIR/simplify-arm.rs:19:23: 19:24 - ((_0 as Err).0: i32) = move _6; // scope 2 at $DIR/simplify-arm.rs:19:19: 19:25 - discriminant(_0) = 1; // scope 2 at $DIR/simplify-arm.rs:19:19: 19:25 - StorageDead(_6); // scope 2 at $DIR/simplify-arm.rs:19:24: 19:25 - StorageDead(_5); // scope 0 at $DIR/simplify-arm.rs:19:24: 19:25 +- StorageLive(_5); // scope 0 at $DIR/simplify-arm.rs:19:13: 19:14 +- _5 = ((_1 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:19:13: 19:14 +- StorageLive(_6); // scope 2 at $DIR/simplify-arm.rs:19:23: 19:24 +- _6 = _5; // scope 2 at $DIR/simplify-arm.rs:19:23: 19:24 +- ((_0 as Err).0: i32) = move _6; // scope 2 at $DIR/simplify-arm.rs:19:19: 19:25 +- discriminant(_0) = 1; // scope 2 at $DIR/simplify-arm.rs:19:19: 19:25 +- StorageDead(_6); // scope 2 at $DIR/simplify-arm.rs:19:24: 19:25 +- StorageDead(_5); // scope 0 at $DIR/simplify-arm.rs:19:24: 19:25 ++ _0 = move _1; // scope 2 at $DIR/simplify-arm.rs:19:19: 19:25 goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:17:5: 20:6 } @@ -38,14 +41,15 @@ } bb3: { - StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:18:12: 18:13 - _3 = ((_1 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:18:12: 18:13 - StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:18:21: 18:22 - _4 = _3; // scope 1 at $DIR/simplify-arm.rs:18:21: 18:22 - ((_0 as Ok).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:18:18: 18:23 - discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:18:18: 18:23 - StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:18:22: 18:23 - StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:18:22: 18:23 +- StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:18:12: 18:13 +- _3 = ((_1 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:18:12: 18:13 +- StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:18:21: 18:22 +- _4 = _3; // scope 1 at $DIR/simplify-arm.rs:18:21: 18:22 +- ((_0 as Ok).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:18:18: 18:23 +- discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:18:18: 18:23 +- StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:18:22: 18:23 +- StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:18:22: 18:23 ++ _0 = move _1; // scope 1 at $DIR/simplify-arm.rs:18:18: 18:23 goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:17:5: 20:6 } diff --git a/src/test/mir-opt/simplify_arm.id_result.SimplifyBranchSame.diff b/src/test/mir-opt/simplify_arm.id_result.SimplifyBranchSame.diff index 95ce09a39ed..23cf43c5319 100644 --- a/src/test/mir-opt/simplify_arm.id_result.SimplifyBranchSame.diff +++ b/src/test/mir-opt/simplify_arm.id_result.SimplifyBranchSame.diff @@ -10,46 +10,35 @@ let _5: i32; // in scope 0 at $DIR/simplify-arm.rs:19:13: 19:14 let mut _6: i32; // in scope 0 at $DIR/simplify-arm.rs:19:23: 19:24 scope 1 { - debug x => _3; // in scope 1 at $DIR/simplify-arm.rs:18:12: 18:13 + debug x => ((_0 as Ok).0: u8); // in scope 1 at $DIR/simplify-arm.rs:18:12: 18:13 } scope 2 { - debug y => _5; // in scope 2 at $DIR/simplify-arm.rs:19:13: 19:14 + debug y => ((_0 as Err).0: i32); // in scope 2 at $DIR/simplify-arm.rs:19:13: 19:14 } bb0: { _2 = discriminant(_1); // scope 0 at $DIR/simplify-arm.rs:18:9: 18:14 - switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:18:9: 18:14 +- switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:18:9: 18:14 ++ goto -> bb1; // scope 0 at $DIR/simplify-arm.rs:18:9: 18:14 } bb1: { - StorageLive(_5); // scope 0 at $DIR/simplify-arm.rs:19:13: 19:14 - _5 = ((_1 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:19:13: 19:14 - StorageLive(_6); // scope 2 at $DIR/simplify-arm.rs:19:23: 19:24 - _6 = _5; // scope 2 at $DIR/simplify-arm.rs:19:23: 19:24 - ((_0 as Err).0: i32) = move _6; // scope 2 at $DIR/simplify-arm.rs:19:19: 19:25 - discriminant(_0) = 1; // scope 2 at $DIR/simplify-arm.rs:19:19: 19:25 - StorageDead(_6); // scope 2 at $DIR/simplify-arm.rs:19:24: 19:25 - StorageDead(_5); // scope 0 at $DIR/simplify-arm.rs:19:24: 19:25 - goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:17:5: 20:6 +- _0 = move _1; // scope 2 at $DIR/simplify-arm.rs:19:19: 19:25 +- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:17:5: 20:6 +- } +- +- bb2: { +- unreachable; // scope 0 at $DIR/simplify-arm.rs:17:11: 17:12 +- } +- +- bb3: { + _0 = move _1; // scope 1 at $DIR/simplify-arm.rs:18:18: 18:23 +- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:17:5: 20:6 ++ goto -> bb2; // scope 0 at $DIR/simplify-arm.rs:17:5: 20:6 } - bb2: { - unreachable; // scope 0 at $DIR/simplify-arm.rs:17:11: 17:12 - } - - bb3: { - StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:18:12: 18:13 - _3 = ((_1 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:18:12: 18:13 - StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:18:21: 18:22 - _4 = _3; // scope 1 at $DIR/simplify-arm.rs:18:21: 18:22 - ((_0 as Ok).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:18:18: 18:23 - discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:18:18: 18:23 - StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:18:22: 18:23 - StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:18:22: 18:23 - goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:17:5: 20:6 - } - - bb4: { +- bb4: { ++ bb2: { return; // scope 0 at $DIR/simplify-arm.rs:21:2: 21:2 } } diff --git a/src/test/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff index b46ca21fb90..063f8495960 100644 --- a/src/test/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff +++ b/src/test/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff @@ -15,94 +15,88 @@ let _10: u8; // in scope 0 at $DIR/simplify-arm.rs:24:13: 24:15 let mut _11: u8; // in scope 0 at $DIR/simplify-arm.rs:25:8: 25:9 scope 1 { - debug x => _2; // in scope 1 at $DIR/simplify-arm.rs:24:9: 24:10 +- debug x => _2; // in scope 1 at $DIR/simplify-arm.rs:24:9: 24:10 ++ debug x => ((_0 as Ok).0: u8); // in scope 1 at $DIR/simplify-arm.rs:24:9: 24:10 } scope 2 { - debug err => _6; // in scope 2 at $DIR/simplify-arm.rs:24:14: 24:15 +- debug err => _6; // in scope 2 at $DIR/simplify-arm.rs:24:14: 24:15 ++ debug err => ((_0 as Err).0: i32); // in scope 2 at $DIR/simplify-arm.rs:24:14: 24:15 scope 3 { + scope 7 { +- debug t => _9; // in scope 7 at $SRC_DIR/core/src/convert/mod.rs:LL:COL ++ debug t => ((_0 as Err).0: i32); // in scope 7 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + } + scope 8 { +- debug v => _8; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ debug v => ((_0 as Err).0: i32); // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _12: i32; // in scope 8 at $DIR/simplify-arm.rs:24:14: 24:15 + } } } scope 4 { - debug val => _10; // in scope 4 at $DIR/simplify-arm.rs:24:13: 24:15 +- debug val => _10; // in scope 4 at $DIR/simplify-arm.rs:24:13: 24:15 ++ debug val => ((_0 as Ok).0: u8); // in scope 4 at $DIR/simplify-arm.rs:24:13: 24:15 scope 5 { } } + scope 6 { + debug self => _4; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + } bb0: { StorageLive(_2); // scope 0 at $DIR/simplify-arm.rs:24:9: 24:10 StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15 StorageLive(_4); // scope 0 at $DIR/simplify-arm.rs:24:13: 24:14 _4 = _1; // scope 0 at $DIR/simplify-arm.rs:24:13: 24:14 - _3 = const <std::result::Result<u8, i32> as std::ops::Try>::into_result(move _4) -> bb1; // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15 - // ty::Const - // + ty: fn(std::result::Result<u8, i32>) -> std::result::Result<<std::result::Result<u8, i32> as std::ops::Try>::Ok, <std::result::Result<u8, i32> as std::ops::Try>::Error> {<std::result::Result<u8, i32> as std::ops::Try>::into_result} - // + val: Value(Scalar(<ZST>)) - // mir::Constant - // + span: $DIR/simplify-arm.rs:24:13: 24:15 - // + literal: Const { ty: fn(std::result::Result<u8, i32>) -> std::result::Result<<std::result::Result<u8, i32> as std::ops::Try>::Ok, <std::result::Result<u8, i32> as std::ops::Try>::Error> {<std::result::Result<u8, i32> as std::ops::Try>::into_result}, val: Value(Scalar(<ZST>)) } - } - - bb1: { + _3 = move _4; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL StorageDead(_4); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 _5 = discriminant(_3); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 - switchInt(move _5) -> [0_isize: bb2, 1_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 + switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 } - bb2: { - StorageLive(_10); // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15 - _10 = ((_3 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15 - _2 = _10; // scope 5 at $DIR/simplify-arm.rs:24:13: 24:15 - StorageDead(_10); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 + bb1: { +- StorageLive(_10); // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15 +- _10 = ((_3 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15 +- _2 = _10; // scope 5 at $DIR/simplify-arm.rs:24:13: 24:15 +- StorageDead(_10); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 ++ _0 = move _3; // scope 1 at $DIR/simplify-arm.rs:25:5: 25:10 StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:24:15: 24:16 - StorageLive(_11); // scope 1 at $DIR/simplify-arm.rs:25:8: 25:9 - _11 = _2; // scope 1 at $DIR/simplify-arm.rs:25:8: 25:9 - ((_0 as Ok).0: u8) = move _11; // scope 1 at $DIR/simplify-arm.rs:25:5: 25:10 - discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:25:5: 25:10 - StorageDead(_11); // scope 1 at $DIR/simplify-arm.rs:25:9: 25:10 +- StorageLive(_11); // scope 1 at $DIR/simplify-arm.rs:25:8: 25:9 +- _11 = _2; // scope 1 at $DIR/simplify-arm.rs:25:8: 25:9 +- ((_0 as Ok).0: u8) = move _11; // scope 1 at $DIR/simplify-arm.rs:25:5: 25:10 +- discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:25:5: 25:10 +- StorageDead(_11); // scope 1 at $DIR/simplify-arm.rs:25:9: 25:10 StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:26:1: 26:2 - goto -> bb5; // scope 0 at $DIR/simplify-arm.rs:26:2: 26:2 + goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:26:2: 26:2 } - bb3: { + bb2: { unreachable; // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15 } - bb4: { - StorageLive(_6); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 - _6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 - StorageLive(_8); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15 - StorageLive(_9); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15 - _9 = _6; // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15 - _8 = const <i32 as std::convert::From<i32>>::from(move _9) -> bb6; // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15 - // ty::Const - // + ty: fn(i32) -> i32 {<i32 as std::convert::From<i32>>::from} - // + val: Value(Scalar(<ZST>)) - // mir::Constant - // + span: $DIR/simplify-arm.rs:24:14: 24:15 - // + literal: Const { ty: fn(i32) -> i32 {<i32 as std::convert::From<i32>>::from}, val: Value(Scalar(<ZST>)) } + bb3: { +- StorageLive(_6); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 +- _6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 +- StorageLive(_8); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15 +- StorageLive(_9); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15 +- _9 = _6; // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15 +- _8 = move _9; // scope 7 at $SRC_DIR/core/src/convert/mod.rs:LL:COL +- StorageDead(_9); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15 +- StorageLive(_12); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL +- _12 = move _8; // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL +- ((_0 as Err).0: i32) = move _12; // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL +- discriminant(_0) = 1; // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL +- StorageDead(_12); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL +- StorageDead(_8); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15 +- StorageDead(_6); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 ++ _0 = move _3; // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:24:15: 24:16 + StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:26:1: 26:2 + goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 } - bb5: { + bb4: { return; // scope 0 at $DIR/simplify-arm.rs:26:2: 26:2 } - - bb6: { - StorageDead(_9); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15 - _0 = const <std::result::Result<u8, i32> as std::ops::Try>::from_error(move _8) -> bb7; // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15 - // ty::Const - // + ty: fn(<std::result::Result<u8, i32> as std::ops::Try>::Error) -> std::result::Result<u8, i32> {<std::result::Result<u8, i32> as std::ops::Try>::from_error} - // + val: Value(Scalar(<ZST>)) - // mir::Constant - // + span: $DIR/simplify-arm.rs:24:13: 24:15 - // + literal: Const { ty: fn(<std::result::Result<u8, i32> as std::ops::Try>::Error) -> std::result::Result<u8, i32> {<std::result::Result<u8, i32> as std::ops::Try>::from_error}, val: Value(Scalar(<ZST>)) } - } - - bb7: { - StorageDead(_8); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15 - StorageDead(_6); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 - StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:24:15: 24:16 - StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:26:1: 26:2 - goto -> bb5; // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 - } } diff --git a/src/test/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff b/src/test/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff index 93412d1a74f..7c7b1b6d6c6 100644 --- a/src/test/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff +++ b/src/test/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff @@ -15,94 +15,62 @@ let _10: u8; // in scope 0 at $DIR/simplify-arm.rs:24:13: 24:15 let mut _11: u8; // in scope 0 at $DIR/simplify-arm.rs:25:8: 25:9 scope 1 { - debug x => _2; // in scope 1 at $DIR/simplify-arm.rs:24:9: 24:10 + debug x => ((_0 as Ok).0: u8); // in scope 1 at $DIR/simplify-arm.rs:24:9: 24:10 } scope 2 { - debug err => _6; // in scope 2 at $DIR/simplify-arm.rs:24:14: 24:15 + debug err => ((_0 as Err).0: i32); // in scope 2 at $DIR/simplify-arm.rs:24:14: 24:15 scope 3 { + scope 7 { + debug t => ((_0 as Err).0: i32); // in scope 7 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + } + scope 8 { + debug v => ((_0 as Err).0: i32); // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _12: i32; // in scope 8 at $DIR/simplify-arm.rs:24:14: 24:15 + } } } scope 4 { - debug val => _10; // in scope 4 at $DIR/simplify-arm.rs:24:13: 24:15 + debug val => ((_0 as Ok).0: u8); // in scope 4 at $DIR/simplify-arm.rs:24:13: 24:15 scope 5 { } } + scope 6 { + debug self => _4; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + } bb0: { StorageLive(_2); // scope 0 at $DIR/simplify-arm.rs:24:9: 24:10 StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15 StorageLive(_4); // scope 0 at $DIR/simplify-arm.rs:24:13: 24:14 _4 = _1; // scope 0 at $DIR/simplify-arm.rs:24:13: 24:14 - _3 = const <std::result::Result<u8, i32> as std::ops::Try>::into_result(move _4) -> bb1; // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15 - // ty::Const - // + ty: fn(std::result::Result<u8, i32>) -> std::result::Result<<std::result::Result<u8, i32> as std::ops::Try>::Ok, <std::result::Result<u8, i32> as std::ops::Try>::Error> {<std::result::Result<u8, i32> as std::ops::Try>::into_result} - // + val: Value(Scalar(<ZST>)) - // mir::Constant - // + span: $DIR/simplify-arm.rs:24:13: 24:15 - // + literal: Const { ty: fn(std::result::Result<u8, i32>) -> std::result::Result<<std::result::Result<u8, i32> as std::ops::Try>::Ok, <std::result::Result<u8, i32> as std::ops::Try>::Error> {<std::result::Result<u8, i32> as std::ops::Try>::into_result}, val: Value(Scalar(<ZST>)) } - } - - bb1: { + _3 = move _4; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL StorageDead(_4); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 _5 = discriminant(_3); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 - switchInt(move _5) -> [0_isize: bb2, 1_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 +- switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 ++ goto -> bb1; // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 } - bb2: { - StorageLive(_10); // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15 - _10 = ((_3 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15 - _2 = _10; // scope 5 at $DIR/simplify-arm.rs:24:13: 24:15 - StorageDead(_10); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 + bb1: { + _0 = move _3; // scope 1 at $DIR/simplify-arm.rs:25:5: 25:10 StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:24:15: 24:16 - StorageLive(_11); // scope 1 at $DIR/simplify-arm.rs:25:8: 25:9 - _11 = _2; // scope 1 at $DIR/simplify-arm.rs:25:8: 25:9 - ((_0 as Ok).0: u8) = move _11; // scope 1 at $DIR/simplify-arm.rs:25:5: 25:10 - discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:25:5: 25:10 - StorageDead(_11); // scope 1 at $DIR/simplify-arm.rs:25:9: 25:10 StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:26:1: 26:2 - goto -> bb5; // scope 0 at $DIR/simplify-arm.rs:26:2: 26:2 - } - - bb3: { - unreachable; // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15 +- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:26:2: 26:2 ++ goto -> bb2; // scope 0 at $DIR/simplify-arm.rs:26:2: 26:2 } - bb4: { - StorageLive(_6); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 - _6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 - StorageLive(_8); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15 - StorageLive(_9); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15 - _9 = _6; // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15 - _8 = const <i32 as std::convert::From<i32>>::from(move _9) -> bb6; // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15 - // ty::Const - // + ty: fn(i32) -> i32 {<i32 as std::convert::From<i32>>::from} - // + val: Value(Scalar(<ZST>)) - // mir::Constant - // + span: $DIR/simplify-arm.rs:24:14: 24:15 - // + literal: Const { ty: fn(i32) -> i32 {<i32 as std::convert::From<i32>>::from}, val: Value(Scalar(<ZST>)) } - } - - bb5: { + bb2: { +- unreachable; // scope 0 at $DIR/simplify-arm.rs:24:13: 24:15 +- } +- +- bb3: { +- _0 = move _3; // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL +- StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:24:15: 24:16 +- StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:26:1: 26:2 +- goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 +- } +- +- bb4: { return; // scope 0 at $DIR/simplify-arm.rs:26:2: 26:2 } - - bb6: { - StorageDead(_9); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15 - _0 = const <std::result::Result<u8, i32> as std::ops::Try>::from_error(move _8) -> bb7; // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15 - // ty::Const - // + ty: fn(<std::result::Result<u8, i32> as std::ops::Try>::Error) -> std::result::Result<u8, i32> {<std::result::Result<u8, i32> as std::ops::Try>::from_error} - // + val: Value(Scalar(<ZST>)) - // mir::Constant - // + span: $DIR/simplify-arm.rs:24:13: 24:15 - // + literal: Const { ty: fn(<std::result::Result<u8, i32> as std::ops::Try>::Error) -> std::result::Result<u8, i32> {<std::result::Result<u8, i32> as std::ops::Try>::from_error}, val: Value(Scalar(<ZST>)) } - } - - bb7: { - StorageDead(_8); // scope 3 at $DIR/simplify-arm.rs:24:14: 24:15 - StorageDead(_6); // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 - StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:24:15: 24:16 - StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:26:1: 26:2 - goto -> bb5; // scope 0 at $DIR/simplify-arm.rs:24:14: 24:15 - } } diff --git a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff.32bit b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff.32bit index 0bd13e009dd..9e840553eca 100644 --- a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff.32bit +++ b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff.32bit @@ -4,7 +4,7 @@ fn map(_1: std::option::Option<std::boxed::Box<()>>) -> std::option::Option<std::boxed::Box<()>> { debug x => _1; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:1:8: 1:9 let mut _0: std::option::Option<std::boxed::Box<()>>; // return place in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:1:31: 1:46 - let mut _2: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13 +- let mut _2: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13 - let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:14: 4:15 - let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:25: 4:26 - let mut _5: bool; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2 @@ -29,21 +29,8 @@ - // mir::Constant - // + span: $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13 - // + literal: Const { ty: bool, val: Value(Scalar(0x01)) } - _2 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13 - switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13 - } - - bb1: { +- _2 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13 _0 = move _1; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:20: 4:27 - goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:2:5: 5:6 - } - - bb2: { - discriminant(_0) = 0; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:17: 3:21 - goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:2:5: 5:6 - } - - bb3: { - _6 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2 return; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:2: 6:2 } diff --git a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff.64bit b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff.64bit index 0bd13e009dd..9e840553eca 100644 --- a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff.64bit +++ b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff.64bit @@ -4,7 +4,7 @@ fn map(_1: std::option::Option<std::boxed::Box<()>>) -> std::option::Option<std::boxed::Box<()>> { debug x => _1; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:1:8: 1:9 let mut _0: std::option::Option<std::boxed::Box<()>>; // return place in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:1:31: 1:46 - let mut _2: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13 +- let mut _2: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13 - let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:14: 4:15 - let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:25: 4:26 - let mut _5: bool; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2 @@ -29,21 +29,8 @@ - // mir::Constant - // + span: $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13 - // + literal: Const { ty: bool, val: Value(Scalar(0x01)) } - _2 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13 - switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13 - } - - bb1: { +- _2 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13 _0 = move _1; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:20: 4:27 - goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:2:5: 5:6 - } - - bb2: { - discriminant(_0) = 0; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:17: 3:21 - goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:2:5: 5:6 - } - - bb3: { - _6 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2 return; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:2: 6:2 } diff --git a/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs index bb2a4d03734..8cf8b7a4493 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs @@ -14,7 +14,7 @@ extern crate rustc_session; use rustc_driver::plugin::Registry; use rustc_lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass}; -use rustc_ast::ast; +use rustc_ast as ast; declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'"); declare_lint_pass!(Pass => [TEST_LINT]); diff --git a/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs index 8c517e2bb5d..08b8fb3cbae 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs @@ -12,7 +12,7 @@ extern crate rustc_session; use rustc_driver::plugin::Registry; use rustc_lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintId, LintPass}; -use rustc_ast::ast; +use rustc_ast as ast; declare_tool_lint!(pub clippy::TEST_LINT, Warn, "Warn about stuff"); declare_tool_lint!( /// Some docs diff --git a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs index f0e3ab308e9..8d4101b6526 100644 --- a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs +++ b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs @@ -33,7 +33,7 @@ use rustc_session::parse::ParseSess; use rustc_span::source_map::{Spanned, DUMMY_SP, FileName}; use rustc_span::source_map::FilePathMapping; use rustc_span::symbol::Ident; -use rustc_ast::ast::*; +use rustc_ast::*; use rustc_ast::mut_visit::{self, MutVisitor, visit_clobber}; use rustc_ast::ptr::P; diff --git a/src/test/ui/consts/min_const_fn/allow_raw_ptr_dereference_const_fn.rs b/src/test/ui/consts/min_const_fn/allow_raw_ptr_dereference_const_fn.rs new file mode 100644 index 00000000000..25dc457d144 --- /dev/null +++ b/src/test/ui/consts/min_const_fn/allow_raw_ptr_dereference_const_fn.rs @@ -0,0 +1,11 @@ +// check-pass +#![feature(const_raw_ptr_deref)] +#![feature(raw_ref_macros)] + +use std::ptr; + +const fn test_fn(x: *const i32) { + let x2 = unsafe { ptr::raw_const!(*x) }; +} + +fn main() {} diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs index 0b1ab1c34ff..6462d736ad1 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs +++ b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs @@ -1,4 +1,4 @@ -const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe { &*x } } //~ is unsafe +const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe { &*x } } //~^ dereferencing raw pointers in constant functions const unsafe fn bad_const_unsafe_deref_raw(x: *mut usize) -> usize { *x } diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.stderr index 97b0a778d2c..427ecff5c6d 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.stderr @@ -34,15 +34,7 @@ LL | Foo { x: () }.y = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information = help: add `#![feature(const_fn)]` to the crate attributes to enable -error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block - --> $DIR/min_const_fn_unsafe_bad.rs:1:77 - | -LL | const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe { &*x } } - | ^^^ dereference of raw pointer - | - = note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior - -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0133, E0658, E0723. -For more information about an error, try `rustc --explain E0133`. +Some errors have detailed explanations: E0658, E0723. +For more information about an error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/ptr_comparisons.rs b/src/test/ui/consts/ptr_comparisons.rs new file mode 100644 index 00000000000..be998c80038 --- /dev/null +++ b/src/test/ui/consts/ptr_comparisons.rs @@ -0,0 +1,78 @@ +// compile-flags: --crate-type=lib +// normalize-stderr-32bit: "offset 8" -> "offset $$TWO_WORDS" +// normalize-stderr-64bit: "offset 16" -> "offset $$TWO_WORDS" +// normalize-stderr-32bit: "size 4" -> "size $$WORD" +// normalize-stderr-64bit: "size 8" -> "size $$WORD" + +#![feature( + const_panic, + core_intrinsics, + const_raw_ptr_comparison, + const_ptr_offset, + const_raw_ptr_deref, + raw_ref_macros +)] + +const FOO: &usize = &42; + +macro_rules! check { + (eq, $a:expr, $b:expr) => { + pub const _: () = + assert!(std::intrinsics::ptr_guaranteed_eq($a as *const u8, $b as *const u8)); + }; + (ne, $a:expr, $b:expr) => { + pub const _: () = + assert!(std::intrinsics::ptr_guaranteed_ne($a as *const u8, $b as *const u8)); + }; + (!eq, $a:expr, $b:expr) => { + pub const _: () = + assert!(!std::intrinsics::ptr_guaranteed_eq($a as *const u8, $b as *const u8)); + }; + (!ne, $a:expr, $b:expr) => { + pub const _: () = + assert!(!std::intrinsics::ptr_guaranteed_ne($a as *const u8, $b as *const u8)); + }; +} + +check!(eq, 0, 0); +check!(ne, 0, 1); +check!(!eq, 0, 1); +check!(!ne, 0, 0); +check!(ne, FOO as *const _, 0); +check!(!eq, FOO as *const _, 0); +// We want pointers to be equal to themselves, but aren't checking this yet because +// there are some open questions (e.g. whether function pointers to the same function +// compare equal, they don't necessarily at runtime). +// The case tested here should work eventually, but does not work yet. +check!(!eq, FOO as *const _, FOO as *const _); +check!(ne, unsafe { (FOO as *const usize).offset(1) }, 0); +check!(!eq, unsafe { (FOO as *const usize).offset(1) }, 0); + +check!(ne, unsafe { (FOO as *const usize as *const u8).offset(3) }, 0); +check!(!eq, unsafe { (FOO as *const usize as *const u8).offset(3) }, 0); + +/////////////////////////////////////////////////////////////////////////////// +// If any of the below start compiling, make sure to add a `check` test for it. +// These invocations exist as canaries so we don't forget to check that the +// behaviour of `guaranteed_eq` and `guaranteed_ne` is still correct. +// All of these try to obtain an out of bounds pointer in some manner. If we +// can create out of bounds pointers, we can offset a pointer far enough that +// at runtime it would be zero and at compile-time it would not be zero. + +const _: *const usize = unsafe { (FOO as *const usize).offset(2) }; +//~^ NOTE + +const _: *const u8 = +//~^ NOTE + unsafe { std::ptr::raw_const!((*(FOO as *const usize as *const [u8; 1000]))[999]) }; +//~^ ERROR any use of this value will cause an error + +const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 }; +//~^ ERROR any use of this value will cause an error +//~| NOTE "pointer-to-integer cast" needs an rfc +//~| NOTE + +const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 }; +//~^ ERROR any use of this value will cause an error +//~| NOTE "pointer-to-integer cast" needs an rfc +//~| NOTE diff --git a/src/test/ui/consts/ptr_comparisons.stderr b/src/test/ui/consts/ptr_comparisons.stderr new file mode 100644 index 00000000000..493d9be8f71 --- /dev/null +++ b/src/test/ui/consts/ptr_comparisons.stderr @@ -0,0 +1,47 @@ +error: any use of this value will cause an error + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | +LL | unsafe { intrinsics::offset(self, count) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | inbounds test failed: pointer must be in-bounds at offset $TWO_WORDS, but is outside bounds of alloc2 which has size $WORD + | inside `std::ptr::const_ptr::<impl *const usize>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | inside `_` at $DIR/ptr_comparisons.rs:62:34 + | + ::: $DIR/ptr_comparisons.rs:62:1 + | +LL | const _: *const usize = unsafe { (FOO as *const usize).offset(2) }; + | ------------------------------------------------------------------- + | + = note: `#[deny(const_err)]` on by default + +error: any use of this value will cause an error + --> $DIR/ptr_comparisons.rs:67:14 + | +LL | / const _: *const u8 = +LL | | +LL | | unsafe { std::ptr::raw_const!((*(FOO as *const usize as *const [u8; 1000]))[999]) }; + | |______________^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^__- + | | + | memory access failed: pointer must be in-bounds at offset 1000, but is outside bounds of alloc2 which has size $WORD + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: any use of this value will cause an error + --> $DIR/ptr_comparisons.rs:70:27 + | +LL | const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 }; + | --------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | "pointer-to-integer cast" needs an rfc before being allowed inside constants + +error: any use of this value will cause an error + --> $DIR/ptr_comparisons.rs:75:27 + | +LL | const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 }; + | --------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | "pointer-to-integer cast" needs an rfc before being allowed inside constants + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/consts/ptr_is_null.rs b/src/test/ui/consts/ptr_is_null.rs new file mode 100644 index 00000000000..324f59443f7 --- /dev/null +++ b/src/test/ui/consts/ptr_is_null.rs @@ -0,0 +1,16 @@ +// compile-flags: --crate-type=lib +// check-pass + +#![feature(const_ptr_is_null, const_panic)] + +const FOO: &usize = &42; + +pub const _: () = assert!(!(FOO as *const usize).is_null()); + +pub const _: () = assert!(!(42 as *const usize).is_null()); + +pub const _: () = assert!((0 as *const usize).is_null()); + +pub const _: () = assert!(std::ptr::null::<usize>().is_null()); + +pub const _: () = assert!(!("foo" as *const str).is_null()); diff --git a/src/test/ui/hygiene/hir-res-hygiene.rs b/src/test/ui/hygiene/hir-res-hygiene.rs new file mode 100644 index 00000000000..c26cf5fdb5b --- /dev/null +++ b/src/test/ui/hygiene/hir-res-hygiene.rs @@ -0,0 +1,18 @@ +// check-pass +// edition:2018 +// aux-build:not-libstd.rs + +// Check that paths created in HIR are not affected by in scope names. + +extern crate not_libstd as std; + +async fn the_future() { + async {}.await; +} + +fn main() -> Result<(), ()> { + for i in 0..10 {} + for j in 0..=10 {} + Ok(())?; + Ok(()) +} diff --git a/src/test/ui/range/range-1.stderr b/src/test/ui/range/range-1.stderr index e179feba7a7..11cb72fa2b6 100644 --- a/src/test/ui/range/range-1.stderr +++ b/src/test/ui/range/range-1.stderr @@ -17,9 +17,13 @@ error[E0277]: the size for values of type `[{integer}]` cannot be known at compi | LL | let range = *arr..; | ^^^^^^ doesn't have a size known at compile-time + | + ::: $SRC_DIR/core/src/ops/range.rs:LL:COL + | +LL | pub struct RangeFrom<Idx> { + | --- required by this bound in `std::ops::RangeFrom` | = help: the trait `std::marker::Sized` is not implemented for `[{integer}]` - = note: required by `std::ops::RangeFrom` error: aborting due to 3 previous errors diff --git a/src/test/ui/suggestions/chain-method-call-mutation-in-place.rs b/src/test/ui/suggestions/chain-method-call-mutation-in-place.rs new file mode 100644 index 00000000000..cb92ab87a8f --- /dev/null +++ b/src/test/ui/suggestions/chain-method-call-mutation-in-place.rs @@ -0,0 +1,4 @@ +fn main() {} +fn foo(mut s: String) -> String { + s.push_str("asdf") //~ ERROR mismatched types +} diff --git a/src/test/ui/suggestions/chain-method-call-mutation-in-place.stderr b/src/test/ui/suggestions/chain-method-call-mutation-in-place.stderr new file mode 100644 index 00000000000..63e3bb78954 --- /dev/null +++ b/src/test/ui/suggestions/chain-method-call-mutation-in-place.stderr @@ -0,0 +1,20 @@ +error[E0308]: mismatched types + --> $DIR/chain-method-call-mutation-in-place.rs:3:5 + | +LL | fn foo(mut s: String) -> String { + | ------ expected `std::string::String` because of return type +LL | s.push_str("asdf") + | ^^^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found `()` + | +note: method `push_str` modifies its receiver in-place + --> $DIR/chain-method-call-mutation-in-place.rs:3:7 + | +LL | s.push_str("asdf") + | - ^^^^^^^^ this call modifies `s` in-place + | | + | you probably want to use this value after calling the method... + = note: ...instead of the `()` output of method `push_str` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/unboxed-closures/unboxed-closures-unique-type-id.rs b/src/test/ui/unboxed-closures/unboxed-closures-unique-type-id.rs index 9c6be50c5c7..4b7016def9d 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-unique-type-id.rs +++ b/src/test/ui/unboxed-closures/unboxed-closures-unique-type-id.rs @@ -4,7 +4,7 @@ // // error: internal compiler error: get_unique_type_id_of_type() - // unexpected type: closure, -// Closure(rustc_ast::ast::DefId{krate: 0, node: 66}, +// Closure(rustc_ast::DefId{krate: 0, node: 66}, // ReScope(63)) // // This is a regression test for issue #17021. diff --git a/src/tools/clippy/clippy_lints/src/attrs.rs b/src/tools/clippy/clippy_lints/src/attrs.rs index 376ac55f9c9..76ccf2e4bb9 100644 --- a/src/tools/clippy/clippy_lints/src/attrs.rs +++ b/src/tools/clippy/clippy_lints/src/attrs.rs @@ -5,7 +5,7 @@ use crate::utils::{ span_lint_and_sugg, span_lint_and_then, without_block_comments, }; use if_chain::if_chain; -use rustc_ast::ast::{AttrKind, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem}; +use rustc_ast::{AttrKind, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem}; use rustc_ast::util::lev_distance::find_best_match_for_name; use rustc_errors::Applicability; use rustc_hir::{ @@ -570,7 +570,7 @@ declare_lint_pass!(EarlyAttributes => [ ]); impl EarlyLintPass for EarlyAttributes { - fn check_item(&mut self, cx: &EarlyContext<'_>, item: &rustc_ast::ast::Item) { + fn check_item(&mut self, cx: &EarlyContext<'_>, item: &rustc_ast::Item) { check_empty_line_after_outer_attr(cx, item); } @@ -580,7 +580,7 @@ impl EarlyLintPass for EarlyAttributes { } } -fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::ast::Item) { +fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::Item) { for attr in &item.attrs { let attr_item = if let AttrKind::Normal(ref attr) = attr.kind { attr diff --git a/src/tools/clippy/clippy_lints/src/default_trait_access.rs b/src/tools/clippy/clippy_lints/src/default_trait_access.rs index 874e19d9e9f..067ea903bdd 100644 --- a/src/tools/clippy/clippy_lints/src/default_trait_access.rs +++ b/src/tools/clippy/clippy_lints/src/default_trait_access.rs @@ -68,7 +68,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultTraitAccess { ); } }, - QPath::TypeRelative(..) => {}, + QPath::TypeRelative(..) | QPath::LangItem(..) => {}, } } } diff --git a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs index a1f58e54ae3..90b1a529be7 100644 --- a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs +++ b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs @@ -89,7 +89,7 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::Index(ref array, ref index) = &expr.kind { let ty = cx.typeck_results().expr_ty(array); - if let Some(range) = higher::range(cx, index) { + if let Some(range) = higher::range(index) { // Ranged indexes, i.e., &x[n..m], &x[n..], &x[..n] and &x[..] if let ty::Array(_, s) = ty.kind { let size: u128 = if let Some(size) = s.try_eval_usize(cx.tcx, cx.param_env) { diff --git a/src/tools/clippy/clippy_lints/src/infinite_iter.rs b/src/tools/clippy/clippy_lints/src/infinite_iter.rs index e511d3ea330..129abd7d897 100644 --- a/src/tools/clippy/clippy_lints/src/infinite_iter.rs +++ b/src/tools/clippy/clippy_lints/src/infinite_iter.rs @@ -171,7 +171,7 @@ fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness { Finite } }, - ExprKind::Struct(..) => higher::range(cx, expr).map_or(false, |r| r.end.is_none()).into(), + ExprKind::Struct(..) => higher::range(expr).map_or(false, |r| r.end.is_none()).into(), _ => Finite, } } diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs index 00d0b8b4e5b..e5daa30f8ca 100644 --- a/src/tools/clippy/clippy_lints/src/len_zero.rs +++ b/src/tools/clippy/clippy_lints/src/len_zero.rs @@ -262,7 +262,7 @@ fn check_len( fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { /// Special case ranges until `range_is_empty` is stabilized. See issue 3807. fn should_skip_range(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - higher::range(cx, expr).map_or(false, |_| { + higher::range(expr).map_or(false, |_| { !cx.tcx .features() .declared_lib_features diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs index 6ad525d7620..aa100263640 100644 --- a/src/tools/clippy/clippy_lints/src/lib.rs +++ b/src/tools/clippy/clippy_lints/src/lib.rs @@ -339,7 +339,7 @@ pub fn register_pre_expansion_lints(store: &mut rustc_lint::LintStore) { } #[doc(hidden)] -pub fn read_conf(args: &[rustc_ast::ast::NestedMetaItem], sess: &Session) -> Conf { +pub fn read_conf(args: &[rustc_ast::NestedMetaItem], sess: &Session) -> Conf { use std::path::Path; match utils::conf::file_from_args(args) { Ok(file_name) => { diff --git a/src/tools/clippy/clippy_lints/src/loops.rs b/src/tools/clippy/clippy_lints/src/loops.rs index 8352a8a3d2c..8ffcd417d1d 100644 --- a/src/tools/clippy/clippy_lints/src/loops.rs +++ b/src/tools/clippy/clippy_lints/src/loops.rs @@ -1003,7 +1003,7 @@ fn detect_manual_memcpy<'tcx>( start: Some(start), end: Some(end), limits, - }) = higher::range(cx, arg) + }) = higher::range(arg) { // the var must be a single name if let PatKind::Binding(_, canonical_id, _, _) = pat.kind { @@ -1177,7 +1177,7 @@ fn check_for_loop_range<'tcx>( start: Some(start), ref end, limits, - }) = higher::range(cx, arg) + }) = higher::range(arg) { // the var must be a single name if let PatKind::Binding(_, canonical_id, ident, _) = pat.kind { @@ -1679,7 +1679,7 @@ fn check_for_mut_range_bound(cx: &LateContext<'_>, arg: &Expr<'_>, body: &Expr<' start: Some(start), end: Some(end), .. - }) = higher::range(cx, arg) + }) = higher::range(arg) { let mut_ids = vec![check_for_mutability(cx, start), check_for_mutability(cx, end)]; if mut_ids[0].is_some() || mut_ids[1].is_some() { diff --git a/src/tools/clippy/clippy_lints/src/match_on_vec_items.rs b/src/tools/clippy/clippy_lints/src/match_on_vec_items.rs index 4f8f2cb171d..faa20687ef6 100644 --- a/src/tools/clippy/clippy_lints/src/match_on_vec_items.rs +++ b/src/tools/clippy/clippy_lints/src/match_on_vec_items.rs @@ -1,7 +1,8 @@ -use crate::utils::{self, is_type_diagnostic_item, match_type, snippet, span_lint_and_sugg, walk_ptrs_ty}; +use crate::utils::{is_type_diagnostic_item, is_type_lang_item, snippet, span_lint_and_sugg}; +use crate::utils::walk_ptrs_ty; use if_chain::if_chain; use rustc_errors::Applicability; -use rustc_hir::{Expr, ExprKind, MatchSource}; +use rustc_hir::{Expr, ExprKind, LangItem, MatchSource}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -96,5 +97,5 @@ fn is_vector(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { fn is_full_range(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { let ty = cx.typeck_results().expr_ty(expr); let ty = walk_ptrs_ty(ty); - match_type(cx, ty, &utils::paths::RANGE_FULL) + is_type_lang_item(cx, ty, LangItem::RangeFull) } diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index 570ae66d595..2265a188855 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -2271,7 +2271,7 @@ fn lint_iter_next<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, iter_ if_chain! { if let hir::ExprKind::Index(ref caller_var, ref index_expr) = &caller_expr.kind; if let Some(higher::Range { start: Some(start_expr), end: None, limits: ast::RangeLimits::HalfOpen }) - = higher::range(cx, index_expr); + = higher::range(index_expr); if let hir::ExprKind::Lit(ref start_lit) = &start_expr.kind; if let ast::LitKind::Int(start_idx, _) = start_lit.node; then { diff --git a/src/tools/clippy/clippy_lints/src/misc.rs b/src/tools/clippy/clippy_lints/src/misc.rs index 26a1c32b6b3..482a563572d 100644 --- a/src/tools/clippy/clippy_lints/src/misc.rs +++ b/src/tools/clippy/clippy_lints/src/misc.rs @@ -433,6 +433,7 @@ impl<'tcx> LateLintPass<'tcx> for MiscLints { return; } let binding = match expr.kind { + ExprKind::Path(hir::QPath::LangItem(..)) => None, ExprKind::Path(ref qpath) => { let binding = last_path_segment(qpath).ident.as_str(); if binding.starts_with('_') && diff --git a/src/tools/clippy/clippy_lints/src/ranges.rs b/src/tools/clippy/clippy_lints/src/ranges.rs index f88075798ca..7a75fc125d0 100644 --- a/src/tools/clippy/clippy_lints/src/ranges.rs +++ b/src/tools/clippy/clippy_lints/src/ranges.rs @@ -147,7 +147,7 @@ impl<'tcx> LateLintPass<'tcx> for Ranges { if let ExprKind::MethodCall(ref iter_path, _, ref iter_args , _) = *iter; if iter_path.ident.name == sym!(iter); // range expression in `.zip()` call: `0..x.len()` - if let Some(higher::Range { start: Some(start), end: Some(end), .. }) = higher::range(cx, zip_arg); + if let Some(higher::Range { start: Some(start), end: Some(end), .. }) = higher::range(zip_arg); if is_integer_const(cx, start, 0); // `.len()` call if let ExprKind::MethodCall(ref len_path, _, ref len_args, _) = end.kind; @@ -180,7 +180,7 @@ fn check_exclusive_range_plus_one(cx: &LateContext<'_>, expr: &Expr<'_>) { start, end: Some(end), limits: RangeLimits::HalfOpen - }) = higher::range(cx, expr); + }) = higher::range(expr); if let Some(y) = y_plus_one(cx, end); then { let span = if expr.span.from_expansion() { @@ -225,7 +225,7 @@ fn check_exclusive_range_plus_one(cx: &LateContext<'_>, expr: &Expr<'_>) { // inclusive range minus one: `x..=(y-1)` fn check_inclusive_range_minus_one(cx: &LateContext<'_>, expr: &Expr<'_>) { if_chain! { - if let Some(higher::Range { start, end: Some(end), limits: RangeLimits::Closed }) = higher::range(cx, expr); + if let Some(higher::Range { start, end: Some(end), limits: RangeLimits::Closed }) = higher::range(expr); if let Some(y) = y_minus_one(cx, end); then { span_lint_and_then( @@ -279,7 +279,7 @@ fn check_reversed_empty_range(cx: &LateContext<'_>, expr: &Expr<'_>) { } if_chain! { - if let Some(higher::Range { start: Some(start), end: Some(end), limits }) = higher::range(cx, expr); + if let Some(higher::Range { start: Some(start), end: Some(end), limits }) = higher::range(expr); let ty = cx.typeck_results().expr_ty(start); if let ty::Int(_) | ty::Uint(_) = ty.kind; if let Some((start_idx, _)) = constant(cx, cx.typeck_results(), start); diff --git a/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs b/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs index 2e853e8301d..58bfd0bc553 100644 --- a/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs +++ b/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs @@ -1,6 +1,6 @@ use crate::utils::{in_macro, span_lint_and_sugg}; use if_chain::if_chain; -use rustc_ast::ast::{Item, ItemKind, UseTreeKind}; +use rustc_ast::{Item, ItemKind, UseTreeKind}; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs index bada6fa7c52..7a659bf779c 100644 --- a/src/tools/clippy/clippy_lints/src/strings.rs +++ b/src/tools/clippy/clippy_lints/src/strings.rs @@ -161,7 +161,7 @@ declare_lint_pass!(StringLitAsBytes => [STRING_LIT_AS_BYTES]); impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes { fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { use crate::utils::{snippet, snippet_with_applicability}; - use rustc_ast::ast::LitKind; + use rustc_ast::LitKind; if_chain! { if let ExprKind::MethodCall(path, _, args, _) = &e.kind; diff --git a/src/tools/clippy/clippy_lints/src/transmute.rs b/src/tools/clippy/clippy_lints/src/transmute.rs index 7b5e92eb5ee..28fd55f6ff0 100644 --- a/src/tools/clippy/clippy_lints/src/transmute.rs +++ b/src/tools/clippy/clippy_lints/src/transmute.rs @@ -3,7 +3,7 @@ use crate::utils::{ span_lint_and_then, sugg, }; use if_chain::if_chain; -use rustc_ast::ast; +use rustc_ast as ast; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, GenericArg, Mutability, QPath, TyKind, UnOp}; use rustc_lint::{LateContext, LateLintPass}; diff --git a/src/tools/clippy/clippy_lints/src/transmuting_null.rs b/src/tools/clippy/clippy_lints/src/transmuting_null.rs index fbf7f0b2517..d60306336c6 100644 --- a/src/tools/clippy/clippy_lints/src/transmuting_null.rs +++ b/src/tools/clippy/clippy_lints/src/transmuting_null.rs @@ -1,7 +1,7 @@ use crate::consts::{constant_context, Constant}; use crate::utils::{match_qpath, paths, span_lint}; use if_chain::if_chain; -use rustc_ast::ast::LitKind; +use rustc_ast::LitKind; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; diff --git a/src/tools/clippy/clippy_lints/src/try_err.rs b/src/tools/clippy/clippy_lints/src/try_err.rs index 3bd73d9f21a..a74104e9282 100644 --- a/src/tools/clippy/clippy_lints/src/try_err.rs +++ b/src/tools/clippy/clippy_lints/src/try_err.rs @@ -1,10 +1,10 @@ use crate::utils::{ - is_type_diagnostic_item, match_def_path, match_qpath, paths, snippet, snippet_with_macro_callsite, - span_lint_and_sugg, + is_type_diagnostic_item, match_def_path, match_qpath, paths, snippet, + snippet_with_macro_callsite, span_lint_and_sugg, }; use if_chain::if_chain; use rustc_errors::Applicability; -use rustc_hir::{Expr, ExprKind, MatchSource}; +use rustc_hir::{Expr, ExprKind, QPath, LangItem, MatchSource}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::{self, Ty}; @@ -62,7 +62,7 @@ impl<'tcx> LateLintPass<'tcx> for TryErr { if let ExprKind::Match(ref match_arg, _, MatchSource::TryDesugar) = expr.kind; if let ExprKind::Call(ref match_fun, ref try_args) = match_arg.kind; if let ExprKind::Path(ref match_fun_path) = match_fun.kind; - if match_qpath(match_fun_path, &paths::TRY_INTO_RESULT); + if matches!(match_fun_path, QPath::LangItem(LangItem::TryIntoResult, _)); if let Some(ref try_arg) = try_args.get(0); if let ExprKind::Call(ref err_fun, ref err_args) = try_arg.kind; if let Some(ref err_arg) = err_args.get(0); diff --git a/src/tools/clippy/clippy_lints/src/types.rs b/src/tools/clippy/clippy_lints/src/types.rs index c3dea447521..0fd70550fa0 100644 --- a/src/tools/clippy/clippy_lints/src/types.rs +++ b/src/tools/clippy/clippy_lints/src/types.rs @@ -5,7 +5,7 @@ use std::cmp::Ordering; use std::collections::BTreeMap; use if_chain::if_chain; -use rustc_ast::ast::{FloatTy, IntTy, LitFloatType, LitIntType, LitKind, UintTy}; +use rustc_ast::{FloatTy, IntTy, LitFloatType, LitIntType, LitKind, UintTy}; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::intravisit::{walk_body, walk_expr, walk_ty, FnKind, NestedVisitorMap, Visitor}; @@ -475,6 +475,7 @@ impl Types { } } }, + QPath::LangItem(..) => {}, } }, TyKind::Rptr(ref lt, ref mut_ty) => self.check_ty_rptr(cx, hir_ty, is_local, lt, mut_ty), diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs index 502bf0c4279..b7e2eba0a81 100644 --- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs +++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs @@ -2,7 +2,7 @@ use crate::utils::ast_utils::{eq_field_pat, eq_id, eq_pat, eq_path}; use crate::utils::{over, span_lint_and_then}; -use rustc_ast::ast::{self, Pat, PatKind, PatKind::*, DUMMY_NODE_ID}; +use rustc_ast::{self as ast, Pat, PatKind, PatKind::*, DUMMY_NODE_ID}; use rustc_ast::mut_visit::*; use rustc_ast::ptr::P; use rustc_ast_pretty::pprust; diff --git a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs index 1580f657d77..43166d26787 100644 --- a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs +++ b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs @@ -1,4 +1,4 @@ -use crate::utils::{is_try, match_qpath, match_trait_method, paths, span_lint}; +use crate::utils::{is_try, match_trait_method, paths, span_lint}; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -42,10 +42,11 @@ impl<'tcx> LateLintPass<'tcx> for UnusedIoAmount { match expr.kind { hir::ExprKind::Match(ref res, _, _) if is_try(expr).is_some() => { if let hir::ExprKind::Call(ref func, ref args) = res.kind { - if let hir::ExprKind::Path(ref path) = func.kind { - if match_qpath(path, &paths::TRY_INTO_RESULT) && args.len() == 1 { - check_method_call(cx, &args[0], expr); - } + if matches!( + func.kind, + hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::TryIntoResult, _)) + ) { + check_method_call(cx, &args[0], expr); } } else { check_method_call(cx, res, expr); diff --git a/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs b/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs index ad02bc5fd8e..c32c80dcd3c 100644 --- a/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs +++ b/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs @@ -5,7 +5,7 @@ #![allow(clippy::similar_names, clippy::wildcard_imports, clippy::enum_glob_use)] use crate::utils::{both, over}; -use rustc_ast::ast::{self, *}; +use rustc_ast::{self as ast, *}; use rustc_ast::ptr::P; use rustc_span::symbol::Ident; use std::mem; diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 128fa87a162..9b7a268c628 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -175,9 +175,19 @@ impl PrintVisitor { } fn print_qpath(&mut self, path: &QPath<'_>) { - print!(" if match_qpath({}, &[", self.current); - print_path(path, &mut true); - println!("]);"); + match *path { + QPath::LangItem(lang_item, _) => { + println!( + " if matches!({}, QPath::LangItem(LangItem::{:?}, _));", + self.current, lang_item, + ); + }, + _ => { + print!(" if match_qpath({}, &[", self.current); + print_path(path, &mut true); + println!("]);"); + }, + } } } @@ -760,5 +770,6 @@ fn print_path(path: &QPath<'_>, first: &mut bool) { }, ref other => print!("/* unimplemented: {:?}*/", other), }, + QPath::LangItem(..) => panic!("print_path: called for lang item qpath"), } } diff --git a/src/tools/clippy/clippy_lints/src/utils/higher.rs b/src/tools/clippy/clippy_lints/src/utils/higher.rs index f81a132c7e7..ba15456014d 100644 --- a/src/tools/clippy/clippy_lints/src/utils/higher.rs +++ b/src/tools/clippy/clippy_lints/src/utils/higher.rs @@ -3,12 +3,11 @@ #![deny(clippy::missing_docs_in_private_items)] -use crate::utils::{is_expn_of, match_def_path, match_qpath, paths}; +use crate::utils::{is_expn_of, match_def_path, paths}; use if_chain::if_chain; use rustc_ast::ast; use rustc_hir as hir; use rustc_lint::LateContext; -use rustc_middle::ty; /// Converts a hir binary operator to the corresponding `ast` type. #[must_use] @@ -47,7 +46,7 @@ pub struct Range<'a> { } /// Higher a `hir` range to something similar to `ast::ExprKind::Range`. -pub fn range<'a, 'tcx>(cx: &LateContext<'tcx>, expr: &'a hir::Expr<'_>) -> Option<Range<'a>> { +pub fn range<'a>(expr: &'a hir::Expr<'_>) -> Option<Range<'a>> { /// Finds the field named `name` in the field. Always return `Some` for /// convenience. fn get_field<'c>(name: &str, fields: &'c [hir::Field<'_>]) -> Option<&'c hir::Expr<'c>> { @@ -56,94 +55,43 @@ pub fn range<'a, 'tcx>(cx: &LateContext<'tcx>, expr: &'a hir::Expr<'_>) -> Optio Some(expr) } - let def_path = match cx.typeck_results().expr_ty(expr).kind { - ty::Adt(def, _) => cx.tcx.def_path(def.did), - _ => return None, - }; - - // sanity checks for std::ops::RangeXXXX - if def_path.data.len() != 3 { - return None; - } - if def_path.data.get(0)?.data.as_symbol() != sym!(ops) { - return None; - } - if def_path.data.get(1)?.data.as_symbol() != sym!(range) { - return None; - } - let type_name = def_path.data.get(2)?.data.as_symbol(); - let range_types = [ - "RangeFrom", - "RangeFull", - "RangeInclusive", - "Range", - "RangeTo", - "RangeToInclusive", - ]; - if !range_types.contains(&&*type_name.as_str()) { - return None; - } - - // The range syntax is expanded to literal paths starting with `core` or `std` - // depending on - // `#[no_std]`. Testing both instead of resolving the paths. - match expr.kind { - hir::ExprKind::Path(ref path) => { - if match_qpath(path, &paths::RANGE_FULL_STD) || match_qpath(path, &paths::RANGE_FULL) { - Some(Range { + hir::ExprKind::Call(ref path, ref args) if matches!( + path.kind, + hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, _)) + ) => Some(Range { + start: Some(&args[0]), + end: Some(&args[1]), + limits: ast::RangeLimits::Closed, + }), + hir::ExprKind::Struct(ref path, ref fields, None) => { + match path { + hir::QPath::LangItem(hir::LangItem::RangeFull, _) => Some(Range { start: None, end: None, limits: ast::RangeLimits::HalfOpen, - }) - } else { - None - } - }, - hir::ExprKind::Call(ref path, ref args) => { - if let hir::ExprKind::Path(ref path) = path.kind { - if match_qpath(path, &paths::RANGE_INCLUSIVE_STD_NEW) || match_qpath(path, &paths::RANGE_INCLUSIVE_NEW) - { - Some(Range { - start: Some(&args[0]), - end: Some(&args[1]), - limits: ast::RangeLimits::Closed, - }) - } else { - None - } - } else { - None - } - }, - hir::ExprKind::Struct(ref path, ref fields, None) => { - if match_qpath(path, &paths::RANGE_FROM_STD) || match_qpath(path, &paths::RANGE_FROM) { - Some(Range { + }), + hir::QPath::LangItem(hir::LangItem::RangeFrom, _) => Some(Range { start: Some(get_field("start", fields)?), end: None, limits: ast::RangeLimits::HalfOpen, - }) - } else if match_qpath(path, &paths::RANGE_STD) || match_qpath(path, &paths::RANGE) { - Some(Range { + }), + hir::QPath::LangItem(hir::LangItem::Range, _) => Some(Range { start: Some(get_field("start", fields)?), end: Some(get_field("end", fields)?), limits: ast::RangeLimits::HalfOpen, - }) - } else if match_qpath(path, &paths::RANGE_TO_INCLUSIVE_STD) || match_qpath(path, &paths::RANGE_TO_INCLUSIVE) - { - Some(Range { + }), + hir::QPath::LangItem(hir::LangItem::RangeToInclusive, _) => Some(Range { start: None, end: Some(get_field("end", fields)?), limits: ast::RangeLimits::Closed, - }) - } else if match_qpath(path, &paths::RANGE_TO_STD) || match_qpath(path, &paths::RANGE_TO) { - Some(Range { + }), + hir::QPath::LangItem(hir::LangItem::RangeTo, _) => Some(Range { start: None, end: Some(get_field("end", fields)?), limits: ast::RangeLimits::HalfOpen, - }) - } else { - None + }), + _ => None, } }, _ => None, diff --git a/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs b/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs index 28fb6ed12a0..2eefd4a38a6 100644 --- a/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs +++ b/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs @@ -3,9 +3,9 @@ use crate::utils::differing_macro_contexts; use rustc_ast::ast::InlineAsmTemplatePiece; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_hir::{ - BinOpKind, Block, BlockCheckMode, BodyId, BorrowKind, CaptureBy, Expr, ExprKind, Field, FnRetTy, GenericArg, - GenericArgs, Guard, InlineAsmOperand, Lifetime, LifetimeName, ParamName, Pat, PatKind, Path, PathSegment, QPath, - Stmt, StmtKind, Ty, TyKind, TypeBinding, + BinOpKind, Block, BlockCheckMode, BodyId, BorrowKind, CaptureBy, Expr, ExprKind, Field, FieldPat, + FnRetTy, GenericArg, GenericArgs, Guard, InlineAsmOperand, Lifetime, LifetimeName, ParamName, + Pat, PatKind, Path, PathSegment, QPath, Stmt, StmtKind, Ty, TyKind, TypeBinding, }; use rustc_lint::LateContext; use rustc_middle::ich::StableHashingContextProvider; @@ -185,10 +185,20 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> { left.name == right.name } + pub fn eq_fieldpat(&mut self, left: &FieldPat<'_>, right: &FieldPat<'_>) -> bool { + match (&left, &right) { + (FieldPat { ident: li, pat: lp, .. }, FieldPat { ident: ri, pat: rp, .. }) => + li.name.as_str() == ri.name.as_str() && self.eq_pat(lp, rp), + } + } + /// Checks whether two patterns are the same. pub fn eq_pat(&mut self, left: &Pat<'_>, right: &Pat<'_>) -> bool { match (&left.kind, &right.kind) { (&PatKind::Box(ref l), &PatKind::Box(ref r)) => self.eq_pat(l, r), + (&PatKind::Struct(ref lp, ref la, ..), &PatKind::Struct(ref rp, ref ra, ..)) => { + self.eq_qpath(lp, rp) && over(la, ra, |l, r| self.eq_fieldpat(l, r)) + }, (&PatKind::TupleStruct(ref lp, ref la, ls), &PatKind::TupleStruct(ref rp, ref ra, rs)) => { self.eq_qpath(lp, rp) && over(la, ra, |l, r| self.eq_pat(l, r)) && ls == rs }, @@ -223,6 +233,8 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> { (&QPath::TypeRelative(ref lty, ref lseg), &QPath::TypeRelative(ref rty, ref rseg)) => { self.eq_ty(lty, rty) && self.eq_path_segment(lseg, rseg) }, + (&QPath::LangItem(llang_item, _), &QPath::LangItem(rlang_item, _)) => + llang_item == rlang_item, _ => false, } } @@ -601,6 +613,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { QPath::TypeRelative(_, ref path) => { self.hash_name(path.ident.name); }, + QPath::LangItem(lang_item, ..) => { + lang_item.hash_stable(&mut self.cx.tcx.get_stable_hashing_context(), &mut self.s); + } } // self.maybe_typeck_results.unwrap().qpath_res(p, id).hash(&mut self.s); } @@ -710,6 +725,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_ty(ty); segment.ident.name.hash(&mut self.s); }, + QPath::LangItem(lang_item, ..) => { + lang_item.hash(&mut self.s); + } }, TyKind::OpaqueDef(_, arg_list) => { self.hash_generic_args(arg_list); diff --git a/src/tools/clippy/clippy_lints/src/utils/inspector.rs b/src/tools/clippy/clippy_lints/src/utils/inspector.rs index d8fa1fa278e..4701a3f26e6 100644 --- a/src/tools/clippy/clippy_lints/src/utils/inspector.rs +++ b/src/tools/clippy/clippy_lints/src/utils/inspector.rs @@ -266,6 +266,9 @@ fn print_expr(cx: &LateContext<'_>, expr: &hir::Expr<'_>, indent: usize) { println!("{}Relative Path, {:?}", ind, ty); println!("{}seg: {:?}", ind, seg); }, + hir::ExprKind::Path(hir::QPath::LangItem(lang_item, ..)) => { + println!("{}Lang Item Path, {:?}", ind, lang_item.name()); + }, hir::ExprKind::AddrOf(kind, ref muta, ref e) => { println!("{}AddrOf", ind); println!("kind: {:?}", kind); @@ -488,6 +491,9 @@ fn print_pat(cx: &LateContext<'_>, pat: &hir::Pat<'_>, indent: usize) { println!("{}Relative Path, {:?}", ind, ty); println!("{}seg: {:?}", ind, seg); }, + hir::PatKind::Path(hir::QPath::LangItem(lang_item, ..)) => { + println!("{}Lang Item Path, {:?}", ind, lang_item.name()); + }, hir::PatKind::Tuple(pats, opt_dots_position) => { println!("{}Tuple", ind); if let Some(dot_position) = opt_dots_position { diff --git a/src/tools/clippy/clippy_lints/src/utils/mod.rs b/src/tools/clippy/clippy_lints/src/utils/mod.rs index 223628cc610..a56b8203513 100644 --- a/src/tools/clippy/clippy_lints/src/utils/mod.rs +++ b/src/tools/clippy/clippy_lints/src/utils/mod.rs @@ -142,6 +142,14 @@ pub fn is_type_diagnostic_item(cx: &LateContext<'_>, ty: Ty<'_>, diag_item: Symb } } +/// Checks if the type is equal to a lang item +pub fn is_type_lang_item(cx: &LateContext<'_>, ty: Ty<'_>, lang_item: hir::LangItem) -> bool { + match ty.kind { + ty::Adt(adt, _) => cx.tcx.lang_items().require(lang_item).unwrap() == adt.did, + _ => false, + } +} + /// Checks if the method call given in `expr` belongs to the given trait. pub fn match_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, path: &[&str]) -> bool { let def_id = cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap(); @@ -163,6 +171,7 @@ pub fn last_path_segment<'tcx>(path: &QPath<'tcx>) -> &'tcx PathSegment<'tcx> { match *path { QPath::Resolved(_, ref path) => path.segments.last().expect("A path must have at least one segment"), QPath::TypeRelative(_, ref seg) => seg, + QPath::LangItem(..) => panic!("last_path_segment: lang item has no path segments"), } } @@ -170,6 +179,7 @@ pub fn single_segment_path<'tcx>(path: &QPath<'tcx>) -> Option<&'tcx PathSegment match *path { QPath::Resolved(_, ref path) => path.segments.get(0), QPath::TypeRelative(_, ref seg) => Some(seg), + QPath::LangItem(..) => None, } } @@ -196,6 +206,7 @@ pub fn match_qpath(path: &QPath<'_>, segments: &[&str]) -> bool { }, _ => false, }, + QPath::LangItem(..) => false, } } @@ -277,7 +288,7 @@ pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Option<def::Res> { pub fn qpath_res(cx: &LateContext<'_>, qpath: &hir::QPath<'_>, id: hir::HirId) -> Res { match qpath { hir::QPath::Resolved(_, path) => path.res, - hir::QPath::TypeRelative(..) => { + hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => { if cx.tcx.has_typeck_results(id.owner.to_def_id()) { cx.tcx.typeck(id.owner.to_def_id().expect_local()).qpath_res(qpath, id) } else { diff --git a/src/tools/clippy/clippy_lints/src/utils/paths.rs b/src/tools/clippy/clippy_lints/src/utils/paths.rs index 923b319d777..9c28d63d414 100644 --- a/src/tools/clippy/clippy_lints/src/utils/paths.rs +++ b/src/tools/clippy/clippy_lints/src/utils/paths.rs @@ -84,19 +84,7 @@ pub const POLL: [&str; 4] = ["core", "task", "poll", "Poll"]; pub const PTR_EQ: [&str; 3] = ["core", "ptr", "eq"]; pub const PTR_NULL: [&str; 2] = ["ptr", "null"]; pub const PTR_NULL_MUT: [&str; 2] = ["ptr", "null_mut"]; -pub const RANGE: [&str; 3] = ["core", "ops", "Range"]; pub const RANGE_ARGUMENT_TRAIT: [&str; 3] = ["core", "ops", "RangeBounds"]; -pub const RANGE_FROM: [&str; 3] = ["core", "ops", "RangeFrom"]; -pub const RANGE_FROM_STD: [&str; 3] = ["std", "ops", "RangeFrom"]; -pub const RANGE_FULL: [&str; 4] = ["core", "ops", "range", "RangeFull"]; -pub const RANGE_FULL_STD: [&str; 3] = ["std", "ops", "RangeFull"]; -pub const RANGE_INCLUSIVE_NEW: [&str; 4] = ["core", "ops", "RangeInclusive", "new"]; -pub const RANGE_INCLUSIVE_STD_NEW: [&str; 4] = ["std", "ops", "RangeInclusive", "new"]; -pub const RANGE_STD: [&str; 3] = ["std", "ops", "Range"]; -pub const RANGE_TO: [&str; 3] = ["core", "ops", "RangeTo"]; -pub const RANGE_TO_INCLUSIVE: [&str; 3] = ["core", "ops", "RangeToInclusive"]; -pub const RANGE_TO_INCLUSIVE_STD: [&str; 3] = ["std", "ops", "RangeToInclusive"]; -pub const RANGE_TO_STD: [&str; 3] = ["std", "ops", "RangeTo"]; pub const RC: [&str; 3] = ["alloc", "rc", "Rc"]; pub const RC_PTR_EQ: [&str; 4] = ["alloc", "rc", "Rc", "ptr_eq"]; pub const RECEIVER: [&str; 4] = ["std", "sync", "mpsc", "Receiver"]; @@ -130,7 +118,6 @@ pub const TO_STRING: [&str; 3] = ["alloc", "string", "ToString"]; pub const TO_STRING_METHOD: [&str; 4] = ["alloc", "string", "ToString", "to_string"]; pub const TRANSMUTE: [&str; 4] = ["core", "intrinsics", "", "transmute"]; pub const TRY_FROM: [&str; 4] = ["core", "convert", "TryFrom", "try_from"]; -pub const TRY_INTO_RESULT: [&str; 4] = ["std", "ops", "Try", "into_result"]; pub const TRY_INTO_TRAIT: [&str; 3] = ["core", "convert", "TryInto"]; pub const VEC: [&str; 3] = ["alloc", "vec", "Vec"]; pub const VEC_AS_MUT_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_mut_slice"]; diff --git a/src/tools/clippy/clippy_lints/src/utils/sugg.rs b/src/tools/clippy/clippy_lints/src/utils/sugg.rs index 0ac7714fbeb..2955f8d8e59 100644 --- a/src/tools/clippy/clippy_lints/src/utils/sugg.rs +++ b/src/tools/clippy/clippy_lints/src/utils/sugg.rs @@ -42,7 +42,7 @@ impl<'a> Sugg<'a> { pub fn hir_opt(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Self> { snippet_opt(cx, expr.span).map(|snippet| { let snippet = Cow::Owned(snippet); - Self::hir_from_snippet(cx, expr, snippet) + Self::hir_from_snippet(expr, snippet) }) } @@ -80,13 +80,13 @@ impl<'a> Sugg<'a> { pub fn hir_with_macro_callsite(cx: &LateContext<'_>, expr: &hir::Expr<'_>, default: &'a str) -> Self { let snippet = snippet_with_macro_callsite(cx, expr.span, default); - Self::hir_from_snippet(cx, expr, snippet) + Self::hir_from_snippet(expr, snippet) } /// Generate a suggestion for an expression with the given snippet. This is used by the `hir_*` /// function variants of `Sugg`, since these use different snippet functions. - fn hir_from_snippet(cx: &LateContext<'_>, expr: &hir::Expr<'_>, snippet: Cow<'a, str>) -> Self { - if let Some(range) = higher::range(cx, expr) { + fn hir_from_snippet(expr: &hir::Expr<'_>, snippet: Cow<'a, str>) -> Self { + if let Some(range) = higher::range(expr) { let op = match range.limits { ast::RangeLimits::HalfOpen => AssocOp::DotDot, ast::RangeLimits::Closed => AssocOp::DotDotEq, diff --git a/src/tools/clippy/clippy_lints/src/vec_resize_to_zero.rs b/src/tools/clippy/clippy_lints/src/vec_resize_to_zero.rs index 58e7c354b27..d2494b321ef 100644 --- a/src/tools/clippy/clippy_lints/src/vec_resize_to_zero.rs +++ b/src/tools/clippy/clippy_lints/src/vec_resize_to_zero.rs @@ -7,7 +7,7 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Spanned; use crate::utils::{match_def_path, paths}; -use rustc_ast::ast::LitKind; +use rustc_ast::LitKind; use rustc_hir as hir; declare_clippy_lint! { diff --git a/src/tools/clippy/tests/ui/author/for_loop.stdout b/src/tools/clippy/tests/ui/author/for_loop.stdout index 81ede955347..3bf7607c62f 100644 --- a/src/tools/clippy/tests/ui/author/for_loop.stdout +++ b/src/tools/clippy/tests/ui/author/for_loop.stdout @@ -3,10 +3,10 @@ if_chain! { if let ExprKind::Match(ref expr1, ref arms, MatchSource::ForLoopDesugar) = expr.kind; if let ExprKind::Call(ref func, ref args) = expr1.kind; if let ExprKind::Path(ref path) = func.kind; - if match_qpath(path, &["{{root}}", "std", "iter", "IntoIterator", "into_iter"]); + if matches!(path, QPath::LangItem(LangItem::IntoIterIntoIter, _)); if args.len() == 1; if let ExprKind::Struct(ref path1, ref fields, None) = args[0].kind; - if match_qpath(path1, &["{{root}}", "std", "ops", "Range"]); + if matches!(path1, QPath::LangItem(LangItem::Range, _)); if fields.len() == 2; // unimplemented: field checks if arms.len() == 1; @@ -20,7 +20,7 @@ if_chain! { if let ExprKind::Match(ref expr2, ref arms1, MatchSource::ForLoopDesugar) = e.kind; if let ExprKind::Call(ref func1, ref args1) = expr2.kind; if let ExprKind::Path(ref path2) = func1.kind; - if match_qpath(path2, &["{{root}}", "std", "iter", "Iterator", "next"]); + if matches!(path2, QPath::LangItem(LangItem::IteratorNext, _)); if args1.len() == 1; if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, ref inner) = args1[0].kind; if let ExprKind::Path(ref path3) = inner.kind; @@ -31,13 +31,15 @@ if_chain! { if match_qpath(path4, &["__next"]); if let ExprKind::Path(ref path5) = value.kind; if match_qpath(path5, &["val"]); - if let PatKind::TupleStruct(ref path6, ref fields1, None) = arms1[0].pat.kind; - if match_qpath(path6, &["{{root}}", "std", "option", "Option", "Some"]); + if let PatKind::Struct(ref path6, ref fields1, false) = arms1[0].pat.kind; + if matches!(path6, QPath::LangItem(LangItem::OptionSome, _)); if fields1.len() == 1; // unimplemented: field checks if let ExprKind::Break(ref destination, None) = arms1[1].body.kind; - if let PatKind::Path(ref path7) = arms1[1].pat.kind; - if match_qpath(path7, &["{{root}}", "std", "option", "Option", "None"]); + if let PatKind::Struct(ref path7, ref fields2, false) = arms1[1].pat.kind; + if matches!(path7, QPath::LangItem(LangItem::OptionNone, _)); + if fields2.len() == 0; + // unimplemented: field checks if let StmtKind::Local(ref local1) = body.stmts[2].kind; if let Some(ref init) = local1.init; if let ExprKind::Path(ref path8) = init.kind; |
