From 017a092f45e53c9dc999b5ef1e4e0762dfd34979 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Tue, 29 Mar 2022 12:37:20 +0100 Subject: [PATCH 01/15] Disable #[thread_local] support on i686-pc-windows-msvc --- compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs index 174294895bf7a..5b30dc1d3dab6 100644 --- a/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs @@ -19,6 +19,8 @@ pub fn target() -> Target { .entry(LinkerFlavor::Lld(LldFlavor::Link)) .or_default() .extend(pre_link_args_msvc); + // Workaround for #95429 + base.has_thread_local = false; Target { llvm_target: "i686-pc-windows-msvc".to_string(), From 5d30180634080dd761db77afc748dfd58e192a1d Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 26 Mar 2022 19:20:36 -0700 Subject: [PATCH 02/15] Handle rustc_const_stable attribute in library feature collector --- compiler/rustc_passes/src/lib_features.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_passes/src/lib_features.rs b/compiler/rustc_passes/src/lib_features.rs index 00445690f8f02..c414d7c031c04 100644 --- a/compiler/rustc_passes/src/lib_features.rs +++ b/compiler/rustc_passes/src/lib_features.rs @@ -29,10 +29,11 @@ impl<'tcx> LibFeatureCollector<'tcx> { } fn extract(&self, attr: &Attribute) -> Option<(Symbol, Option, Span)> { - let stab_attrs = [sym::stable, sym::unstable, sym::rustc_const_unstable]; + let stab_attrs = + [sym::stable, sym::unstable, sym::rustc_const_stable, sym::rustc_const_unstable]; - // Find a stability attribute (i.e., `#[stable (..)]`, `#[unstable (..)]`, - // `#[rustc_const_unstable (..)]`). + // Find a stability attribute: one of #[stable(…)], #[unstable(…)], + // #[rustc_const_stable(…)], or #[rustc_const_unstable(…)]. if let Some(stab_attr) = stab_attrs.iter().find(|stab_attr| attr.has_name(**stab_attr)) { let meta_kind = attr.meta_kind(); if let Some(MetaItemKind::List(ref metas)) = meta_kind { @@ -52,7 +53,9 @@ impl<'tcx> LibFeatureCollector<'tcx> { // This additional check for stability is to make sure we // don't emit additional, irrelevant errors for malformed // attributes. - if *stab_attr != sym::stable || since.is_some() { + let is_unstable = + matches!(*stab_attr, sym::unstable | sym::rustc_const_unstable); + if since.is_some() || is_unstable { return Some((feature, since, attr.span)); } } From 4246916619e98b5e2c5f5abd21caacfdd392ec71 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 26 Mar 2022 19:43:11 -0700 Subject: [PATCH 03/15] Adjust feature names that disagree on const stabilization version --- library/core/src/alloc/layout.rs | 8 ++-- library/core/src/char/methods.rs | 2 +- library/core/src/intrinsics.rs | 6 +-- library/core/src/lib.rs | 3 +- library/core/src/mem/maybe_uninit.rs | 4 +- library/core/src/mem/mod.rs | 4 +- library/core/src/num/int_macros.rs | 6 +-- library/core/src/num/mod.rs | 2 +- library/core/src/num/nonzero.rs | 2 +- library/core/src/num/uint_macros.rs | 6 +-- library/core/src/option.rs | 6 +-- library/core/src/result.rs | 6 +-- library/core/src/sync/atomic.rs | 4 +- library/core/src/time.rs | 8 ++-- library/core/tests/lib.rs | 1 - library/std/src/net/ip.rs | 46 +++++++++---------- src/test/rustdoc/const-display.rs | 6 +-- src/test/ui/consts/assert-type-intrinsics.rs | 2 +- .../consts/const-eval/simd/insert_extract.rs | 2 +- 19 files changed, 61 insertions(+), 63 deletions(-) diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index 0639d6eed62a5..db6898c1308a2 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -56,7 +56,7 @@ impl Layout { /// must not overflow (i.e., the rounded value must be less than /// or equal to `usize::MAX`). #[stable(feature = "alloc_layout", since = "1.28.0")] - #[rustc_const_stable(feature = "const_alloc_layout", since = "1.50.0")] + #[rustc_const_stable(feature = "const_alloc_layout_size_align", since = "1.50.0")] #[inline] pub const fn from_size_align(size: usize, align: usize) -> Result { if !align.is_power_of_two() { @@ -93,7 +93,7 @@ impl Layout { /// This function is unsafe as it does not verify the preconditions from /// [`Layout::from_size_align`]. #[stable(feature = "alloc_layout", since = "1.28.0")] - #[rustc_const_stable(feature = "alloc_layout", since = "1.36.0")] + #[rustc_const_stable(feature = "const_alloc_layout_unchecked", since = "1.36.0")] #[must_use] #[inline] pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self { @@ -103,7 +103,7 @@ impl Layout { /// The minimum size in bytes for a memory block of this layout. #[stable(feature = "alloc_layout", since = "1.28.0")] - #[rustc_const_stable(feature = "const_alloc_layout", since = "1.50.0")] + #[rustc_const_stable(feature = "const_alloc_layout_size_align", since = "1.50.0")] #[must_use] #[inline] pub const fn size(&self) -> usize { @@ -112,7 +112,7 @@ impl Layout { /// The minimum byte alignment for a memory block of this layout. #[stable(feature = "alloc_layout", since = "1.28.0")] - #[rustc_const_stable(feature = "const_alloc_layout", since = "1.50.0")] + #[rustc_const_stable(feature = "const_alloc_layout_size_align", since = "1.50.0")] #[must_use = "this returns the minimum alignment, \ without modifying the layout"] #[inline] diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index 7deb3358c95d5..3195205b1b677 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -1092,7 +1092,7 @@ impl char { /// ``` #[must_use] #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.32.0")] + #[rustc_const_stable(feature = "const_char_is_ascii", since = "1.32.0")] #[inline] pub const fn is_ascii(&self) -> bool { *self as u32 <= 0x7F diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 8ad4317c145ac..474a632773fb8 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1638,7 +1638,7 @@ extern "rust-intrinsic" { /// let num_trailing = unsafe { cttz_nonzero(x) }; /// assert_eq!(num_trailing, 3); /// ``` - #[rustc_const_stable(feature = "const_cttz", since = "1.53.0")] + #[rustc_const_stable(feature = "const_cttz_nonzero", since = "1.53.0")] pub fn cttz_nonzero(x: T) -> T; /// Reverses the bytes in an integer type `T`. @@ -1718,7 +1718,7 @@ extern "rust-intrinsic" { /// Safe wrappers for this intrinsic are available on the integer /// primitives via the `checked_div` method. For example, /// [`u32::checked_div`] - #[rustc_const_stable(feature = "const_int_unchecked_arith", since = "1.52.0")] + #[rustc_const_stable(feature = "const_int_unchecked_div", since = "1.52.0")] pub fn unchecked_div(x: T, y: T) -> T; /// Returns the remainder of an unchecked division, resulting in /// undefined behavior when `y == 0` or `x == T::MIN && y == -1` @@ -1726,7 +1726,7 @@ extern "rust-intrinsic" { /// Safe wrappers for this intrinsic are available on the integer /// primitives via the `checked_rem` method. For example, /// [`u32::checked_rem`] - #[rustc_const_stable(feature = "const_int_unchecked_arith", since = "1.52.0")] + #[rustc_const_stable(feature = "const_int_unchecked_rem", since = "1.52.0")] pub fn unchecked_rem(x: T, y: T) -> T; /// Performs an unchecked left shift, resulting in undefined behavior when diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 445a7ba6e2d66..8dbabe8911fa6 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -97,7 +97,6 @@ // Library features: #![feature(const_align_offset)] #![feature(const_align_of_val)] -#![feature(const_alloc_layout)] #![feature(const_arguments_as_str)] #![feature(const_array_into_iter_constructors)] #![feature(const_bigint_helper_methods)] @@ -119,7 +118,7 @@ #![feature(const_intrinsic_forget)] #![feature(const_likely)] #![feature(const_maybe_uninit_as_mut_ptr)] -#![feature(const_maybe_uninit_assume_init)] +#![feature(const_maybe_uninit_assume_init_mut)] #![feature(const_num_from_num)] #![feature(const_ops)] #![feature(const_option)] diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 9db5a9a288940..3d66090e04115 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -905,7 +905,7 @@ impl MaybeUninit { /// }; /// ``` #[stable(feature = "maybe_uninit_ref", since = "1.55.0")] - #[rustc_const_unstable(feature = "const_maybe_uninit_assume_init", issue = "none")] + #[rustc_const_unstable(feature = "const_maybe_uninit_assume_init_mut", issue = "none")] #[inline(always)] pub const unsafe fn assume_init_mut(&mut self) -> &mut T { // SAFETY: the caller must guarantee that `self` is initialized. @@ -991,7 +991,7 @@ impl MaybeUninit { /// /// [`assume_init_mut`]: MaybeUninit::assume_init_mut #[unstable(feature = "maybe_uninit_slice", issue = "63569")] - #[rustc_const_unstable(feature = "const_maybe_uninit_assume_init", issue = "none")] + #[rustc_const_unstable(feature = "const_maybe_uninit_assume_init_mut", issue = "none")] #[inline(always)] pub const unsafe fn slice_assume_init_mut(slice: &mut [Self]) -> &mut [T] { // SAFETY: similar to safety notes for `slice_get_ref`, but we have a diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 8a99bed6a96ab..005f8749e01e6 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -299,7 +299,7 @@ pub fn forget_unsized(t: T) { #[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_promotable] -#[rustc_const_stable(feature = "const_size_of", since = "1.24.0")] +#[rustc_const_stable(feature = "const_mem_size_of", since = "1.24.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "mem_size_of")] pub const fn size_of() -> usize { intrinsics::size_of::() @@ -581,7 +581,7 @@ pub const unsafe fn align_of_val_raw(val: *const T) -> usize { #[inline] #[must_use] #[stable(feature = "needs_drop", since = "1.21.0")] -#[rustc_const_stable(feature = "const_needs_drop", since = "1.36.0")] +#[rustc_const_stable(feature = "const_mem_needs_drop", since = "1.36.0")] #[rustc_diagnostic_item = "needs_drop"] pub const fn needs_drop() -> bool { intrinsics::needs_drop::() diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 3665573ab0ff2..ec460286d0378 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -270,7 +270,7 @@ macro_rules! int_impl { #[doc = concat!("assert_eq!(0, 0", stringify!($SelfT), ".reverse_bits());")] /// ``` #[stable(feature = "reverse_bits", since = "1.37.0")] - #[rustc_const_stable(feature = "const_int_methods", since = "1.37.0")] + #[rustc_const_stable(feature = "reverse_bits", since = "1.37.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] @@ -603,7 +603,7 @@ macro_rules! int_impl { #[doc = concat!("assert_eq!((1", stringify!($SelfT), ").checked_div(0), None);")] /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.52.0")] + #[rustc_const_stable(feature = "const_checked_int_div", since = "1.52.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -656,7 +656,7 @@ macro_rules! int_impl { #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.checked_rem(-1), None);")] /// ``` #[stable(feature = "wrapping", since = "1.7.0")] - #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.52.0")] + #[rustc_const_stable(feature = "const_checked_int_div", since = "1.52.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index f4f1d274d105b..8cbece0417b07 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -281,7 +281,7 @@ impl u8 { /// ``` #[must_use] #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.43.0")] + #[rustc_const_stable(feature = "const_u8_is_ascii", since = "1.43.0")] #[inline] pub const fn is_ascii(&self) -> bool { *self & 128 == 0 diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index c36529314784e..0ffbde33a0d1e 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -74,7 +74,7 @@ macro_rules! nonzero_integers { /// Returns the value as a primitive type. #[$stability] #[inline] - #[rustc_const_stable(feature = "nonzero", since = "1.34.0")] + #[rustc_const_stable(feature = "const_nonzero_get", since = "1.34.0")] pub const fn get(self) -> $Int { self.0 } diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 4751faeb93678..514ac69f7e049 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -273,7 +273,7 @@ macro_rules! uint_impl { #[doc = concat!("assert_eq!(0, 0", stringify!($SelfT), ".reverse_bits());")] /// ``` #[stable(feature = "reverse_bits", since = "1.37.0")] - #[rustc_const_stable(feature = "const_math", since = "1.37.0")] + #[rustc_const_stable(feature = "reverse_bits", since = "1.37.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] @@ -591,7 +591,7 @@ macro_rules! uint_impl { #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_div(0), None);")] /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.52.0")] + #[rustc_const_stable(feature = "const_checked_int_div", since = "1.52.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -642,7 +642,7 @@ macro_rules! uint_impl { #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_rem(0), None);")] /// ``` #[stable(feature = "wrapping", since = "1.7.0")] - #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.52.0")] + #[rustc_const_stable(feature = "const_checked_int_div", since = "1.52.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] diff --git a/library/core/src/option.rs b/library/core/src/option.rs index acab8de8c70f5..b5ca9e35dced1 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -549,7 +549,7 @@ impl Option { #[must_use = "if you intended to assert that this has a value, consider `.unwrap()` instead"] #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_option", since = "1.48.0")] + #[rustc_const_stable(feature = "const_option_basics", since = "1.48.0")] pub const fn is_some(&self) -> bool { matches!(*self, Some(_)) } @@ -592,7 +592,7 @@ impl Option { `.and_then(|_| panic!(\"`Option` had a value when expected `None`\"))` instead"] #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_option", since = "1.48.0")] + #[rustc_const_stable(feature = "const_option_basics", since = "1.48.0")] pub const fn is_none(&self) -> bool { !self.is_some() } @@ -621,7 +621,7 @@ impl Option { /// println!("still can print text: {text:?}"); /// ``` #[inline] - #[rustc_const_stable(feature = "const_option", since = "1.48.0")] + #[rustc_const_stable(feature = "const_option_basics", since = "1.48.0")] #[stable(feature = "rust1", since = "1.0.0")] pub const fn as_ref(&self) -> Option<&T> { match *self { diff --git a/library/core/src/result.rs b/library/core/src/result.rs index afd0c8572291d..641749be36637 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -536,7 +536,7 @@ impl Result { /// assert_eq!(x.is_ok(), false); /// ``` #[must_use = "if you intended to assert that this is ok, consider `.unwrap()` instead"] - #[rustc_const_stable(feature = "const_result", since = "1.48.0")] + #[rustc_const_stable(feature = "const_result_basics", since = "1.48.0")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub const fn is_ok(&self) -> bool { @@ -580,7 +580,7 @@ impl Result { /// assert_eq!(x.is_err(), true); /// ``` #[must_use = "if you intended to assert that this is err, consider `.unwrap_err()` instead"] - #[rustc_const_stable(feature = "const_result", since = "1.48.0")] + #[rustc_const_stable(feature = "const_result_basics", since = "1.48.0")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub const fn is_err(&self) -> bool { @@ -698,7 +698,7 @@ impl Result { /// assert_eq!(x.as_ref(), Err(&"Error")); /// ``` #[inline] - #[rustc_const_stable(feature = "const_result", since = "1.48.0")] + #[rustc_const_stable(feature = "const_result_basics", since = "1.48.0")] #[stable(feature = "rust1", since = "1.0.0")] pub const fn as_ref(&self) -> Result<&T, &E> { match *self { diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index a9edec80540dd..f45b4b6015c0f 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -2497,7 +2497,7 @@ macro_rules! atomic_int_ptr_sized { stable(feature = "atomic_access", since = "1.15.0"), stable(feature = "atomic_from", since = "1.23.0"), stable(feature = "atomic_nand", since = "1.27.0"), - rustc_const_stable(feature = "const_integer_atomics", since = "1.24.0"), + rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"), stable(feature = "rust1", since = "1.0.0"), "isize", "", @@ -2517,7 +2517,7 @@ macro_rules! atomic_int_ptr_sized { stable(feature = "atomic_access", since = "1.15.0"), stable(feature = "atomic_from", since = "1.23.0"), stable(feature = "atomic_nand", since = "1.27.0"), - rustc_const_stable(feature = "const_integer_atomics", since = "1.24.0"), + rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"), stable(feature = "rust1", since = "1.0.0"), "usize", "", diff --git a/library/core/src/time.rs b/library/core/src/time.rs index bd72d82b71c00..6c97305b1a849 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -333,7 +333,7 @@ impl Duration { /// /// [`subsec_nanos`]: Duration::subsec_nanos #[stable(feature = "duration", since = "1.3.0")] - #[rustc_const_stable(feature = "duration", since = "1.32.0")] + #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")] #[must_use] #[inline] pub const fn as_secs(&self) -> u64 { @@ -356,7 +356,7 @@ impl Duration { /// assert_eq!(duration.subsec_millis(), 432); /// ``` #[stable(feature = "duration_extras", since = "1.27.0")] - #[rustc_const_stable(feature = "duration_extras", since = "1.32.0")] + #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")] #[must_use] #[inline] pub const fn subsec_millis(&self) -> u32 { @@ -379,7 +379,7 @@ impl Duration { /// assert_eq!(duration.subsec_micros(), 234_567); /// ``` #[stable(feature = "duration_extras", since = "1.27.0")] - #[rustc_const_stable(feature = "duration_extras", since = "1.32.0")] + #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")] #[must_use] #[inline] pub const fn subsec_micros(&self) -> u32 { @@ -402,7 +402,7 @@ impl Duration { /// assert_eq!(duration.subsec_nanos(), 10_000_000); /// ``` #[stable(feature = "duration", since = "1.3.0")] - #[rustc_const_stable(feature = "duration", since = "1.32.0")] + #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")] #[must_use] #[inline] pub const fn subsec_nanos(&self) -> u32 { diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 5f90a76ab74ee..0d88a88376ab7 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -13,7 +13,6 @@ #![feature(const_convert)] #![feature(const_heap)] #![feature(const_maybe_uninit_as_mut_ptr)] -#![feature(const_maybe_uninit_assume_init)] #![feature(const_maybe_uninit_assume_init_read)] #![feature(const_nonnull_new)] #![feature(const_num_from_num)] diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs index 70a7d7a8cabc1..036f291997607 100644 --- a/library/std/src/net/ip.rs +++ b/library/std/src/net/ip.rs @@ -235,7 +235,7 @@ impl IpAddr { /// assert_eq!(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)).is_unspecified(), true); /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)).is_unspecified(), true); /// ``` - #[rustc_const_stable(feature = "const_ip", since = "1.50.0")] + #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")] #[stable(feature = "ip_shared", since = "1.12.0")] #[must_use] #[inline] @@ -259,7 +259,7 @@ impl IpAddr { /// assert_eq!(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)).is_loopback(), true); /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1)).is_loopback(), true); /// ``` - #[rustc_const_stable(feature = "const_ip", since = "1.50.0")] + #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")] #[stable(feature = "ip_shared", since = "1.12.0")] #[must_use] #[inline] @@ -309,7 +309,7 @@ impl IpAddr { /// assert_eq!(IpAddr::V4(Ipv4Addr::new(224, 254, 0, 0)).is_multicast(), true); /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0)).is_multicast(), true); /// ``` - #[rustc_const_stable(feature = "const_ip", since = "1.50.0")] + #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")] #[stable(feature = "ip_shared", since = "1.12.0")] #[must_use] #[inline] @@ -387,7 +387,7 @@ impl IpAddr { /// assert_eq!(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 6)).is_ipv4(), true); /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0)).is_ipv4(), false); /// ``` - #[rustc_const_stable(feature = "const_ip", since = "1.50.0")] + #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")] #[stable(feature = "ipaddr_checker", since = "1.16.0")] #[must_use] #[inline] @@ -408,7 +408,7 @@ impl IpAddr { /// assert_eq!(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 6)).is_ipv6(), false); /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0)).is_ipv6(), true); /// ``` - #[rustc_const_stable(feature = "const_ip", since = "1.50.0")] + #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")] #[stable(feature = "ipaddr_checker", since = "1.16.0")] #[must_use] #[inline] @@ -454,7 +454,7 @@ impl Ipv4Addr { /// /// let addr = Ipv4Addr::new(127, 0, 0, 1); /// ``` - #[rustc_const_stable(feature = "const_ipv4", since = "1.32.0")] + #[rustc_const_stable(feature = "const_ip_32", since = "1.32.0")] #[stable(feature = "rust1", since = "1.0.0")] #[must_use] #[inline] @@ -516,7 +516,7 @@ impl Ipv4Addr { /// let addr = Ipv4Addr::new(127, 0, 0, 1); /// assert_eq!(addr.octets(), [127, 0, 0, 1]); /// ``` - #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")] + #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")] #[stable(feature = "rust1", since = "1.0.0")] #[must_use] #[inline] @@ -540,7 +540,7 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(0, 0, 0, 0).is_unspecified(), true); /// assert_eq!(Ipv4Addr::new(45, 22, 13, 197).is_unspecified(), false); /// ``` - #[rustc_const_stable(feature = "const_ipv4", since = "1.32.0")] + #[rustc_const_stable(feature = "const_ip_32", since = "1.32.0")] #[stable(feature = "ip_shared", since = "1.12.0")] #[must_use] #[inline] @@ -562,7 +562,7 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(127, 0, 0, 1).is_loopback(), true); /// assert_eq!(Ipv4Addr::new(45, 22, 13, 197).is_loopback(), false); /// ``` - #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")] + #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")] #[stable(since = "1.7.0", feature = "ip_17")] #[must_use] #[inline] @@ -593,7 +593,7 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(192, 168, 0, 2).is_private(), true); /// assert_eq!(Ipv4Addr::new(192, 169, 0, 2).is_private(), false); /// ``` - #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")] + #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")] #[stable(since = "1.7.0", feature = "ip_17")] #[must_use] #[inline] @@ -621,7 +621,7 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(169, 254, 10, 65).is_link_local(), true); /// assert_eq!(Ipv4Addr::new(16, 89, 10, 65).is_link_local(), false); /// ``` - #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")] + #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")] #[stable(since = "1.7.0", feature = "ip_17")] #[must_use] #[inline] @@ -823,7 +823,7 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(236, 168, 10, 65).is_multicast(), true); /// assert_eq!(Ipv4Addr::new(172, 16, 10, 65).is_multicast(), false); /// ``` - #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")] + #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")] #[stable(since = "1.7.0", feature = "ip_17")] #[must_use] #[inline] @@ -845,7 +845,7 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_broadcast(), true); /// assert_eq!(Ipv4Addr::new(236, 168, 10, 65).is_broadcast(), false); /// ``` - #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")] + #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")] #[stable(since = "1.7.0", feature = "ip_17")] #[must_use] #[inline] @@ -873,7 +873,7 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(203, 0, 113, 6).is_documentation(), true); /// assert_eq!(Ipv4Addr::new(193, 34, 17, 19).is_documentation(), false); /// ``` - #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")] + #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")] #[stable(since = "1.7.0", feature = "ip_17")] #[must_use] #[inline] @@ -901,7 +901,7 @@ impl Ipv4Addr { /// Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0xc000, 0x2ff) /// ); /// ``` - #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")] + #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")] #[stable(feature = "rust1", since = "1.0.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] @@ -928,7 +928,7 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(192, 0, 2, 255).to_ipv6_mapped(), /// Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x2ff)); /// ``` - #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")] + #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")] #[stable(feature = "rust1", since = "1.0.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] @@ -1216,7 +1216,7 @@ impl Ipv6Addr { /// /// let addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff); /// ``` - #[rustc_const_stable(feature = "const_ipv6", since = "1.32.0")] + #[rustc_const_stable(feature = "const_ip_32", since = "1.32.0")] #[stable(feature = "rust1", since = "1.0.0")] #[must_use] #[inline] @@ -1278,7 +1278,7 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).segments(), /// [0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff]); /// ``` - #[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")] + #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")] #[stable(feature = "rust1", since = "1.0.0")] #[must_use] #[inline] @@ -1315,7 +1315,7 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unspecified(), false); /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0).is_unspecified(), true); /// ``` - #[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")] + #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")] #[stable(since = "1.7.0", feature = "ip_17")] #[must_use] #[inline] @@ -1339,7 +1339,7 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_loopback(), false); /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1).is_loopback(), true); /// ``` - #[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")] + #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")] #[stable(since = "1.7.0", feature = "ip_17")] #[must_use] #[inline] @@ -1624,7 +1624,7 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).is_multicast(), true); /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_multicast(), false); /// ``` - #[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")] + #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")] #[stable(since = "1.7.0", feature = "ip_17")] #[must_use] #[inline] @@ -1693,7 +1693,7 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).to_ipv4(), /// Some(Ipv4Addr::new(0, 0, 0, 1))); /// ``` - #[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")] + #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")] #[stable(feature = "rust1", since = "1.0.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] @@ -1740,7 +1740,7 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).octets(), /// [255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); /// ``` - #[rustc_const_stable(feature = "const_ipv6", since = "1.32.0")] + #[rustc_const_stable(feature = "const_ip_32", since = "1.32.0")] #[stable(feature = "ipv6_to_octets", since = "1.12.0")] #[must_use] #[inline] diff --git a/src/test/rustdoc/const-display.rs b/src/test/rustdoc/const-display.rs index e3f5d07478304..8455dd9ef95f4 100644 --- a/src/test/rustdoc/const-display.rs +++ b/src/test/rustdoc/const-display.rs @@ -64,7 +64,7 @@ impl Foo { // @has 'foo/struct.Foo.html' '//*[@id="method.stable_impl"]/h4[@class="code-header"]' 'pub const fn stable_impl() -> u32' // @has - '//span[@class="since"]' '1.0.0 (const: 1.2.0)' #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "rust1", since = "1.2.0")] + #[rustc_const_stable(feature = "const2", since = "1.2.0")] pub const fn stable_impl() -> u32 { 42 } } @@ -75,12 +75,12 @@ impl Bar { // Do not show non-const stabilities that are the same as the enclosing item. // @matches 'foo/struct.Bar.html' '//span[@class="since"]' '^const: 1.2.0$' #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "rust1", since = "1.2.0")] + #[rustc_const_stable(feature = "const2", since = "1.2.0")] pub const fn stable_impl() -> u32 { 42 } // Show const-stability even for unstable functions. // @matches 'foo/struct.Bar.html' '//span[@class="since"]' '^const: 1.3.0$' #[unstable(feature = "foo2", issue = "none")] - #[rustc_const_stable(feature = "rust1", since = "1.3.0")] + #[rustc_const_stable(feature = "const3", since = "1.3.0")] pub const fn const_stable_unstable() -> u32 { 42 } } diff --git a/src/test/ui/consts/assert-type-intrinsics.rs b/src/test/ui/consts/assert-type-intrinsics.rs index 31ff6aed03b2f..38e5c454edf75 100644 --- a/src/test/ui/consts/assert-type-intrinsics.rs +++ b/src/test/ui/consts/assert-type-intrinsics.rs @@ -1,7 +1,7 @@ // error-pattern: any use of this value will cause an error #![feature(never_type)] -#![feature(const_maybe_uninit_assume_init, const_assert_type2)] +#![feature(const_assert_type2)] #![feature(core_intrinsics)] use std::intrinsics; diff --git a/src/test/ui/consts/const-eval/simd/insert_extract.rs b/src/test/ui/consts/const-eval/simd/insert_extract.rs index a1d6c5e51b498..3472c05d12fa8 100644 --- a/src/test/ui/consts/const-eval/simd/insert_extract.rs +++ b/src/test/ui/consts/const-eval/simd/insert_extract.rs @@ -2,7 +2,7 @@ #![feature(repr_simd)] #![feature(platform_intrinsics)] #![feature(staged_api)] -#![stable(feature = "foo", since = "1.33.7")] +#![stable(feature = "foo", since = "1.3.37")] #![allow(non_camel_case_types)] #[repr(simd)] struct i8x1(i8); From 3c8e7b9e56d7588846e0e7f69914a296729b5b39 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 31 Mar 2022 12:04:14 -0700 Subject: [PATCH 04/15] Adjust MaybeUninit feature names to avoid changing unstable one --- library/core/src/lib.rs | 2 +- library/core/src/mem/maybe_uninit.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 8dbabe8911fa6..7dfcc36ce9391 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -118,7 +118,7 @@ #![feature(const_intrinsic_forget)] #![feature(const_likely)] #![feature(const_maybe_uninit_as_mut_ptr)] -#![feature(const_maybe_uninit_assume_init_mut)] +#![feature(const_maybe_uninit_assume_init)] #![feature(const_num_from_num)] #![feature(const_ops)] #![feature(const_option)] diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 3d66090e04115..58d682fc4c8d4 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -622,7 +622,7 @@ impl MaybeUninit { /// // `x` had not been initialized yet, so this last line caused undefined behavior. ⚠️ /// ``` #[stable(feature = "maybe_uninit", since = "1.36.0")] - #[rustc_const_stable(feature = "const_maybe_uninit_assume_init", since = "1.59.0")] + #[rustc_const_stable(feature = "const_maybe_uninit_assume_init_by_value", since = "1.59.0")] #[inline(always)] #[rustc_diagnostic_item = "assume_init"] #[track_caller] @@ -788,7 +788,7 @@ impl MaybeUninit { /// } /// ``` #[stable(feature = "maybe_uninit_ref", since = "1.55.0")] - #[rustc_const_stable(feature = "const_maybe_uninit_assume_init", since = "1.59.0")] + #[rustc_const_stable(feature = "const_maybe_uninit_assume_init_ref", since = "1.59.0")] #[inline(always)] pub const unsafe fn assume_init_ref(&self) -> &T { // SAFETY: the caller must guarantee that `self` is initialized. @@ -905,7 +905,7 @@ impl MaybeUninit { /// }; /// ``` #[stable(feature = "maybe_uninit_ref", since = "1.55.0")] - #[rustc_const_unstable(feature = "const_maybe_uninit_assume_init_mut", issue = "none")] + #[rustc_const_unstable(feature = "const_maybe_uninit_assume_init", issue = "none")] #[inline(always)] pub const unsafe fn assume_init_mut(&mut self) -> &mut T { // SAFETY: the caller must guarantee that `self` is initialized. @@ -991,7 +991,7 @@ impl MaybeUninit { /// /// [`assume_init_mut`]: MaybeUninit::assume_init_mut #[unstable(feature = "maybe_uninit_slice", issue = "63569")] - #[rustc_const_unstable(feature = "const_maybe_uninit_assume_init_mut", issue = "none")] + #[rustc_const_unstable(feature = "const_maybe_uninit_assume_init", issue = "none")] #[inline(always)] pub const unsafe fn slice_assume_init_mut(slice: &mut [Self]) -> &mut [T] { // SAFETY: similar to safety notes for `slice_get_ref`, but we have a From 971ecff70fbaea5f43f979289e9becd5d4fc4b48 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 31 Mar 2022 12:46:30 -0700 Subject: [PATCH 05/15] Fix feature name of stable parts of strict_provenance --- library/core/src/ptr/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 6a7841d3de6af..36cce3b09c4e6 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -510,7 +510,7 @@ pub const fn null_mut() -> *mut T { /// see the [module documentation][crate::ptr] for details. #[inline(always)] #[must_use] -#[rustc_const_stable(feature = "strict_provenance", since = "1.61.0")] +#[rustc_const_stable(feature = "stable_things_using_strict_provenance", since = "1.61.0")] #[unstable(feature = "strict_provenance", issue = "95228")] pub const fn invalid(addr: usize) -> *const T { // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. @@ -537,7 +537,7 @@ pub const fn invalid(addr: usize) -> *const T { /// see the [module documentation][crate::ptr] for details. #[inline(always)] #[must_use] -#[rustc_const_stable(feature = "strict_provenance", since = "1.61.0")] +#[rustc_const_stable(feature = "stable_things_using_strict_provenance", since = "1.61.0")] #[unstable(feature = "strict_provenance", issue = "95228")] pub const fn invalid_mut(addr: usize) -> *mut T { // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. From b657cb5577d373c4c926c4a555520d0f5c3afdeb Mon Sep 17 00:00:00 2001 From: jam1garner <8260240+jam1garner@users.noreply.github.com> Date: Thu, 31 Mar 2022 18:14:01 -0400 Subject: [PATCH 06/15] Add error message suggestion for missing noreturn in naked function --- compiler/rustc_passes/src/naked_functions.rs | 15 +++++++++++- src/test/ui/asm/naked-functions.stderr | 25 ++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index 00a93ccc9aa09..30db0cec0804a 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -1,7 +1,7 @@ //! Checks validity of naked functions. use rustc_ast::{Attribute, InlineAsmOptions}; -use rustc_errors::struct_span_err; +use rustc_errors::{struct_span_err, Applicability}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{FnKind, Visitor}; @@ -274,12 +274,25 @@ impl<'tcx> CheckInlineAssembly<'tcx> { } if !asm.options.contains(InlineAsmOptions::NORETURN) { + let last_span = asm + .operands + .last() + .map_or_else(|| asm.template_strs.last().unwrap().2, |op| op.1) + .shrink_to_hi(); + struct_span_err!( self.tcx.sess, span, E0787, "asm in naked functions must use `noreturn` option" ) + .span_suggestion( + last_span, + "consider specifying that the asm block is responsible \ + for returning, if desired", + String::from(", options(noreturn)"), + Applicability::MachineApplicable, + ) .emit(); } } diff --git a/src/test/ui/asm/naked-functions.stderr b/src/test/ui/asm/naked-functions.stderr index 5520f815f3e54..edaecb78b2c56 100644 --- a/src/test/ui/asm/naked-functions.stderr +++ b/src/test/ui/asm/naked-functions.stderr @@ -97,6 +97,11 @@ LL | | LL | | sym G, LL | | ); | |_____^ + | +help: consider specifying that the asm block is responsible for returning, if desired + | +LL | sym G, options(noreturn), + | +++++++++++++++++++ error[E0787]: naked functions must contain a single asm block --> $DIR/naked-functions.rs:53:1 @@ -131,18 +136,33 @@ error[E0787]: asm in naked functions must use `noreturn` option | LL | asm!(""); | ^^^^^^^^ + | +help: consider specifying that the asm block is responsible for returning, if desired + | +LL | asm!("", options(noreturn)); + | +++++++++++++++++++ error[E0787]: asm in naked functions must use `noreturn` option --> $DIR/naked-functions.rs:85:5 | LL | asm!(""); | ^^^^^^^^ + | +help: consider specifying that the asm block is responsible for returning, if desired + | +LL | asm!("", options(noreturn)); + | +++++++++++++++++++ error[E0787]: asm in naked functions must use `noreturn` option --> $DIR/naked-functions.rs:87:5 | LL | asm!(""); | ^^^^^^^^ + | +help: consider specifying that the asm block is responsible for returning, if desired + | +LL | asm!("", options(noreturn)); + | +++++++++++++++++++ error[E0787]: naked functions must contain a single asm block --> $DIR/naked-functions.rs:81:1 @@ -198,6 +218,11 @@ error[E0787]: asm in naked functions must use `noreturn` option | LL | asm!("", options(readonly, nostack), options(pure)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider specifying that the asm block is responsible for returning, if desired + | +LL | asm!("", options(noreturn), options(readonly, nostack), options(pure)); + | +++++++++++++++++++ error[E0787]: asm options unsupported in naked functions: `may_unwind` --> $DIR/naked-functions.rs:118:5 From 2a827635ba65e3d40af8643373e4584858eecc7d Mon Sep 17 00:00:00 2001 From: Declan Kelly Date: Fri, 1 Apr 2022 00:19:10 -0700 Subject: [PATCH 07/15] Implement provenance preserving method on NonNull **Description** Add the `addr`, `with_addr, `map_addr` methods to the `NonNull` type, and map the address type to `NonZeroUsize`. **Motiviation** The `NonNull` type is useful for implementing pointer types which have the 0-niche. It is currently possible to implement these provenance preserving functions by calling `NonNull::as_ptr` and `new_unchecked`. The addition of these methods simply make it more ergonomic to use. **Testing** Added a unit test of a nonnull tagged pointer type. This is based on some real code I have elsewhere, that currently routes the pointer through a `NonZeroUsize` and back out to produce a usable pointer. --- library/core/src/ptr/non_null.rs | 48 ++++++++++++++++++++ library/core/tests/lib.rs | 1 + library/core/tests/ptr.rs | 78 ++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index c1b19895f006c..7516d4bba4cdf 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -4,6 +4,7 @@ use crate::fmt; use crate::hash; use crate::marker::Unsize; use crate::mem::{self, MaybeUninit}; +use crate::num::NonZeroUsize; use crate::ops::{CoerceUnsized, DispatchFromDyn}; use crate::ptr::Unique; use crate::slice::{self, SliceIndex}; @@ -253,6 +254,53 @@ impl NonNull { (self.cast(), super::metadata(self.as_ptr())) } + /// Gets the "address" portion of the pointer. + /// + /// This API and its claimed semantics are part of the Strict Provenance experiment, + /// see the [module documentation][crate::ptr] for details. + #[must_use] + #[inline] + #[unstable(feature = "strict_provenance", issue = "95228")] + pub fn addr(self) -> NonZeroUsize + where + T: Sized, + { + // SAFETY: The pointer is guaranteed by the type to be non-null, + // meaning that the address will be non-zero. + unsafe { NonZeroUsize::new_unchecked(self.pointer.addr()) } + } + + /// Creates a new pointer with the given address. + /// + /// This API and its claimed semantics are part of the Strict Provenance experiment, + /// see the [module documentation][crate::ptr] for details. + #[must_use] + #[inline] + #[unstable(feature = "strict_provenance", issue = "95228")] + pub fn with_addr(self, addr: NonZeroUsize) -> Self + where + T: Sized, + { + // SAFETY: The result of `ptr::from::with_addr` is non-null because `addr` is guaranteed to be non-zero. + unsafe { NonNull::new_unchecked(self.pointer.with_addr(addr.get()) as *mut _) } + } + + /// Creates a new pointer by mapping `self`'s address to a new one. + /// + /// This is a convenience for [`with_addr`][Self::with_addr], see that method for details. + /// + /// This API and its claimed semantics are part of the Strict Provenance experiment, + /// see the [module documentation][crate::ptr] for details. + #[must_use] + #[inline] + #[unstable(feature = "strict_provenance", issue = "95228")] + pub fn map_addr(self, f: impl FnOnce(NonZeroUsize) -> NonZeroUsize) -> Self + where + T: Sized, + { + self.with_addr(f(self.addr())) + } + /// Acquires the underlying `*mut` pointer. /// /// # Examples diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 5f90a76ab74ee..42d31c44deee7 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -87,6 +87,7 @@ #![feature(int_roundings)] #![feature(slice_group_by)] #![feature(split_array)] +#![feature(strict_provenance)] #![feature(trusted_random_access)] #![feature(unsize)] #![feature(unzip_option)] diff --git a/library/core/tests/ptr.rs b/library/core/tests/ptr.rs index 750e7295fb533..75857e29ae1cd 100644 --- a/library/core/tests/ptr.rs +++ b/library/core/tests/ptr.rs @@ -1,4 +1,5 @@ use core::cell::RefCell; +use core::num::NonZeroUsize; use core::ptr; use core::ptr::*; use std::fmt::{Debug, Display}; @@ -691,3 +692,80 @@ fn thin_box() { } } } + +#[test] +fn nonnull_tagged_pointer_with_provenance() { + let raw_pointer = Box::into_raw(Box::new(10)); + + let mut p = TaggedPointer::new(raw_pointer).unwrap(); + assert_eq!(p.tag(), 0); + + p.set_tag(1); + assert_eq!(p.tag(), 1); + assert_eq!(unsafe { *p.pointer().as_ptr() }, 10); + + p.set_tag(3); + assert_eq!(p.tag(), 3); + assert_eq!(unsafe { *p.pointer().as_ptr() }, 10); + + unsafe { Box::from_raw(p.pointer().as_ptr()) }; + + /// A non-null pointer type which carries several bits of metadata and maintains provenance. + #[repr(transparent)] + pub struct TaggedPointer(NonNull); + + impl Clone for TaggedPointer { + fn clone(&self) -> Self { + Self(self.0) + } + } + + impl Copy for TaggedPointer {} + + impl TaggedPointer { + /// The ABI-required minimum alignment of the `P` type. + pub const ALIGNMENT: usize = core::mem::align_of::(); + /// A mask for data-carrying bits of the address. + pub const DATA_MASK: usize = !Self::ADDRESS_MASK; + /// Number of available bits of storage in the address. + pub const NUM_BITS: u32 = Self::ALIGNMENT.trailing_zeros(); + /// A mask for the non-data-carrying bits of the address. + pub const ADDRESS_MASK: usize = usize::MAX << Self::NUM_BITS; + + /// Create a new tagged pointer from a possibly null pointer. + pub fn new(pointer: *mut T) -> Option> { + Some(TaggedPointer(NonNull::new(pointer)?)) + } + + /// Consume this tagged pointer and produce a raw mutable pointer to the + /// memory location. + pub fn pointer(self) -> NonNull { + // SAFETY: The `addr` guaranteed to have bits set in the Self::ADDRESS_MASK, so the result will be non-null. + self.0.map_addr(|addr| unsafe { + NonZeroUsize::new_unchecked(addr.get() & Self::ADDRESS_MASK) + }) + } + + /// Consume this tagged pointer and produce the data it carries. + pub fn tag(&self) -> usize { + self.0.addr().get() & Self::DATA_MASK + } + + /// Update the data this tagged pointer carries to a new value. + pub fn set_tag(&mut self, data: usize) { + assert_eq!( + data & Self::ADDRESS_MASK, + 0, + "cannot set more data beyond the lowest NUM_BITS" + ); + let data = data & Self::DATA_MASK; + + // SAFETY: This value will always be non-zero because the upper bits (from + // ADDRESS_MASK) will always be non-zero. This a property of the type and its + // construction. + self.0 = self.0.map_addr(|addr| unsafe { + NonZeroUsize::new_unchecked((addr.get() & Self::ADDRESS_MASK) | data) + }) + } + } +} From 1f232b8e6de8ef170e896a2a98734dd54273349b Mon Sep 17 00:00:00 2001 From: niluxv Date: Fri, 1 Apr 2022 10:38:41 +0200 Subject: [PATCH 08/15] Fix `thread_local!` macro to be compatible with `no_implicit_prelude` Fixes issue #95533 --- library/std/src/thread/local.rs | 16 ++++++++-------- src/test/ui/macros/issue-95533.rs | 8 ++++++++ 2 files changed, 16 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/macros/issue-95533.rs diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs index ca29261b1c98d..587e453ceef91 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -193,7 +193,7 @@ macro_rules! __thread_local_inner { #[cfg(all(target_family = "wasm", not(target_feature = "atomics")))] { static mut VAL: $t = INIT_EXPR; - Some(&VAL) + $crate::option::Option::Some(&VAL) } // If the platform has support for `#[thread_local]`, use it. @@ -209,7 +209,7 @@ macro_rules! __thread_local_inner { // just get going. if !$crate::mem::needs_drop::<$t>() { unsafe { - return Some(&VAL) + return $crate::option::Option::Some(&VAL) } } @@ -223,7 +223,7 @@ macro_rules! __thread_local_inner { let ptr = ptr as *mut $t; unsafe { - debug_assert_eq!(STATE, 1); + $crate::debug_assert_eq!(STATE, 1); STATE = 2; $crate::ptr::drop_in_place(ptr); } @@ -239,14 +239,14 @@ macro_rules! __thread_local_inner { destroy, ); STATE = 1; - Some(&VAL) + $crate::option::Option::Some(&VAL) } // 1 == the destructor is registered and the value // is valid, so return the pointer. - 1 => Some(&VAL), + 1 => $crate::option::Option::Some(&VAL), // otherwise the destructor has already run, so we // can't give access. - _ => None, + _ => $crate::option::Option::None, } } } @@ -269,7 +269,7 @@ macro_rules! __thread_local_inner { if let $crate::option::Option::Some(value) = init.take() { return value; } else if $crate::cfg!(debug_assertions) { - unreachable!("missing initial value"); + $crate::unreachable!("missing initial value"); } } __init() @@ -344,7 +344,7 @@ macro_rules! __thread_local_inner { if let $crate::option::Option::Some(value) = init.take() { return value; } else if $crate::cfg!(debug_assertions) { - unreachable!("missing default value"); + $crate::unreachable!("missing default value"); } } __init() diff --git a/src/test/ui/macros/issue-95533.rs b/src/test/ui/macros/issue-95533.rs new file mode 100644 index 0000000000000..905c14dc5fd21 --- /dev/null +++ b/src/test/ui/macros/issue-95533.rs @@ -0,0 +1,8 @@ +// check-pass + +#![no_implicit_prelude] +// the macro should not rely on the prelude being imported +::std::thread_local! { static P: () = (); } +::std::thread_local! { static Q: () = const { () }; } + +fn main () {} From 18fae7b2e5744f9a177482e268967a9c7a171425 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 1 Apr 2022 12:08:57 +0200 Subject: [PATCH 09/15] update comments --- compiler/rustc_infer/src/infer/canonical/mod.rs | 1 - compiler/rustc_infer/src/infer/mod.rs | 6 +++--- compiler/rustc_typeck/src/check/inherited.rs | 6 +++--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs index 7985686798519..c7fa2527eb2f3 100644 --- a/compiler/rustc_infer/src/infer/canonical/mod.rs +++ b/compiler/rustc_infer/src/infer/canonical/mod.rs @@ -49,7 +49,6 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { /// At the end of processing, the substitution S (once /// canonicalized) then represents the values that you computed /// for each of the canonical inputs to your query. - pub fn instantiate_canonical_with_fresh_inference_vars( &self, span: Span, diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index bd59bf4dea883..8ad4805f94f39 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -558,9 +558,9 @@ impl<'tcx> fmt::Display for FixupError<'tcx> { } } -/// Helper type of a temporary returned by `tcx.infer_ctxt()`. -/// Necessary because we can't write the following bound: -/// `F: for<'b, 'tcx> where 'tcx FnOnce(InferCtxt<'b, 'tcx>)`. +/// A temporary returned by `tcx.infer_ctxt()`. This is necessary +/// for multiple `InferCtxt` to share the same `in_progress_typeck_results` +/// without using `Rc` or something similar. pub struct InferCtxtBuilder<'tcx> { tcx: TyCtxt<'tcx>, fresh_typeck_results: Option>>, diff --git a/compiler/rustc_typeck/src/check/inherited.rs b/compiler/rustc_typeck/src/check/inherited.rs index e7cfa3a7c1493..62ca728868b45 100644 --- a/compiler/rustc_typeck/src/check/inherited.rs +++ b/compiler/rustc_typeck/src/check/inherited.rs @@ -68,9 +68,9 @@ impl<'a, 'tcx> Deref for Inherited<'a, 'tcx> { } } -/// Helper type of a temporary returned by `Inherited::build(...)`. -/// Necessary because we can't write the following bound: -/// `F: for<'b, 'tcx> where 'tcx FnOnce(Inherited<'b, 'tcx>)`. +/// A temporary returned by `Inherited::build(...)`. This is necessary +/// for multiple `InferCtxt` to share the same `in_progress_typeck_results` +/// without using `Rc` or something similar. pub struct InheritedBuilder<'tcx> { infcx: infer::InferCtxtBuilder<'tcx>, def_id: LocalDefId, From c2b5a7ea522672a01b089c159f9b2c3e36d9f4dd Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 1 Apr 2022 12:41:35 +0200 Subject: [PATCH 10/15] remove `unify_key::replace_if_possible` --- compiler/rustc_infer/src/infer/combine.rs | 11 +++----- compiler/rustc_infer/src/infer/freshen.rs | 10 +++---- compiler/rustc_infer/src/infer/mod.rs | 2 -- compiler/rustc_middle/src/infer/unify_key.rs | 27 ++----------------- .../rustc_typeck/src/check/fn_ctxt/mod.rs | 2 +- .../rustc_typeck/src/check/method/probe.rs | 2 +- 6 files changed, 11 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 41995ca509ef6..86229dbfad746 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -27,15 +27,12 @@ use super::glb::Glb; use super::lub::Lub; use super::sub::Sub; use super::type_variable::TypeVariableValue; -use super::unify_key::replace_if_possible; -use super::unify_key::{ConstVarValue, ConstVariableValue}; -use super::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use super::{InferCtxt, MiscVariable, TypeTrace}; - use crate::traits::{Obligation, PredicateObligations}; - use rustc_data_structures::sso::SsoHashMap; use rustc_hir::def_id::DefId; +use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue}; +use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; @@ -140,8 +137,8 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> { return Ok(a); } - let a = replace_if_possible(&mut self.inner.borrow_mut().const_unification_table(), a); - let b = replace_if_possible(&mut self.inner.borrow_mut().const_unification_table(), b); + let a = self.shallow_resolve(a); + let b = self.shallow_resolve(b); let a_is_expected = relation.a_is_expected(); diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index e9d3b6a8aa1a4..0a11a81c29425 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -30,17 +30,13 @@ //! solving a set of constraints. In contrast, the type inferencer assigns a value to each type //! variable only once, and it does so as soon as it can, so it is reasonable to ask what the type //! inferencer knows "so far". - +use super::InferCtxt; +use rustc_data_structures::fx::FxHashMap; +use rustc_middle::infer::unify_key::ToType; use rustc_middle::ty::fold::TypeFolder; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; - -use rustc_data_structures::fx::FxHashMap; - use std::collections::hash_map::Entry; -use super::unify_key::ToType; -use super::InferCtxt; - pub struct TypeFreshener<'a, 'tcx> { infcx: &'a InferCtxt<'a, 'tcx>, ty_freshen_count: u32, diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 8ad4805f94f39..cefe7aae396b4 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -70,8 +70,6 @@ mod sub; pub mod type_variable; mod undo_log; -pub use rustc_middle::infer::unify_key; - #[must_use] #[derive(Debug)] pub struct InferOk<'tcx, T> { diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs index dd303aaada900..7859922d50347 100644 --- a/compiler/rustc_middle/src/infer/unify_key.rs +++ b/compiler/rustc_middle/src/infer/unify_key.rs @@ -1,13 +1,8 @@ -use crate::ty::{self, InferConst, Ty, TyCtxt}; -use rustc_data_structures::snapshot_vec; -use rustc_data_structures::undo_log::UndoLogs; -use rustc_data_structures::unify::{ - self, EqUnifyValue, InPlace, NoError, UnificationTable, UnifyKey, UnifyValue, -}; +use crate::ty::{self, Ty, TyCtxt}; +use rustc_data_structures::unify::{EqUnifyValue, NoError, UnifyKey, UnifyValue}; use rustc_span::def_id::DefId; use rustc_span::symbol::Symbol; use rustc_span::Span; - use std::cmp; use std::marker::PhantomData; @@ -167,21 +162,3 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> { } impl<'tcx> EqUnifyValue for ty::Const<'tcx> {} - -pub fn replace_if_possible<'tcx, V, L>( - table: &mut UnificationTable, V, L>>, - c: ty::Const<'tcx>, -) -> ty::Const<'tcx> -where - V: snapshot_vec::VecLike>>, - L: UndoLogs>>>, -{ - if let ty::ConstKind::Infer(InferConst::Var(vid)) = c.val() { - match table.probe_value(vid).val.known() { - Some(c) => c, - None => c, - } - } else { - c - } -} diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs index 6c55f8212940e..55a5eb966c222 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs @@ -14,7 +14,7 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_infer::infer; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; +use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{self, Const, Ty, TyCtxt}; diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index e3782fe5911df..6edcc12bcf5a6 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -15,8 +15,8 @@ use rustc_hir::def::Namespace; use rustc_infer::infer::canonical::OriginalQueryValues; use rustc_infer::infer::canonical::{Canonical, QueryResponse}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc_infer::infer::{self, InferOk, TyCtxtInferExt}; +use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc_middle::middle::stability; use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; From 389c83b47407747ec96153e04c35717e3ce4d82a Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 1 Apr 2022 12:57:24 +0200 Subject: [PATCH 11/15] remove unused incorrect `EqUnifyValue` impl --- compiler/rustc_middle/src/infer/unify_key.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs index 7859922d50347..f2627885d030d 100644 --- a/compiler/rustc_middle/src/infer/unify_key.rs +++ b/compiler/rustc_middle/src/infer/unify_key.rs @@ -1,5 +1,5 @@ use crate::ty::{self, Ty, TyCtxt}; -use rustc_data_structures::unify::{EqUnifyValue, NoError, UnifyKey, UnifyValue}; +use rustc_data_structures::unify::{NoError, UnifyKey, UnifyValue}; use rustc_span::def_id::DefId; use rustc_span::symbol::Symbol; use rustc_span::Span; @@ -160,5 +160,3 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> { }) } } - -impl<'tcx> EqUnifyValue for ty::Const<'tcx> {} From 796b82837116462377167b16a6d7627250aaa1b0 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 1 Apr 2022 13:38:43 +0200 Subject: [PATCH 12/15] convert more `DefId`s to `LocalDefId` --- .../nice_region_error/static_impl_trait.rs | 4 +-- .../trait_impl_difference.rs | 6 ++-- .../src/infer/error_reporting/note.rs | 4 +-- compiler/rustc_infer/src/infer/mod.rs | 10 +++++-- .../src/traits/error_reporting/mod.rs | 6 ++-- compiler/rustc_middle/src/traits/mod.rs | 6 ++-- .../src/traits/error_reporting/mod.rs | 7 +++-- .../src/traits/error_reporting/suggestions.rs | 8 ++--- .../rustc_typeck/src/check/compare_method.rs | 9 +++--- .../rustc_typeck/src/check/method/confirm.rs | 4 +-- compiler/rustc_typeck/src/check/wfcheck.rs | 29 ++++++++++--------- 11 files changed, 50 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 4fcdcb6366683..c33c0c996bdee 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -237,7 +237,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ObligationCauseCode::MatchImpl(parent, ..) => parent.code(), _ => cause.code(), } - && let (ObligationCauseCode::ItemObligation(item_def_id), None) = (code, override_error_code) + && let (&ObligationCauseCode::ItemObligation(item_def_id), None) = (code, override_error_code) { // Same case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a `'static` // lifetime as above, but called using a fully-qualified path to the method: @@ -245,7 +245,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let mut v = TraitObjectVisitor(FxHashSet::default()); v.visit_ty(param.param_ty); if let Some((ident, self_ty)) = - self.get_impl_ident_and_self_ty_from_trait(*item_def_id, &v.0) + self.get_impl_ident_and_self_ty_from_trait(item_def_id, &v.0) && self.suggest_constrain_dyn_trait_in_impl(&mut err, &v.0, ident, self_ty) { override_error_code = Some(ident.name); diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs index b1a42ee66c920..6d23dc4f471f7 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs @@ -7,7 +7,7 @@ use crate::traits::ObligationCauseCode::CompareImplMethodObligation; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::def::Res; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; use rustc_middle::hir::nested_filter; use rustc_middle::ty::print::RegionHighlightMode; @@ -51,7 +51,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { { let guar = self.emit_associated_type_err( span, - self.infcx.tcx.item_name(impl_item_def_id), + self.infcx.tcx.item_name(impl_item_def_id.to_def_id()), impl_item_def_id, trait_item_def_id, ); @@ -155,7 +155,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { &self, span: Span, item_name: Symbol, - impl_item_def_id: DefId, + impl_item_def_id: LocalDefId, trait_item_def_id: DefId, ) -> ErrorGuaranteed { let impl_sp = self.tcx().def_span(impl_item_def_id); diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index e6c8dc302b6ca..5dcac7f56cc41 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -348,7 +348,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let mut err = self.report_concrete_failure(*parent, sub, sup); let trait_item_span = self.tcx.def_span(trait_item_def_id); - let item_name = self.tcx.item_name(impl_item_def_id); + let item_name = self.tcx.item_name(impl_item_def_id.to_def_id()); err.span_label( trait_item_span, format!("definition of `{}` from trait", item_name), @@ -370,7 +370,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let where_clause_span = self .tcx .hir() - .get_generics(impl_item_def_id.expect_local()) + .get_generics(impl_item_def_id) .unwrap() .where_clause .tail_span_for_suggestion(); diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index bd59bf4dea883..0bb6605492281 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -425,16 +425,20 @@ pub enum SubregionOrigin<'tcx> { /// Comparing the signature and requirements of an impl method against /// the containing trait. - CompareImplMethodObligation { span: Span, impl_item_def_id: DefId, trait_item_def_id: DefId }, + CompareImplMethodObligation { + span: Span, + impl_item_def_id: LocalDefId, + trait_item_def_id: DefId, + }, /// Comparing the signature and requirements of an impl associated type /// against the containing trait - CompareImplTypeObligation { span: Span, impl_item_def_id: DefId, trait_item_def_id: DefId }, + CompareImplTypeObligation { span: Span, impl_item_def_id: LocalDefId, trait_item_def_id: DefId }, /// Checking that the bounds of a trait's associated type hold for a given impl CheckAssociatedTypeBounds { parent: Box>, - impl_item_def_id: DefId, + impl_item_def_id: LocalDefId, trait_item_def_id: DefId, }, } diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs index c8ef08f48b609..25b11e31d57d4 100644 --- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs @@ -4,7 +4,7 @@ use crate::infer::InferCtxt; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{struct_span_err, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::ty::TyCtxt; use rustc_span::{MultiSpan, Span}; use std::fmt; @@ -14,7 +14,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn report_extra_impl_obligation( &self, error_span: Span, - impl_item_def_id: DefId, + impl_item_def_id: LocalDefId, trait_item_def_id: DefId, requirement: &dyn fmt::Display, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { @@ -25,7 +25,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { if let Some(trait_item_span) = self.tcx.hir().span_if_local(trait_item_def_id) { let span = self.tcx.sess.source_map().guess_head_span(trait_item_span); - let item_name = self.tcx.item_name(impl_item_def_id); + let item_name = self.tcx.item_name(impl_item_def_id.to_def_id()); err.span_label(span, format!("definition of `{}` from trait", item_name)); } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 1f18260d9154f..353b872a216da 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -276,19 +276,19 @@ pub enum ObligationCauseCode<'tcx> { /// Error derived when matching traits/impls; see ObligationCause for more details CompareImplMethodObligation { - impl_item_def_id: DefId, + impl_item_def_id: LocalDefId, trait_item_def_id: DefId, }, /// Error derived when matching traits/impls; see ObligationCause for more details CompareImplTypeObligation { - impl_item_def_id: DefId, + impl_item_def_id: LocalDefId, trait_item_def_id: DefId, }, /// Checking that the bounds of a trait's associated type hold for a given impl CheckAssociatedTypeBounds { - impl_item_def_id: DefId, + impl_item_def_id: LocalDefId, trait_item_def_id: DefId, }, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index d83781170e8c3..51b09906e396c 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1797,15 +1797,15 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id()); } else if let ( Ok(ref snippet), - ObligationCauseCode::BindingObligation(ref def_id, _), + &ObligationCauseCode::BindingObligation(def_id, _), ) = (self.tcx.sess.source_map().span_to_snippet(span), obligation.cause.code()) { - let generics = self.tcx.generics_of(*def_id); + let generics = self.tcx.generics_of(def_id); if generics.params.iter().any(|p| p.name != kw::SelfUpper) && !snippet.ends_with('>') && !generics.has_impl_trait() - && !self.tcx.fn_trait_kind_from_lang_item(*def_id).is_some() + && !self.tcx.fn_trait_kind_from_lang_item(def_id).is_some() { // FIXME: To avoid spurious suggestions in functions where type arguments // where already supplied, we check the snippet to make sure it doesn't @@ -2107,6 +2107,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { "suggest_unsized_bound_if_applicable: pred={:?} item_def_id={:?} span={:?}", pred, item_def_id, span ); + let (Some(node), true) = ( self.tcx.hir().get_if_local(item_def_id), Some(pred.def_id()) == self.tcx.lang_items().sized_trait(), diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 58e002b336081..b49a5f6578f75 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -128,7 +128,7 @@ pub trait InferCtxtExt<'tcx> { fn suggest_fully_qualified_path( &self, err: &mut Diagnostic, - def_id: DefId, + item_def_id: DefId, span: Span, trait_ref: DefId, ); @@ -1317,16 +1317,16 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { fn suggest_fully_qualified_path( &self, err: &mut Diagnostic, - def_id: DefId, + item_def_id: DefId, span: Span, trait_ref: DefId, ) { - if let Some(assoc_item) = self.tcx.opt_associated_item(def_id) { + if let Some(assoc_item) = self.tcx.opt_associated_item(item_def_id) { if let ty::AssocKind::Const | ty::AssocKind::Type = assoc_item.kind { err.note(&format!( "{}s cannot be accessed directly on a `trait`, they can only be \ accessed through a specific `impl`", - assoc_item.kind.as_def_kind().descr(def_id) + assoc_item.kind.as_def_kind().descr(item_def_id) )); err.span_suggestion( span, diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index a22c9210a9c22..0bd5e018f4a38 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -28,7 +28,6 @@ use super::{potentially_plural_count, FnCtxt, Inherited}; /// - `impl_m_span`: span to use for reporting errors /// - `trait_m`: the method in the trait /// - `impl_trait_ref`: the TraitRef corresponding to the trait implementation - crate fn compare_impl_method<'tcx>( tcx: TyCtxt<'tcx>, impl_m: &ty::AssocItem, @@ -88,7 +87,7 @@ fn compare_predicate_entailment<'tcx>( impl_m_span, impl_m_hir_id, ObligationCauseCode::CompareImplMethodObligation { - impl_item_def_id: impl_m.def_id, + impl_item_def_id: impl_m.def_id.expect_local(), trait_item_def_id: trait_m.def_id, }, ); @@ -231,7 +230,7 @@ fn compare_predicate_entailment<'tcx>( span, impl_m_hir_id, ObligationCauseCode::CompareImplMethodObligation { - impl_item_def_id: impl_m.def_id, + impl_item_def_id: impl_m.def_id.expect_local(), trait_item_def_id: trait_m.def_id, }, ); @@ -1154,7 +1153,7 @@ fn compare_type_predicate_entailment<'tcx>( impl_ty_span, impl_ty_hir_id, ObligationCauseCode::CompareImplTypeObligation { - impl_item_def_id: impl_ty.def_id, + impl_item_def_id: impl_ty.def_id.expect_local(), trait_item_def_id: trait_ty.def_id, }, ); @@ -1383,7 +1382,7 @@ pub fn check_type_bounds<'tcx>( impl_ty_span, impl_ty_hir_id, ObligationCauseCode::CheckAssociatedTypeBounds { - impl_item_def_id: impl_ty.def_id, + impl_item_def_id: impl_ty.def_id.expect_local(), trait_item_def_id: trait_ty.def_id, }, ); diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs index 3fa873e46abbb..bc0fa9165561d 100644 --- a/compiler/rustc_typeck/src/check/method/confirm.rs +++ b/compiler/rustc_typeck/src/check/method/confirm.rs @@ -2,9 +2,9 @@ use super::{probe, MethodCallee}; use crate::astconv::{AstConv, CreateSubstsForGenericArgsCtxt, IsMethodCall}; use crate::check::{callee, FnCtxt}; -use crate::hir::def_id::DefId; -use crate::hir::GenericArg; use rustc_hir as hir; +use rustc_hir::def_id::DefId; +use rustc_hir::GenericArg; use rustc_infer::infer::{self, InferOk}; use rustc_middle::traits::{ObligationCauseCode, UnifyReceiverContext}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast}; diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index bd08da9529a5f..9b1767c783555 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -940,7 +940,7 @@ fn check_associated_item( item.ident(fcx.tcx).span, sig, hir_sig.decl, - item.def_id, + item.def_id.expect_local(), &mut implied_bounds, ); check_method_receiver(fcx, hir_sig, item, self_ty); @@ -1068,7 +1068,7 @@ fn check_type_defn<'tcx, F>( } } - check_where_clauses(fcx, item.span, item.def_id.to_def_id(), None); + check_where_clauses(fcx, item.span, item.def_id, None); // No implied bounds in a struct definition. FxHashSet::default() @@ -1096,7 +1096,7 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) { // FIXME: this shouldn't use an `FnCtxt` at all. for_item(tcx, item).with_fcx(|fcx| { - check_where_clauses(fcx, item.span, item.def_id.to_def_id(), None); + check_where_clauses(fcx, item.span, item.def_id, None); FxHashSet::default() }); @@ -1144,7 +1144,7 @@ fn check_item_fn( for_id(tcx, def_id, span).with_fcx(|fcx| { let sig = tcx.fn_sig(def_id); let mut implied_bounds = FxHashSet::default(); - check_fn_or_method(fcx, ident.span, sig, decl, def_id.to_def_id(), &mut implied_bounds); + check_fn_or_method(fcx, ident.span, sig, decl, def_id, &mut implied_bounds); implied_bounds }) } @@ -1238,7 +1238,7 @@ fn check_impl<'tcx>( } } - check_where_clauses(fcx, item.span, item.def_id.to_def_id(), None); + check_where_clauses(fcx, item.span, item.def_id, None); fcx.impl_implied_bounds(item.def_id.to_def_id(), item.span) }); @@ -1249,7 +1249,7 @@ fn check_impl<'tcx>( fn check_where_clauses<'tcx, 'fcx>( fcx: &FnCtxt<'fcx, 'tcx>, span: Span, - def_id: DefId, + def_id: LocalDefId, return_ty: Option<(Ty<'tcx>, Span)>, ) { let tcx = fcx.tcx; @@ -1317,7 +1317,7 @@ fn check_where_clauses<'tcx, 'fcx>( // For more examples see tests `defaults-well-formedness.rs` and `type-check-defaults.rs`. // // First we build the defaulted substitution. - let substs = InternalSubsts::for_item(tcx, def_id, |param, _| { + let substs = InternalSubsts::for_item(tcx, def_id.to_def_id(), |param, _| { match param.kind { GenericParamDefKind::Lifetime => { // All regions are identity. @@ -1411,8 +1411,11 @@ fn check_where_clauses<'tcx, 'fcx>( // below: there, we are not trying to prove those predicates // to be *true* but merely *well-formed*. let pred = fcx.normalize_associated_types_in(sp, pred); - let cause = - traits::ObligationCause::new(sp, fcx.body_id, traits::ItemObligation(def_id)); + let cause = traits::ObligationCause::new( + sp, + fcx.body_id, + traits::ItemObligation(def_id.to_def_id()), + ); traits::Obligation::new(cause, fcx.param_env, pred) }); @@ -1445,10 +1448,10 @@ fn check_fn_or_method<'fcx, 'tcx>( span: Span, sig: ty::PolyFnSig<'tcx>, hir_decl: &hir::FnDecl<'_>, - def_id: DefId, + def_id: LocalDefId, implied_bounds: &mut FxHashSet>, ) { - let sig = fcx.tcx.liberate_late_bound_regions(def_id, sig); + let sig = fcx.tcx.liberate_late_bound_regions(def_id.to_def_id(), sig); // Normalize the input and output types one at a time, using a different // `WellFormedLoc` for each. We cannot call `normalize_associated_types` @@ -1462,7 +1465,7 @@ fn check_fn_or_method<'fcx, 'tcx>( span, ty, WellFormedLoc::Param { - function: def_id.expect_local(), + function: def_id, // Note that the `param_idx` of the output type is // one greater than the index of the last input type. param_idx: i.try_into().unwrap(), @@ -1485,7 +1488,7 @@ fn check_fn_or_method<'fcx, 'tcx>( input_ty.into(), ty.span, ObligationCauseCode::WellFormed(Some(WellFormedLoc::Param { - function: def_id.expect_local(), + function: def_id, param_idx: i.try_into().unwrap(), })), ); From 8eacf6078fd923bddf54ae9227beeb41a7218e1d Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 1 Apr 2022 13:47:01 +0200 Subject: [PATCH 13/15] update comment --- compiler/rustc_middle/src/traits/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 353b872a216da..7c3d08b26bf54 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -292,8 +292,7 @@ pub enum ObligationCauseCode<'tcx> { trait_item_def_id: DefId, }, - /// Checking that this expression can be assigned where it needs to be - // FIXME(eddyb) #11161 is the original Expr required? + /// Checking that this expression can be assigned to its target. ExprAssignable, /// Computing common supertype in the arms of a match expression From af24588a06b9fbed47495c787c20e930398bbb86 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 27 Mar 2022 13:10:34 -0400 Subject: [PATCH 14/15] invalid_value lint: detect invalid initialization of arrays --- compiler/rustc_lint/src/builtin.rs | 23 +++++--- src/test/ui/lint/uninitialized-zeroed.rs | 8 +++ src/test/ui/lint/uninitialized-zeroed.stderr | 55 ++++++++++++++++---- 3 files changed, 68 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 50a3df21a3bc9..d43c661dda6fa 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2548,7 +2548,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { /// Return `Some` only if we are sure this type does *not* /// allow zero initialization. fn ty_find_init_error<'tcx>( - tcx: TyCtxt<'tcx>, + cx: &LateContext<'tcx>, ty: Ty<'tcx>, init: InitKind, ) -> Option { @@ -2575,7 +2575,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { Adt(adt_def, substs) if !adt_def.is_union() => { // First check if this ADT has a layout attribute (like `NonNull` and friends). use std::ops::Bound; - match tcx.layout_scalar_valid_range(adt_def.did()) { + match cx.tcx.layout_scalar_valid_range(adt_def.did()) { // We exploit here that `layout_scalar_valid_range` will never // return `Bound::Excluded`. (And we have tests checking that we // handle the attribute correctly.) @@ -2603,12 +2603,12 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { // Proceed recursively, check all fields. let variant = &adt_def.variant(VariantIdx::from_u32(0)); variant.fields.iter().find_map(|field| { - ty_find_init_error(tcx, field.ty(tcx, substs), init).map( + ty_find_init_error(cx, field.ty(cx.tcx, substs), init).map( |(mut msg, span)| { if span.is_none() { // Point to this field, should be helpful for figuring // out where the source of the error is. - let span = tcx.def_span(field.did); + let span = cx.tcx.def_span(field.did); write!( &mut msg, " (in this {} field)", @@ -2627,7 +2627,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { // Multi-variant enum. _ => { if init == InitKind::Uninit && is_multi_variant(*adt_def) { - let span = tcx.def_span(adt_def.did()); + let span = cx.tcx.def_span(adt_def.did()); Some(( "enums have to be initialized to a variant".to_string(), Some(span), @@ -2642,7 +2642,16 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { } Tuple(..) => { // Proceed recursively, check all fields. - ty.tuple_fields().iter().find_map(|field| ty_find_init_error(tcx, field, init)) + ty.tuple_fields().iter().find_map(|field| ty_find_init_error(cx, field, init)) + } + Array(ty, len) => { + if matches!(len.try_eval_usize(cx.tcx, cx.param_env), Some(v) if v > 0) { + // Array length known at array non-empty -- recurse. + ty_find_init_error(cx, *ty, init) + } else { + // Empty array or size unknown. + None + } } // Conservative fallback. _ => None, @@ -2655,7 +2664,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { // We are extremely conservative with what we warn about. let conjured_ty = cx.typeck_results().expr_ty(expr); if let Some((msg, span)) = - with_no_trimmed_paths!(ty_find_init_error(cx.tcx, conjured_ty, init)) + with_no_trimmed_paths!(ty_find_init_error(cx, conjured_ty, init)) { cx.struct_span_lint(INVALID_VALUE, expr.span, |lint| { let mut err = lint.build(&format!( diff --git a/src/test/ui/lint/uninitialized-zeroed.rs b/src/test/ui/lint/uninitialized-zeroed.rs index 122933c3c4e46..5cd323c01db8c 100644 --- a/src/test/ui/lint/uninitialized-zeroed.rs +++ b/src/test/ui/lint/uninitialized-zeroed.rs @@ -81,6 +81,9 @@ fn main() { let _val: *const dyn Send = mem::zeroed(); //~ ERROR: does not permit zero-initialization let _val: *const dyn Send = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: [fn(); 2] = mem::zeroed(); //~ ERROR: does not permit zero-initialization + let _val: [fn(); 2] = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + // Things that can be zero, but not uninit. let _val: bool = mem::zeroed(); let _val: bool = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized @@ -94,6 +97,9 @@ fn main() { let _val: Fruit = mem::zeroed(); let _val: Fruit = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: [bool; 2] = mem::zeroed(); + let _val: [bool; 2] = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + // Transmute-from-0 let _val: &'static i32 = mem::transmute(0usize); //~ ERROR: does not permit zero-initialization let _val: &'static [i32] = mem::transmute((0usize, 0usize)); //~ ERROR: does not permit zero-initialization @@ -110,6 +116,8 @@ fn main() { let _val: MaybeUninit<&'static i32> = mem::zeroed(); let _val: i32 = mem::zeroed(); let _val: bool = MaybeUninit::zeroed().assume_init(); + let _val: [bool; 0] = MaybeUninit::uninit().assume_init(); + let _val: [!; 0] = MaybeUninit::zeroed().assume_init(); // Some things that happen to work due to rustc implementation details, // but are not guaranteed to keep working. let _val: i32 = mem::uninitialized(); diff --git a/src/test/ui/lint/uninitialized-zeroed.stderr b/src/test/ui/lint/uninitialized-zeroed.stderr index 0af185ef61b5e..b6a66f0a95ad1 100644 --- a/src/test/ui/lint/uninitialized-zeroed.stderr +++ b/src/test/ui/lint/uninitialized-zeroed.stderr @@ -329,8 +329,30 @@ LL | let _val: *const dyn Send = mem::uninitialized(); | = note: the vtable of a wide raw pointer must be non-null +error: the type `[fn(); 2]` does not permit zero-initialization + --> $DIR/uninitialized-zeroed.rs:84:31 + | +LL | let _val: [fn(); 2] = mem::zeroed(); + | ^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done + | + = note: function pointers must be non-null + +error: the type `[fn(); 2]` does not permit being left uninitialized + --> $DIR/uninitialized-zeroed.rs:85:31 + | +LL | let _val: [fn(); 2] = mem::uninitialized(); + | ^^^^^^^^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done + | + = note: function pointers must be non-null + error: the type `bool` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:86:26 + --> $DIR/uninitialized-zeroed.rs:89:26 | LL | let _val: bool = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -341,7 +363,7 @@ LL | let _val: bool = mem::uninitialized(); = note: booleans must be either `true` or `false` error: the type `Wrap` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:89:32 + --> $DIR/uninitialized-zeroed.rs:92:32 | LL | let _val: Wrap = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -356,7 +378,7 @@ LL | struct Wrap { wrapped: T } | ^^^^^^^^^^ error: the type `NonBig` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:92:28 + --> $DIR/uninitialized-zeroed.rs:95:28 | LL | let _val: NonBig = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -367,7 +389,7 @@ LL | let _val: NonBig = mem::uninitialized(); = note: `NonBig` must be initialized inside its custom valid range error: the type `Fruit` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:95:27 + --> $DIR/uninitialized-zeroed.rs:98:27 | LL | let _val: Fruit = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -384,8 +406,19 @@ LL | | Banana, LL | | } | |_^ +error: the type `[bool; 2]` does not permit being left uninitialized + --> $DIR/uninitialized-zeroed.rs:101:31 + | +LL | let _val: [bool; 2] = mem::uninitialized(); + | ^^^^^^^^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done + | + = note: booleans must be either `true` or `false` + error: the type `&i32` does not permit zero-initialization - --> $DIR/uninitialized-zeroed.rs:98:34 + --> $DIR/uninitialized-zeroed.rs:104:34 | LL | let _val: &'static i32 = mem::transmute(0usize); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -396,7 +429,7 @@ LL | let _val: &'static i32 = mem::transmute(0usize); = note: references must be non-null error: the type `&[i32]` does not permit zero-initialization - --> $DIR/uninitialized-zeroed.rs:99:36 + --> $DIR/uninitialized-zeroed.rs:105:36 | LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -407,7 +440,7 @@ LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize)); = note: references must be non-null error: the type `NonZeroU32` does not permit zero-initialization - --> $DIR/uninitialized-zeroed.rs:100:32 + --> $DIR/uninitialized-zeroed.rs:106:32 | LL | let _val: NonZeroU32 = mem::transmute(0); | ^^^^^^^^^^^^^^^^^ @@ -418,7 +451,7 @@ LL | let _val: NonZeroU32 = mem::transmute(0); = note: `std::num::NonZeroU32` must be non-null error: the type `NonNull` does not permit zero-initialization - --> $DIR/uninitialized-zeroed.rs:103:34 + --> $DIR/uninitialized-zeroed.rs:109:34 | LL | let _val: NonNull = MaybeUninit::zeroed().assume_init(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -429,7 +462,7 @@ LL | let _val: NonNull = MaybeUninit::zeroed().assume_init(); = note: `std::ptr::NonNull` must be non-null error: the type `NonNull` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:104:34 + --> $DIR/uninitialized-zeroed.rs:110:34 | LL | let _val: NonNull = MaybeUninit::uninit().assume_init(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -440,7 +473,7 @@ LL | let _val: NonNull = MaybeUninit::uninit().assume_init(); = note: `std::ptr::NonNull` must be non-null error: the type `bool` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:105:26 + --> $DIR/uninitialized-zeroed.rs:111:26 | LL | let _val: bool = MaybeUninit::uninit().assume_init(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -450,5 +483,5 @@ LL | let _val: bool = MaybeUninit::uninit().assume_init(); | = note: booleans must be either `true` or `false` -error: aborting due to 36 previous errors +error: aborting due to 39 previous errors From f793b696c8080e0e23060c74659ab5d04240fa38 Mon Sep 17 00:00:00 2001 From: jam1garner <8260240+jam1garner@users.noreply.github.com> Date: Fri, 1 Apr 2022 11:28:45 -0400 Subject: [PATCH 15/15] Reword purpose description of noreturn in naked function --- compiler/rustc_passes/src/naked_functions.rs | 2 +- src/test/ui/asm/naked-functions.stderr | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index 30db0cec0804a..02f6b4060599e 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -289,7 +289,7 @@ impl<'tcx> CheckInlineAssembly<'tcx> { .span_suggestion( last_span, "consider specifying that the asm block is responsible \ - for returning, if desired", + for returning from the function", String::from(", options(noreturn)"), Applicability::MachineApplicable, ) diff --git a/src/test/ui/asm/naked-functions.stderr b/src/test/ui/asm/naked-functions.stderr index edaecb78b2c56..35dc9cca33b5a 100644 --- a/src/test/ui/asm/naked-functions.stderr +++ b/src/test/ui/asm/naked-functions.stderr @@ -98,7 +98,7 @@ LL | | sym G, LL | | ); | |_____^ | -help: consider specifying that the asm block is responsible for returning, if desired +help: consider specifying that the asm block is responsible for returning from the function | LL | sym G, options(noreturn), | +++++++++++++++++++ @@ -137,7 +137,7 @@ error[E0787]: asm in naked functions must use `noreturn` option LL | asm!(""); | ^^^^^^^^ | -help: consider specifying that the asm block is responsible for returning, if desired +help: consider specifying that the asm block is responsible for returning from the function | LL | asm!("", options(noreturn)); | +++++++++++++++++++ @@ -148,7 +148,7 @@ error[E0787]: asm in naked functions must use `noreturn` option LL | asm!(""); | ^^^^^^^^ | -help: consider specifying that the asm block is responsible for returning, if desired +help: consider specifying that the asm block is responsible for returning from the function | LL | asm!("", options(noreturn)); | +++++++++++++++++++ @@ -159,7 +159,7 @@ error[E0787]: asm in naked functions must use `noreturn` option LL | asm!(""); | ^^^^^^^^ | -help: consider specifying that the asm block is responsible for returning, if desired +help: consider specifying that the asm block is responsible for returning from the function | LL | asm!("", options(noreturn)); | +++++++++++++++++++ @@ -219,7 +219,7 @@ error[E0787]: asm in naked functions must use `noreturn` option LL | asm!("", options(readonly, nostack), options(pure)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: consider specifying that the asm block is responsible for returning, if desired +help: consider specifying that the asm block is responsible for returning from the function | LL | asm!("", options(noreturn), options(readonly, nostack), options(pure)); | +++++++++++++++++++