]> git.lizzy.rs Git - rust.git/commitdiff
Require stable/unstable annotations for the constness of all stable functions with...
authorOliver Scherer <github35764891676564198441@oli-obk.de>
Sun, 8 Dec 2019 00:43:10 +0000 (01:43 +0100)
committerOliver Scherer <github35764891676564198441@oli-obk.de>
Fri, 13 Dec 2019 10:27:02 +0000 (11:27 +0100)
58 files changed:
src/liballoc/collections/linked_list.rs
src/liballoc/string.rs
src/liballoc/vec.rs
src/libcore/alloc.rs
src/libcore/any.rs
src/libcore/cell.rs
src/libcore/char/methods.rs
src/libcore/convert/mod.rs
src/libcore/intrinsics.rs
src/libcore/iter/sources.rs
src/libcore/mem/manually_drop.rs
src/libcore/mem/maybe_uninit.rs
src/libcore/mem/mod.rs
src/libcore/num/mod.rs
src/libcore/num/wrapping.rs
src/libcore/ops/range.rs
src/libcore/ptr/mod.rs
src/libcore/ptr/non_null.rs
src/libcore/slice/mod.rs
src/libcore/str/mod.rs
src/libcore/sync/atomic.rs
src/libcore/task/wake.rs
src/libcore/time.rs
src/librustc/middle/stability.rs
src/librustc/query/mod.rs
src/librustc/ty/constness.rs
src/librustc/ty/context.rs
src/librustc_feature/builtin_attrs.rs
src/librustc_metadata/rmeta/decoder.rs
src/librustc_metadata/rmeta/decoder/cstore_impl.rs
src/librustc_metadata/rmeta/encoder.rs
src/librustc_metadata/rmeta/mod.rs
src/libstd/ffi/c_str.rs
src/libstd/net/ip.rs
src/libstd/sync/once.rs
src/libsyntax/attr/builtin.rs
src/libsyntax_expand/base.rs
src/libsyntax_pos/symbol.rs
src/test/ui/consts/auxiliary/promotable_const_fn_lib.rs
src/test/ui/consts/const-eval/auxiliary/stability.rs
src/test/ui/consts/const-eval/dont_promote_unstable_const_fn.rs
src/test/ui/consts/min_const_fn/allow_const_fn_ptr.rs
src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr
src/test/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs
src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs
src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr
src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs
src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr
src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.rs
src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.stderr
src/test/ui/consts/unstable-const-fn-in-libcore.rs
src/test/ui/feature-gate/allow-features-empty.stderr
src/test/ui/feature-gate/allow-features.stderr
src/test/ui/feature-gates/feature-gate-rustc_const_unstable.stderr
src/test/ui/invalid_const_promotion.rs
src/test/ui/stability-attribute/stability-attribute-sanity.rs
src/test/ui/stability-attribute/stability-attribute-sanity.stderr
src/tools/tidy/src/error_codes_check.rs

index 6ee22834a460e72b124a9c2c81ea3294f12b5812..4a74a479e71bb8cff582404dbb4e18af96e0c387 100644 (file)
@@ -275,6 +275,10 @@ impl<T> LinkedList<T> {
     /// let list: LinkedList<u32> = LinkedList::new();
     /// ```
     #[inline]
+    #[cfg_attr(
+        not(bootstrap),
+        rustc_const_stable(feature = "const_linked_list_new", since = "1.32.0"),
+    )]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const fn new() -> Self {
         LinkedList {
index f7dff4c21f7c4343bdb79759ecf7a4755d38b720..bf9bbba47535d9f55e9d39fffa0f79a5b1c07af1 100644 (file)
@@ -367,6 +367,10 @@ impl String {
     /// let s = String::new();
     /// ```
     #[inline]
+    #[cfg_attr(
+        not(bootstrap),
+        rustc_const_stable(feature = "const_string_new", since = "1.32.0"),
+    )]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const fn new() -> String {
         String { vec: Vec::new() }
index 6e165ccb91998a7eb37b64ead5f6961445332723..52b45b0b8fe079ded0a0182b357462c659465eeb 100644 (file)
@@ -315,6 +315,10 @@ impl<T> Vec<T> {
     /// let mut vec: Vec<i32> = Vec::new();
     /// ```
     #[inline]
+    #[cfg_attr(
+        not(bootstrap),
+        rustc_const_stable(feature = "const_vec_new", since = "1.32.0"),
+    )]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const fn new() -> Vec<T> {
         Vec {
index 5c24e3d8f5d5ac5b6034a07b65e561bd79950a0a..71517ffb0065e4e4df0a05a00c7f478de9a0e670 100644 (file)
@@ -100,6 +100,7 @@ pub fn from_size_align(size: usize, align: usize) -> Result<Self, LayoutErr> {
     /// This function is unsafe as it does not verify the preconditions from
     /// [`Layout::from_size_align`](#method.from_size_align).
     #[stable(feature = "alloc_layout", since = "1.28.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "alloc_layout", since = "1.28.0"))]
     #[inline]
     pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
         Layout { size_: size, align_: NonZeroUsize::new_unchecked(align) }
index 466750fc7d2c63035f6f4cc46cba596ccf5827fe..b0e3021e0bf4dc839431d3c12fc75276d9191587 100644 (file)
@@ -423,7 +423,8 @@ impl TypeId {
     /// assert_eq!(is_string(&"cookie monster".to_string()), true);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature="const_type_id")]
+    #[cfg_attr(bootstrap, rustc_const_unstable(feature="const_type_id"))]
+    #[cfg_attr(not(bootstrap), rustc_const_unstable(feature="const_type_id", issue = "41875"))]
     pub const fn of<T: ?Sized + 'static>() -> TypeId {
         TypeId {
             #[cfg(bootstrap)]
@@ -461,7 +462,8 @@ pub const fn of<T: ?Sized + 'static>() -> TypeId {
 /// );
 /// ```
 #[stable(feature = "type_name", since = "1.38.0")]
-#[rustc_const_unstable(feature = "const_type_name")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_type_name"))]
+#[cfg_attr(not(bootstrap), rustc_const_unstable(feature = "const_type_name", issue = "63084"))]
 pub const fn type_name<T: ?Sized>() -> &'static str {
     intrinsics::type_name::<T>()
 }
@@ -499,7 +501,8 @@ pub const fn type_name<T: ?Sized>() -> &'static str {
 /// println!("{}", type_name_of_val(&y));
 /// ```
 #[unstable(feature = "type_name_of_val", issue = "66359")]
-#[rustc_const_unstable(feature = "const_type_name")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_type_name"))]
+#[cfg_attr(not(bootstrap), rustc_const_unstable(feature = "const_type_name", issue = "63084"))]
 pub const fn type_name_of_val<T: ?Sized>(val: &T) -> &'static str {
     let _ = val;
     type_name::<T>()
index 03f32e726187b09ea86af46601df58465cd16c31..e4b4cd31c63aff040cb6c849aef456e478e93cdf 100644 (file)
@@ -324,6 +324,7 @@ impl<T> Cell<T> {
     /// let c = Cell::new(5);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_cell_new", since = "1.32.0"))]
     #[inline]
     pub const fn new(value: T) -> Cell<T> {
         Cell {
@@ -469,6 +470,7 @@ impl<T: ?Sized> Cell<T> {
     /// ```
     #[inline]
     #[stable(feature = "cell_as_ptr", since = "1.12.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_cell_as_ptr", since = "1.32.0"))]
     pub const fn as_ptr(&self) -> *mut T {
         self.value.get()
     }
@@ -649,6 +651,7 @@ impl<T> RefCell<T> {
     /// let c = RefCell::new(5);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_refcell_new", since = "1.32.0"))]
     #[inline]
     pub const fn new(value: T) -> RefCell<T> {
         RefCell {
@@ -1501,6 +1504,10 @@ impl<T> UnsafeCell<T> {
     /// let uc = UnsafeCell::new(5);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(
+        not(bootstrap),
+        rustc_const_stable(feature = "const_unsafe_cell_new", since = "1.32.0"),
+    )]
     #[inline]
     pub const fn new(value: T) -> UnsafeCell<T> {
         UnsafeCell { value }
@@ -1543,6 +1550,10 @@ impl<T: ?Sized> UnsafeCell<T> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(
+        not(bootstrap),
+        rustc_const_stable(feature = "const_unsafecell_get", since = "1.32.0"),
+    )]
     pub const fn get(&self) -> *mut T {
         // We can just cast the pointer from `UnsafeCell<T>` to `T` because of
         // #[repr(transparent)]. This exploits libstd's special status, there is
index 5c63eebf595f9e59d32690b46488513db72ddade..5cfb9583a86d135ef1735f485de8c267377ddf13 100644 (file)
@@ -911,6 +911,10 @@ pub fn to_uppercase(self) -> ToUppercase {
     /// assert!(!non_ascii.is_ascii());
     /// ```
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
+    #[cfg_attr(
+        not(bootstrap),
+        rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.32.0"),
+    )]
     #[inline]
     pub const fn is_ascii(&self) -> bool {
         *self as u32 <= 0x7F
index 5414d9ac2344ab25a287596a97ba973d5cf9c672..27d78b55a7580b6a80bf25e127de2f6138a78663 100644 (file)
@@ -99,6 +99,7 @@
 /// assert_eq!(vec![1, 3], filtered);
 /// ```
 #[stable(feature = "convert_id", since = "1.33.0")]
+#[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_identity", since = "1.33.0"))]
 #[inline]
 pub const fn identity<T>(x: T) -> T {
     x
index 18aae59573d7d56a0707f586617bf86570a816ad..1f72b7ab0902d0e5e1864eff1e1b9f9b2aab862a 100644 (file)
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_transmute")]
+    #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_transmute"))]
+    #[cfg_attr(
+        not(bootstrap),
+        rustc_const_unstable(feature = "const_transmute", issue = "53605"),
+    )]
     pub fn transmute<T, U>(e: T) -> U;
 
     /// Returns `true` if the actual type given as `T` requires drop
index ffac7d4e995389981fcb65d557cba78457751df4..127b778e62e68e87d8559445347c5ea5e727b164 100644 (file)
@@ -281,6 +281,7 @@ fn default() -> Empty<T> {
 /// assert_eq!(None, nope.next());
 /// ```
 #[stable(feature = "iter_empty", since = "1.2.0")]
+#[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_iter_empty", since = "1.32.0"))]
 pub const fn empty<T>() -> Empty<T> {
     Empty(marker::PhantomData)
 }
index 34fc0618ea2ae182655e4db3e02b95a2ef9c846f..6463668a03e3d411384d76637d5dc5e287085318 100644 (file)
@@ -63,6 +63,10 @@ impl<T> ManuallyDrop<T> {
     /// ManuallyDrop::new(Box::new(()));
     /// ```
     #[stable(feature = "manually_drop", since = "1.20.0")]
+    #[cfg_attr(
+        not(bootstrap),
+        rustc_const_stable(feature = "const_manually_drop", since = "1.36.0"),
+    )]
     #[inline(always)]
     pub const fn new(value: T) -> ManuallyDrop<T> {
         ManuallyDrop { value }
@@ -80,6 +84,10 @@ pub const fn new(value: T) -> ManuallyDrop<T> {
     /// let _: Box<()> = ManuallyDrop::into_inner(x); // This drops the `Box`.
     /// ```
     #[stable(feature = "manually_drop", since = "1.20.0")]
+    #[cfg_attr(
+        not(bootstrap),
+        rustc_const_stable(feature = "const_manually_drop", since = "1.36.0"),
+    )]
     #[inline(always)]
     pub const fn into_inner(slot: ManuallyDrop<T>) -> T {
         slot.value
index 6661df2ae0d8414c4a17e27102fc3b4d7acf345f..670a194e2d6cce3e560c78da0772bda3dcef9c8a 100644 (file)
@@ -250,6 +250,10 @@ impl<T> MaybeUninit<T> {
     ///
     /// [`assume_init`]: #method.assume_init
     #[stable(feature = "maybe_uninit", since = "1.36.0")]
+    #[cfg_attr(
+        not(bootstrap),
+        rustc_const_stable(feature = "const_maybe_uninit", since = "1.36.0"),
+    )]
     #[inline(always)]
     pub const fn new(val: T) -> MaybeUninit<T> {
         MaybeUninit { value: ManuallyDrop::new(val) }
@@ -264,6 +268,10 @@ pub const fn new(val: T) -> MaybeUninit<T> {
     ///
     /// [type]: union.MaybeUninit.html
     #[stable(feature = "maybe_uninit", since = "1.36.0")]
+    #[cfg_attr(
+        not(bootstrap),
+        rustc_const_stable(feature = "const_maybe_uninit", since = "1.36.0"),
+    )]
     #[inline(always)]
     #[cfg_attr(all(not(bootstrap)), rustc_diagnostic_item = "maybe_uninit_uninit")]
     pub const fn uninit() -> MaybeUninit<T> {
index bba441464ff35bf22452748bd111b82829249b00..c50a8ad60002f8113d1aa4be39b3d89b2ed45097 100644 (file)
@@ -271,6 +271,7 @@ pub fn forget_unsized<T: ?Sized>(t: T) {
 #[inline(always)]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_promotable]
+#[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_size_of", since = "1.32.0"))]
 pub const fn size_of<T>() -> usize {
     intrinsics::size_of::<T>()
 }
@@ -371,6 +372,7 @@ pub fn min_align_of_val<T: ?Sized>(val: &T) -> usize {
 #[inline(always)]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_promotable]
+#[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_align_of", since = "1.32.0"))]
 pub const fn align_of<T>() -> usize {
     intrinsics::min_align_of::<T>()
 }
@@ -453,6 +455,7 @@ pub fn align_of_val<T: ?Sized>(val: &T) -> usize {
 /// ```
 #[inline]
 #[stable(feature = "needs_drop", since = "1.21.0")]
+#[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_needs_drop", since = "1.36.0"))]
 pub const fn needs_drop<T>() -> bool {
     intrinsics::needs_drop::<T>()
 }
index d1f518d52dd72735577a5450cbe8efed76ebb866..5a97aa4acfa4cd982b0455f0056b77ee5a9df61f 100644 (file)
@@ -60,6 +60,10 @@ impl $Ty {
                 ///
                 /// The value must not be zero.
                 #[$stability]
+                #[cfg_attr(
+                    not(bootstrap),
+                    rustc_const_stable(feature = "nonzero", since = "1.34.0"),
+                )]
                 #[inline]
                 pub const unsafe fn new_unchecked(n: $Int) -> Self {
                     $Ty(n)
@@ -80,6 +84,10 @@ pub fn new(n: $Int) -> Option<Self> {
                 /// Returns the value as a primitive type.
                 #[$stability]
                 #[inline]
+                #[cfg_attr(
+                    not(bootstrap),
+                    rustc_const_stable(feature = "nonzero", since = "1.34.0"),
+                )]
                 pub const fn get(self) -> $Int {
                     self.0
                 }
@@ -255,6 +263,10 @@ macro_rules! int_impl {
             #[stable(feature = "rust1", since = "1.0.0")]
             #[inline(always)]
             #[rustc_promotable]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_min_value", since = "1.32.0"),
+            )]
             pub const fn min_value() -> Self {
                 !0 ^ ((!0 as $UnsignedT) >> 1) as Self
             }
@@ -274,6 +286,10 @@ pub const fn min_value() -> Self {
             #[stable(feature = "rust1", since = "1.0.0")]
             #[inline(always)]
             #[rustc_promotable]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_max_value", since = "1.32.0"),
+            )]
             pub const fn max_value() -> Self {
                 !Self::min_value()
             }
@@ -323,6 +339,10 @@ pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
 ```
 "),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
         }
@@ -338,6 +358,10 @@ pub const fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
 ", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value().count_zeros(), 1);", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn count_zeros(self) -> u32 {
                 (!self).count_ones()
@@ -358,6 +382,10 @@ pub const fn count_zeros(self) -> u32 {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn leading_zeros(self) -> u32 {
                 (self as $UnsignedT).leading_zeros()
@@ -378,6 +406,10 @@ pub const fn leading_zeros(self) -> u32 {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn trailing_zeros(self) -> u32 {
                 (self as $UnsignedT).trailing_zeros()
@@ -401,6 +433,10 @@ pub const fn trailing_zeros(self) -> u32 {
 assert_eq!(n.rotate_left(", $rot, "), m);
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -427,6 +463,10 @@ pub const fn rotate_left(self, n: u32) -> Self {
 assert_eq!(n.rotate_right(", $rot, "), m);
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -450,6 +490,10 @@ pub const fn rotate_right(self, n: u32) -> Self {
 assert_eq!(m, ", $swapped, ");
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn swap_bytes(self) -> Self {
                 (self as $UnsignedT).swap_bytes() as Self
@@ -470,6 +514,10 @@ pub const fn swap_bytes(self) -> Self {
 assert_eq!(m, ", $reversed, ");
 ```"),
             #[stable(feature = "reverse_bits", since = "1.37.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[inline]
             #[must_use]
             pub const fn reverse_bits(self) -> Self {
@@ -497,6 +545,10 @@ pub const fn reverse_bits(self) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_conversions", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn from_be(x: Self) -> Self {
                 #[cfg(target_endian = "big")]
@@ -530,6 +582,10 @@ pub const fn from_be(x: Self) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_conversions", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn from_le(x: Self) -> Self {
                 #[cfg(target_endian = "little")]
@@ -563,6 +619,10 @@ pub const fn from_le(x: Self) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_conversions", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn to_be(self) -> Self { // or not to be?
                 #[cfg(target_endian = "big")]
@@ -596,6 +656,10 @@ pub const fn to_be(self) -> Self { // or not to be?
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_conversions", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn to_le(self) -> Self {
                 #[cfg(target_endian = "little")]
@@ -948,7 +1012,11 @@ pub fn checked_pow(self, mut exp: u32) -> Option<Self> {
 ```"),
 
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_saturating_int_methods")]
+            #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_saturating_int_methods"))]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_unstable(feature = "const_saturating_int_methods", issue = "53718"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -974,7 +1042,11 @@ pub const fn saturating_add(self, rhs: Self) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_saturating_int_methods")]
+            #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_saturating_int_methods"))]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_unstable(feature = "const_saturating_int_methods", issue = "53718"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -1114,6 +1186,10 @@ pub fn saturating_pow(self, exp: u32) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -1137,6 +1213,10 @@ pub const fn wrapping_add(self, rhs: Self) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -1159,6 +1239,10 @@ pub const fn wrapping_sub(self, rhs: Self) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -1303,6 +1387,10 @@ pub fn wrapping_rem_euclid(self, rhs: Self) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "num_wrapping", since = "1.2.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn wrapping_neg(self) -> Self {
                 self.overflowing_neg().0
@@ -1328,6 +1416,10 @@ pub const fn wrapping_neg(self) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "num_wrapping", since = "1.2.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -1359,6 +1451,10 @@ pub const fn wrapping_shl(self, rhs: u32) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "num_wrapping", since = "1.2.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -1392,6 +1488,10 @@ pub const fn wrapping_shr(self, rhs: u32) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "no_panic_abs", since = "1.13.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn wrapping_abs(self) -> Self {
                 // sign is -1 (all ones) for negative numbers, 0 otherwise.
@@ -1466,6 +1566,10 @@ pub fn wrapping_pow(self, mut exp: u32) -> Self {
 "::MIN, true));", $EndFeature, "
 ```"),
             #[stable(feature = "wrapping", since = "1.7.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -1493,6 +1597,10 @@ pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
 "::MAX, true));", $EndFeature, "
 ```"),
             #[stable(feature = "wrapping", since = "1.7.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -1518,6 +1626,10 @@ pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
 $EndFeature, "
 ```"),
             #[stable(feature = "wrapping", since = "1.7.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -1685,6 +1797,10 @@ pub fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
 ```"),
             #[inline]
             #[stable(feature = "wrapping", since = "1.7.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             pub const fn overflowing_neg(self) -> (Self, bool) {
                 ((!self).wrapping_add(1), self == Self::min_value())
             }
@@ -1707,6 +1823,10 @@ pub const fn overflowing_neg(self) -> (Self, bool) {
 $EndFeature, "
 ```"),
             #[stable(feature = "wrapping", since = "1.7.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -1732,6 +1852,10 @@ pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
 $EndFeature, "
 ```"),
             #[stable(feature = "wrapping", since = "1.7.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -1760,6 +1884,10 @@ pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
 $EndFeature, "
 ```"),
             #[stable(feature = "no_panic_abs", since = "1.13.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn overflowing_abs(self) -> (Self, bool) {
                 (self.wrapping_abs(), self == Self::min_value())
@@ -1964,6 +2092,10 @@ pub fn rem_euclid(self, rhs: Self) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[inline]
             #[rustc_inherit_overflow_checks]
             pub const fn abs(self) -> Self {
@@ -2006,7 +2138,11 @@ pub const fn abs(self) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_sign")]
+            #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_int_sign"))]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_unstable(feature = "const_int_sign", issue = "53718"),
+            )]
             #[inline]
             pub const fn signum(self) -> Self {
                 (self > 0) as Self - (self < 0) as Self
@@ -2027,6 +2163,10 @@ pub const fn signum(self) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn is_positive(self) -> bool { self > 0 }
         }
@@ -2045,6 +2185,10 @@ pub const fn is_positive(self) -> bool { self > 0 }
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_int_methods", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn is_negative(self) -> bool { self < 0 }
         }
@@ -2062,7 +2206,11 @@ pub const fn is_negative(self) -> bool { self < 0 }
 assert_eq!(bytes, ", $be_bytes, ");
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion")]
+            #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_int_conversion"))]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_unstable(feature = "const_int_conversion", issue = "53718"),
+            )]
             #[inline]
             pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
                 self.to_be().to_ne_bytes()
@@ -2082,7 +2230,11 @@ pub const fn is_negative(self) -> bool { self < 0 }
 assert_eq!(bytes, ", $le_bytes, ");
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion")]
+            #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_int_conversion"))]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_unstable(feature = "const_int_conversion", issue = "53718"),
+            )]
             #[inline]
             pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
                 self.to_le().to_ne_bytes()
@@ -2117,7 +2269,11 @@ pub const fn is_negative(self) -> bool { self < 0 }
 );
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion")]
+            #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_int_conversion"))]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_unstable(feature = "const_int_conversion", issue = "53718"),
+            )]
             #[inline]
             pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
                 // SAFETY: integers are plain old datatypes so we can always transmute them to
@@ -2151,7 +2307,11 @@ fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
 }
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion")]
+            #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_int_conversion"))]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_unstable(feature = "const_int_conversion", issue = "53718"),
+            )]
             #[inline]
             pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                 Self::from_be(Self::from_ne_bytes(bytes))
@@ -2184,7 +2344,11 @@ fn read_le_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
 }
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion")]
+            #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_int_conversion"))]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_unstable(feature = "const_int_conversion", issue = "53718"),
+            )]
             #[inline]
             pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                 Self::from_le(Self::from_ne_bytes(bytes))
@@ -2227,7 +2391,11 @@ fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
 }
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion")]
+            #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_int_conversion"))]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_unstable(feature = "const_int_conversion", issue = "53718"),
+            )]
             #[inline]
             pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                 // SAFETY: integers are plain old datatypes so we can always transmute to them
@@ -2321,6 +2489,10 @@ macro_rules! uint_impl {
             #[stable(feature = "rust1", since = "1.0.0")]
             #[rustc_promotable]
             #[inline(always)]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_min_value", since = "1.32.0"),
+            )]
             pub const fn min_value() -> Self { 0 }
         }
 
@@ -2338,6 +2510,10 @@ pub const fn min_value() -> Self { 0 }
             #[stable(feature = "rust1", since = "1.0.0")]
             #[rustc_promotable]
             #[inline(always)]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_max_value", since = "1.32.0"),
+            )]
             pub const fn max_value() -> Self { !0 }
         }
 
@@ -2384,6 +2560,10 @@ pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
 assert_eq!(n.count_ones(), 3);", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_math", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn count_ones(self) -> u32 {
                 intrinsics::ctpop(self as $ActualT) as u32
@@ -2401,6 +2581,10 @@ pub const fn count_ones(self) -> u32 {
 ", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value().count_zeros(), 0);", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_math", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn count_zeros(self) -> u32 {
                 (!self).count_ones()
@@ -2420,6 +2604,10 @@ pub const fn count_zeros(self) -> u32 {
 assert_eq!(n.leading_zeros(), 2);", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_math", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn leading_zeros(self) -> u32 {
                 intrinsics::ctlz(self as $ActualT) as u32
@@ -2440,6 +2628,10 @@ pub const fn leading_zeros(self) -> u32 {
 assert_eq!(n.trailing_zeros(), 3);", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_math", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn trailing_zeros(self) -> u32 {
                 intrinsics::cttz(self) as u32
@@ -2463,6 +2655,10 @@ pub const fn trailing_zeros(self) -> u32 {
 assert_eq!(n.rotate_left(", $rot, "), m);
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_math", since = "1.32.0"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -2489,6 +2685,10 @@ pub const fn rotate_left(self, n: u32) -> Self {
 assert_eq!(n.rotate_right(", $rot, "), m);
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_math", since = "1.32.0"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -2512,6 +2712,10 @@ pub const fn rotate_right(self, n: u32) -> Self {
 assert_eq!(m, ", $swapped, ");
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_math", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn swap_bytes(self) -> Self {
                 intrinsics::bswap(self as $ActualT) as Self
@@ -2532,6 +2736,10 @@ pub const fn swap_bytes(self) -> Self {
 assert_eq!(m, ", $reversed, ");
 ```"),
             #[stable(feature = "reverse_bits", since = "1.37.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_math", since = "1.32.0"),
+            )]
             #[inline]
             #[must_use]
             pub const fn reverse_bits(self) -> Self {
@@ -2559,6 +2767,10 @@ pub const fn reverse_bits(self) -> Self {
 }", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_math", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn from_be(x: Self) -> Self {
                 #[cfg(target_endian = "big")]
@@ -2592,6 +2804,10 @@ pub const fn from_be(x: Self) -> Self {
 }", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_math", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn from_le(x: Self) -> Self {
                 #[cfg(target_endian = "little")]
@@ -2625,6 +2841,10 @@ pub const fn from_le(x: Self) -> Self {
 }", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_math", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn to_be(self) -> Self { // or not to be?
                 #[cfg(target_endian = "big")]
@@ -2658,6 +2878,10 @@ pub const fn to_be(self) -> Self { // or not to be?
 }", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_math", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn to_le(self) -> Self {
                 #[cfg(target_endian = "little")]
@@ -2963,7 +3187,11 @@ pub fn checked_pow(self, mut exp: u32) -> Option<Self> {
             #[stable(feature = "rust1", since = "1.0.0")]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
-            #[rustc_const_unstable(feature = "const_saturating_int_methods")]
+            #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_saturating_int_methods"))]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_unstable(feature = "const_saturating_int_methods", issue = "53718"),
+            )]
             #[inline]
             pub const fn saturating_add(self, rhs: Self) -> Self {
                 intrinsics::saturating_add(self, rhs)
@@ -2985,7 +3213,11 @@ pub const fn saturating_add(self, rhs: Self) -> Self {
             #[stable(feature = "rust1", since = "1.0.0")]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
-            #[rustc_const_unstable(feature = "const_saturating_int_methods")]
+            #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_saturating_int_methods"))]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_unstable(feature = "const_saturating_int_methods", issue = "53718"),
+            )]
             #[inline]
             pub const fn saturating_sub(self, rhs: Self) -> Self {
                 intrinsics::saturating_sub(self, rhs)
@@ -3057,6 +3289,10 @@ pub fn saturating_pow(self, exp: u32) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -3079,6 +3315,10 @@ pub const fn wrapping_add(self, rhs: Self) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -3102,6 +3342,10 @@ pub const fn wrapping_sub(self, rhs: Self) -> Self {
         /// assert_eq!(25u8.wrapping_mul(12), 44);
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
+        #[cfg_attr(
+            not(bootstrap),
+            rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0"),
+        )]
         #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
         #[inline]
@@ -3231,6 +3475,10 @@ pub fn wrapping_rem_euclid(self, rhs: Self) -> Self {
         /// assert_eq!((-128i8).wrapping_neg(), -128);
         /// ```
         #[stable(feature = "num_wrapping", since = "1.2.0")]
+        #[cfg_attr(
+            not(bootstrap),
+            rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0"),
+        )]
         #[inline]
         pub const fn wrapping_neg(self) -> Self {
             self.overflowing_neg().0
@@ -3257,6 +3505,10 @@ pub const fn wrapping_neg(self) -> Self {
 assert_eq!(1", stringify!($SelfT), ".wrapping_shl(128), 1);", $EndFeature, "
 ```"),
             #[stable(feature = "num_wrapping", since = "1.2.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -3290,6 +3542,10 @@ pub const fn wrapping_shl(self, rhs: u32) -> Self {
 assert_eq!(128", stringify!($SelfT), ".wrapping_shr(128), 128);", $EndFeature, "
 ```"),
             #[stable(feature = "num_wrapping", since = "1.2.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -3359,6 +3615,10 @@ pub fn wrapping_pow(self, mut exp: u32) -> Self {
 assert_eq!(", stringify!($SelfT), "::MAX.overflowing_add(1), (0, true));", $EndFeature, "
 ```"),
             #[stable(feature = "wrapping", since = "1.7.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -3387,6 +3647,10 @@ pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
 $EndFeature, "
 ```"),
             #[stable(feature = "wrapping", since = "1.7.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -3414,6 +3678,10 @@ pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
         /// assert_eq!(1_000_000_000u32.overflowing_mul(10), (1410065408, true));
         /// ```
         #[stable(feature = "wrapping", since = "1.7.0")]
+        #[cfg_attr(
+            not(bootstrap),
+            rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0"),
+        )]
         #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
         #[inline]
@@ -3559,6 +3827,10 @@ pub fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
 ```"),
             #[inline]
             #[stable(feature = "wrapping", since = "1.7.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0"),
+            )]
             pub const fn overflowing_neg(self) -> (Self, bool) {
                 ((!self).wrapping_add(1), self != 0)
             }
@@ -3582,6 +3854,10 @@ pub const fn overflowing_neg(self) -> (Self, bool) {
 assert_eq!(0x1", stringify!($SelfT), ".overflowing_shl(132), (0x10, true));", $EndFeature, "
 ```"),
             #[stable(feature = "wrapping", since = "1.7.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -3608,6 +3884,10 @@ pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
 assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(132), (0x1, true));", $EndFeature, "
 ```"),
             #[stable(feature = "wrapping", since = "1.7.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0"),
+            )]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -3773,6 +4053,10 @@ pub fn rem_euclid(self, rhs: Self) -> Self {
 assert!(!10", stringify!($SelfT), ".is_power_of_two());", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_is_power_of_two", since = "1.32.0"),
+            )]
             #[inline]
             pub const fn is_power_of_two(self) -> bool {
                 self.count_ones() == 1
@@ -3884,7 +4168,11 @@ pub fn wrapping_next_power_of_two(self) -> Self {
 assert_eq!(bytes, ", $be_bytes, ");
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion")]
+            #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_int_conversion"))]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_unstable(feature = "const_int_conversion", issue = "53718"),
+            )]
             #[inline]
             pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
                 self.to_be().to_ne_bytes()
@@ -3904,7 +4192,11 @@ pub fn wrapping_next_power_of_two(self) -> Self {
 assert_eq!(bytes, ", $le_bytes, ");
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion")]
+            #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_int_conversion"))]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_unstable(feature = "const_int_conversion", issue = "53718"),
+            )]
             #[inline]
             pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
                 self.to_le().to_ne_bytes()
@@ -3939,7 +4231,11 @@ pub fn wrapping_next_power_of_two(self) -> Self {
 );
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion")]
+            #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_int_conversion"))]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_unstable(feature = "const_int_conversion", issue = "53718"),
+            )]
             #[inline]
             pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
                 // SAFETY: integers are plain old datatypes so we can always transmute them to
@@ -3973,7 +4269,11 @@ fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
 }
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion")]
+            #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_int_conversion"))]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_unstable(feature = "const_int_conversion", issue = "53718"),
+            )]
             #[inline]
             pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                 Self::from_be(Self::from_ne_bytes(bytes))
@@ -4006,7 +4306,11 @@ fn read_le_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
 }
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion")]
+            #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_int_conversion"))]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_unstable(feature = "const_int_conversion", issue = "53718"),
+            )]
             #[inline]
             pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                 Self::from_le(Self::from_ne_bytes(bytes))
@@ -4049,7 +4353,11 @@ fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
 }
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion")]
+            #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_int_conversion"))]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_unstable(feature = "const_int_conversion", issue = "53718"),
+            )]
             #[inline]
             pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                 // SAFETY: integers are plain old datatypes so we can always transmute to them
index 0ddfbd02aa5b02250b453f8d5e31dc10da69130a..46398dd2f82edabc4cf0d6d7050d8df669177c3a 100644 (file)
@@ -530,6 +530,10 @@ pub const fn swap_bytes(self) -> Self {
             /// assert_eq!(m, Wrapping(-22016));
             /// ```
             #[stable(feature = "reverse_bits", since = "1.37.0")]
+            #[cfg_attr(
+                not(bootstrap),
+                rustc_const_stable(feature = "const_reverse_bits", since = "1.37.0"),
+            )]
             #[inline]
             #[must_use]
             pub const fn reverse_bits(self) -> Self {
index a2250337a4dcab131b63c2c3590e2d535f0490c4..54ce2917a368a68cf8d7c13ae17c623cd33f8cfa 100644 (file)
@@ -398,6 +398,7 @@ impl<Idx> RangeInclusive<Idx> {
     #[stable(feature = "inclusive_range_methods", since = "1.27.0")]
     #[inline]
     #[rustc_promotable]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_range_new", since = "1.32.0"))]
     pub const fn new(start: Idx, end: Idx) -> Self {
         Self { start, end, is_empty: None }
     }
@@ -421,6 +422,10 @@ pub const fn new(start: Idx, end: Idx) -> Self {
     /// assert_eq!((3..=5).start(), &3);
     /// ```
     #[stable(feature = "inclusive_range_methods", since = "1.27.0")]
+    #[cfg_attr(
+        not(bootstrap),
+        rustc_const_stable(feature = "const_inclusive_range_methods", since = "1.32.0"),
+    )]
     #[inline]
     pub const fn start(&self) -> &Idx {
         &self.start
@@ -445,6 +450,10 @@ pub const fn start(&self) -> &Idx {
     /// assert_eq!((3..=5).end(), &5);
     /// ```
     #[stable(feature = "inclusive_range_methods", since = "1.27.0")]
+    #[cfg_attr(
+        not(bootstrap),
+        rustc_const_stable(feature = "const_inclusive_range_methods", since = "1.32.0"),
+    )]
     #[inline]
     pub const fn end(&self) -> &Idx {
         &self.end
index 24ffa3483298bdf985d3f693812b436f2f132ba4..33c23233fd1c26dab8c0e212b645bd119e54d03a 100644 (file)
@@ -198,6 +198,7 @@ unsafe fn real_drop_in_place<T: ?Sized>(to_drop: &mut T) {
 #[inline(always)]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_promotable]
+#[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_ptr_null", since = "1.32.0"))]
 pub const fn null<T>() -> *const T {
     0 as *const T
 }
@@ -215,6 +216,7 @@ pub const fn null<T>() -> *const T {
 #[inline(always)]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_promotable]
+#[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_ptr_null", since = "1.32.0"))]
 pub const fn null_mut<T>() -> *mut T {
     0 as *mut T
 }
@@ -1060,6 +1062,7 @@ pub fn is_null(self) -> bool {
 
     /// Casts to a pointer of another type.
     #[stable(feature = "ptr_cast", since = "1.38.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_ptr_cast", since = "1.38.0"))]
     #[inline]
     pub const fn cast<U>(self) -> *const U {
         self as _
@@ -1307,7 +1310,11 @@ pub fn wrapping_offset(self, count: isize) -> *const T
     /// }
     /// ```
     #[unstable(feature = "ptr_offset_from", issue = "41079")]
-    #[rustc_const_unstable(feature = "const_ptr_offset_from")]
+    #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_ptr_offset_from"))]
+    #[cfg_attr(
+        not(bootstrap),
+        rustc_const_unstable(feature = "const_ptr_offset_from", issue = "41079"),
+    )]
     #[inline]
     pub const unsafe fn offset_from(self, origin: *const T) -> isize
     where
@@ -1763,6 +1770,7 @@ pub fn is_null(self) -> bool {
 
     /// Casts to a pointer of another type.
     #[stable(feature = "ptr_cast", since = "1.38.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_ptr_cast", since = "1.38.0"))]
     #[inline]
     pub const fn cast<U>(self) -> *mut U {
         self as _
@@ -2049,7 +2057,11 @@ pub unsafe fn as_mut<'a>(self) -> Option<&'a mut T> {
     /// }
     /// ```
     #[unstable(feature = "ptr_offset_from", issue = "41079")]
-    #[rustc_const_unstable(feature = "const_ptr_offset_from")]
+    #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_ptr_offset_from"))]
+    #[cfg_attr(
+        not(bootstrap),
+        rustc_const_unstable(feature = "const_ptr_offset_from", issue = "41079"),
+    )]
     #[inline]
     pub const unsafe fn offset_from(self, origin: *const T) -> isize
     where
index a121389bef3c9e5ad0bdfc56d963601fa7cc9b44..d1d97d7b332fa36417515b7fecc3312cfd4d7e00 100644 (file)
@@ -66,6 +66,10 @@ impl<T: Sized> NonNull<T> {
     /// sentinel value. Types that lazily allocate must track initialization by
     /// some other means.
     #[stable(feature = "nonnull", since = "1.25.0")]
+    #[cfg_attr(
+        not(bootstrap),
+        rustc_const_stable(feature = "const_nonnull_dangling", since = "1.32.0"),
+    )]
     #[inline]
     pub const fn dangling() -> Self {
         unsafe {
@@ -82,6 +86,10 @@ impl<T: ?Sized> NonNull<T> {
     ///
     /// `ptr` must be non-null.
     #[stable(feature = "nonnull", since = "1.25.0")]
+    #[cfg_attr(
+        not(bootstrap),
+        rustc_const_stable(feature = "const_nonnull_new_unchecked", since = "1.32.0"),
+    )]
     #[inline]
     pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
         NonNull { pointer: ptr as _ }
@@ -96,6 +104,10 @@ pub fn new(ptr: *mut T) -> Option<Self> {
 
     /// Acquires the underlying `*mut` pointer.
     #[stable(feature = "nonnull", since = "1.25.0")]
+    #[cfg_attr(
+        not(bootstrap),
+        rustc_const_stable(feature = "const_nonnull_as_ptr", since = "1.32.0"),
+    )]
     #[inline]
     pub const fn as_ptr(self) -> *mut T {
         self.pointer as *mut T
@@ -125,6 +137,10 @@ pub unsafe fn as_mut(&mut self) -> &mut T {
 
     /// Casts to a pointer of another type.
     #[stable(feature = "nonnull_cast", since = "1.27.0")]
+    #[cfg_attr(
+        not(bootstrap),
+        rustc_const_stable(feature = "const_nonnull_cast", since = "1.32.0"),
+    )]
     #[inline]
     pub const fn cast<U>(self) -> NonNull<U> {
         unsafe { NonNull::new_unchecked(self.as_ptr() as *mut U) }
index c8fe9f98613150f2bf31d03e25b5d97d3d575e5d..a8e500d256fdc263a30ce0223a8bf207a331fc0e 100644 (file)
@@ -62,6 +62,7 @@ impl<T> [T] {
     /// assert_eq!(a.len(), 3);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_slice_len", since = "1.32.0"))]
     #[inline]
     // SAFETY: const sound because we transmute out the length field as a usize (which it must be)
     #[allow(unused_attributes)]
@@ -81,6 +82,10 @@ pub const fn len(&self) -> usize {
     /// assert!(!a.is_empty());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(
+        not(bootstrap),
+        rustc_const_stable(feature = "const_slice_is_empty", since = "1.32.0"),
+    )]
     #[inline]
     pub const fn is_empty(&self) -> bool {
         self.len() == 0
@@ -376,6 +381,10 @@ pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
     ///
     /// [`as_mut_ptr`]: #method.as_mut_ptr
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(
+        not(bootstrap),
+        rustc_const_stable(feature = "const_slice_as_ptr", since = "1.32.0"),
+    )]
     #[inline]
     pub const fn as_ptr(&self) -> *const T {
         self as *const [T] as *const T
index b2a420f3c43778cc06d992c62dbaaa89410f931a..6d225a25f20abed4d86d90381a1f4267e7feeff2 100644 (file)
@@ -2090,6 +2090,7 @@ impl str {
     /// assert_eq!("Æ’oo".chars().count(), 3);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_str_len", since = "1.32.0"))]
     #[inline]
     pub const fn len(&self) -> usize {
         self.as_bytes().len()
@@ -2110,6 +2111,10 @@ pub const fn len(&self) -> usize {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(
+        not(bootstrap),
+        rustc_const_stable(feature = "const_str_is_empty", since = "1.32.0"),
+    )]
     pub const fn is_empty(&self) -> bool {
         self.len() == 0
     }
@@ -2166,6 +2171,7 @@ pub fn is_char_boundary(&self, index: usize) -> bool {
     /// assert_eq!(b"bors", bytes);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "str_as_bytes", since = "1.32.0"))]
     #[inline(always)]
     // SAFETY: const sound because we transmute two types with the same layout
     #[allow(unused_attributes)]
@@ -2239,6 +2245,7 @@ pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
     /// let ptr = s.as_ptr();
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "rustc_str_as_ptr", since = "1.32.0"))]
     #[inline]
     pub const fn as_ptr(&self) -> *const u8 {
         self as *const str as *const u8
index 6e1aac00c7bc5401e536dcba652394b4afb6428e..0b22ae69ac21898ce2d8c3d4d299b4aec7242cd7 100644 (file)
@@ -331,6 +331,7 @@ impl AtomicBool {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_atomic_new", since = "1.32.0"))]
     pub const fn new(v: bool) -> AtomicBool {
         AtomicBool { v: UnsafeCell::new(v as u8) }
     }
@@ -855,6 +856,7 @@ impl<T> AtomicPtr<T> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_atomic_new", since = "1.32.0"))]
     pub const fn new(p: *mut T) -> AtomicPtr<T> {
         AtomicPtr { p: UnsafeCell::new(p) }
     }
@@ -1183,6 +1185,12 @@ macro_rules! atomic_int {
      $stable_access:meta,
      $stable_from:meta,
      $stable_nand:meta,
+     $const_stable:meta,
+     $const_stable_cxchg:meta,
+     $const_stable_debug:meta,
+     $const_stable_access:meta,
+     $const_stable_from:meta,
+     $const_stable_nand:meta,
      $stable_init_const:meta,
      $s_int_type:expr, $int_ref:expr,
      $extra_feature:expr,
@@ -1258,6 +1266,7 @@ impl $atomic_type {
 ```"),
                 #[inline]
                 #[$stable]
+                #[cfg_attr(not(bootstrap), $const_stable)]
                 pub const fn new(v: $int_type) -> Self {
                     $atomic_type {v: UnsafeCell::new(v)}
                 }
@@ -1978,6 +1987,12 @@ pub fn as_mut_ptr(&self) -> *mut $int_type {
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
     unstable(feature = "integer_atomics", issue = "32976"),
     "i8", "../../../std/primitive.i8.html",
     "",
@@ -1995,6 +2010,12 @@ pub fn as_mut_ptr(&self) -> *mut $int_type {
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
     unstable(feature = "integer_atomics", issue = "32976"),
     "u8", "../../../std/primitive.u8.html",
     "",
@@ -2012,6 +2033,12 @@ pub fn as_mut_ptr(&self) -> *mut $int_type {
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
     unstable(feature = "integer_atomics", issue = "32976"),
     "i16", "../../../std/primitive.i16.html",
     "",
@@ -2029,6 +2056,12 @@ pub fn as_mut_ptr(&self) -> *mut $int_type {
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
     unstable(feature = "integer_atomics", issue = "32976"),
     "u16", "../../../std/primitive.u16.html",
     "",
@@ -2046,6 +2079,12 @@ pub fn as_mut_ptr(&self) -> *mut $int_type {
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
     unstable(feature = "integer_atomics", issue = "32976"),
     "i32", "../../../std/primitive.i32.html",
     "",
@@ -2063,6 +2102,12 @@ pub fn as_mut_ptr(&self) -> *mut $int_type {
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
     unstable(feature = "integer_atomics", issue = "32976"),
     "u32", "../../../std/primitive.u32.html",
     "",
@@ -2080,6 +2125,12 @@ pub fn as_mut_ptr(&self) -> *mut $int_type {
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
     unstable(feature = "integer_atomics", issue = "32976"),
     "i64", "../../../std/primitive.i64.html",
     "",
@@ -2097,6 +2148,12 @@ pub fn as_mut_ptr(&self) -> *mut $int_type {
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
     unstable(feature = "integer_atomics", issue = "32976"),
     "u64", "../../../std/primitive.u64.html",
     "",
@@ -2114,6 +2171,12 @@ pub fn as_mut_ptr(&self) -> *mut $int_type {
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
+    rustc_const_unstable(feature = "const_integer_atomics", issue = "32976"),
+    rustc_const_unstable(feature = "const_integer_atomics", issue = "32976"),
+    rustc_const_unstable(feature = "const_integer_atomics", issue = "32976"),
+    rustc_const_unstable(feature = "const_integer_atomics", issue = "32976"),
+    rustc_const_unstable(feature = "const_integer_atomics", issue = "32976"),
+    rustc_const_unstable(feature = "const_integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
     "i128", "../../../std/primitive.i128.html",
     "#![feature(integer_atomics)]\n\n",
@@ -2131,6 +2194,12 @@ pub fn as_mut_ptr(&self) -> *mut $int_type {
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
+    rustc_const_unstable(feature = "const_integer_atomics", issue = "32976"),
+    rustc_const_unstable(feature = "const_integer_atomics", issue = "32976"),
+    rustc_const_unstable(feature = "const_integer_atomics", issue = "32976"),
+    rustc_const_unstable(feature = "const_integer_atomics", issue = "32976"),
+    rustc_const_unstable(feature = "const_integer_atomics", issue = "32976"),
+    rustc_const_unstable(feature = "const_integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
     "u128", "../../../std/primitive.u128.html",
     "#![feature(integer_atomics)]\n\n",
@@ -2163,6 +2232,12 @@ macro_rules! ptr_width {
     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.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
     stable(feature = "rust1", since = "1.0.0"),
     "isize", "../../../std/primitive.isize.html",
     "",
@@ -2180,6 +2255,12 @@ macro_rules! ptr_width {
     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.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
+    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
     stable(feature = "rust1", since = "1.0.0"),
     "usize", "../../../std/primitive.usize.html",
     "",
index 0759ff93ea85f0da49acb9f346068da1b0622a83..c1e45f189b7a62de9f84ff1559c5c3dafbd712dd 100644 (file)
@@ -39,6 +39,7 @@ impl RawWaker {
     /// function in the `vtable` of the underlying `RawWaker` will be called.
     #[rustc_promotable]
     #[stable(feature = "futures_api", since = "1.36.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "futures_api", since = "1.36.0"))]
     pub const fn new(data: *const (), vtable: &'static RawWakerVTable) -> RawWaker {
         RawWaker { data, vtable }
     }
@@ -151,6 +152,7 @@ impl RawWakerVTable {
     // FIXME: remove whenever we have a stable way to accept fn pointers from const fn
     // (see https://github.com/rust-rfcs/const-eval/issues/19#issuecomment-472799062)
     #[rustc_allow_const_fn_ptr]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "futures_api", since = "1.36.0"))]
     pub const fn new(
         clone: unsafe fn(*const ()) -> RawWaker,
         wake: unsafe fn(*const ()),
index 70ec1e42fd71b6981d27c8c02e2e0ee4fd198f07..7d04cfb5da518a715523180cdfe51b18f4a263df 100644 (file)
@@ -130,6 +130,7 @@ impl Duration {
     /// ```
     #[stable(feature = "duration", since = "1.3.0")]
     #[inline]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "duration_consts", since = "1.32.0"))]
     pub fn new(secs: u64, nanos: u32) -> Duration {
         let secs =
             secs.checked_add((nanos / NANOS_PER_SEC) as u64).expect("overflow in Duration::new");
@@ -152,6 +153,7 @@ pub fn new(secs: u64, nanos: u32) -> Duration {
     #[stable(feature = "duration", since = "1.3.0")]
     #[inline]
     #[rustc_promotable]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "duration_consts", since = "1.32.0"))]
     pub const fn from_secs(secs: u64) -> Duration {
         Duration { secs, nanos: 0 }
     }
@@ -171,6 +173,7 @@ pub const fn from_secs(secs: u64) -> Duration {
     #[stable(feature = "duration", since = "1.3.0")]
     #[inline]
     #[rustc_promotable]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "duration_consts", since = "1.32.0"))]
     pub const fn from_millis(millis: u64) -> Duration {
         Duration {
             secs: millis / MILLIS_PER_SEC,
@@ -193,6 +196,7 @@ pub const fn from_millis(millis: u64) -> Duration {
     #[stable(feature = "duration_from_micros", since = "1.27.0")]
     #[inline]
     #[rustc_promotable]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "duration_consts", since = "1.32.0"))]
     pub const fn from_micros(micros: u64) -> Duration {
         Duration {
             secs: micros / MICROS_PER_SEC,
@@ -215,6 +219,7 @@ pub const fn from_micros(micros: u64) -> Duration {
     #[stable(feature = "duration_extras", since = "1.27.0")]
     #[inline]
     #[rustc_promotable]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "duration_consts", since = "1.32.0"))]
     pub const fn from_nanos(nanos: u64) -> Duration {
         Duration {
             secs: nanos / (NANOS_PER_SEC as u64),
@@ -251,6 +256,7 @@ pub const fn from_nanos(nanos: u64) -> Duration {
     ///
     /// [`subsec_nanos`]: #method.subsec_nanos
     #[stable(feature = "duration", since = "1.3.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "duration", since = "1.32.0"))]
     #[inline]
     pub const fn as_secs(&self) -> u64 {
         self.secs
@@ -272,6 +278,7 @@ pub const fn as_secs(&self) -> u64 {
     /// assert_eq!(duration.subsec_millis(), 432);
     /// ```
     #[stable(feature = "duration_extras", since = "1.27.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "duration_extras", since = "1.32.0"))]
     #[inline]
     pub const fn subsec_millis(&self) -> u32 {
         self.nanos / NANOS_PER_MILLI
@@ -293,6 +300,7 @@ pub const fn subsec_millis(&self) -> u32 {
     /// assert_eq!(duration.subsec_micros(), 234_567);
     /// ```
     #[stable(feature = "duration_extras", since = "1.27.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "duration_extras", since = "1.32.0"))]
     #[inline]
     pub const fn subsec_micros(&self) -> u32 {
         self.nanos / NANOS_PER_MICRO
@@ -314,6 +322,7 @@ pub const fn subsec_micros(&self) -> u32 {
     /// assert_eq!(duration.subsec_nanos(), 10_000_000);
     /// ```
     #[stable(feature = "duration", since = "1.3.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "duration", since = "1.32.0"))]
     #[inline]
     pub const fn subsec_nanos(&self) -> u32 {
         self.nanos
@@ -330,6 +339,7 @@ pub const fn subsec_nanos(&self) -> u32 {
     /// assert_eq!(duration.as_millis(), 5730);
     /// ```
     #[stable(feature = "duration_as_u128", since = "1.33.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "duration_as_u128", since = "1.33.0"))]
     #[inline]
     pub const fn as_millis(&self) -> u128 {
         self.secs as u128 * MILLIS_PER_SEC as u128 + (self.nanos / NANOS_PER_MILLI) as u128
@@ -346,6 +356,7 @@ pub const fn as_millis(&self) -> u128 {
     /// assert_eq!(duration.as_micros(), 5730023);
     /// ```
     #[stable(feature = "duration_as_u128", since = "1.33.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "duration_as_u128", since = "1.33.0"))]
     #[inline]
     pub const fn as_micros(&self) -> u128 {
         self.secs as u128 * MICROS_PER_SEC as u128 + (self.nanos / NANOS_PER_MICRO) as u128
@@ -362,6 +373,7 @@ pub const fn as_micros(&self) -> u128 {
     /// assert_eq!(duration.as_nanos(), 5730023852);
     /// ```
     #[stable(feature = "duration_as_u128", since = "1.33.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "duration_as_u128", since = "1.33.0"))]
     #[inline]
     pub const fn as_nanos(&self) -> u128 {
         self.secs as u128 * NANOS_PER_SEC as u128 + self.nanos as u128
index bd47d41a785b4d4e41714702227e8df2504dea92..51756084f24b0b90f4df4986ae33e1d612281ff3 100644 (file)
@@ -19,7 +19,7 @@
 use syntax::ast::{Attribute, CRATE_NODE_ID};
 use syntax::errors::Applicability;
 use syntax::feature_gate::{feature_err, feature_err_issue};
-use syntax::attr::{self, Stability, Deprecation, RustcDeprecation};
+use syntax::attr::{self, Stability, Deprecation, RustcDeprecation, ConstStability};
 use crate::ty::{self, TyCtxt};
 use crate::util::nodemap::{FxHashSet, FxHashMap};
 
@@ -91,6 +91,7 @@ pub struct Index<'tcx> {
     /// This is mostly a cache, except the stabilities of local items
     /// are filled by the annotator.
     stab_map: FxHashMap<HirId, &'tcx Stability>,
+    const_stab_map: FxHashMap<HirId, &'tcx ConstStability>,
     depr_map: FxHashMap<HirId, DeprecationEntry>,
 
     /// Maps for each crate whether it is part of the staged API.
@@ -123,8 +124,14 @@ fn annotate<F>(&mut self, hir_id: HirId, attrs: &[Attribute],
                 self.tcx.sess.span_err(item_sp, "`#[deprecated]` cannot be used in staged API; \
                                                  use `#[rustc_deprecated]` instead");
             }
-            if let Some(mut stab) = attr::find_stability(&self.tcx.sess.parse_sess,
-                                                         attrs, item_sp) {
+            let (stab, const_stab) = attr::find_stability(
+                &self.tcx.sess.parse_sess, attrs, item_sp,
+            );
+            if let Some(const_stab) = const_stab {
+                let const_stab = self.tcx.intern_const_stability(const_stab);
+                self.index.const_stab_map.insert(hir_id, const_stab);
+            }
+            if let Some(mut stab) = stab {
                 // Error if prohibited, or can't inherit anything from a container.
                 if kind == AnnotationKind::Prohibited ||
                    (kind == AnnotationKind::Container &&
@@ -193,6 +200,7 @@ fn annotate<F>(&mut self, hir_id: HirId, attrs: &[Attribute],
                 sym::unstable, sym::stable,
                 sym::rustc_deprecated,
                 sym::rustc_const_unstable,
+                sym::rustc_const_stable,
             ];
             for attr in attrs {
                 let name = attr.name_or_empty();
@@ -404,6 +412,7 @@ pub fn new(tcx: TyCtxt<'tcx>) -> Index<'tcx> {
         let mut index = Index {
             staged_api,
             stab_map: Default::default(),
+            const_stab_map: Default::default(),
             depr_map: Default::default(),
             active_features: Default::default(),
         };
@@ -445,9 +454,6 @@ pub fn new(tcx: TyCtxt<'tcx>) -> Index<'tcx> {
                     },
                     feature: sym::rustc_private,
                     rustc_depr: None,
-                    const_stability: None,
-                    promotable: false,
-                    allow_const_fn_ptr: false,
                 });
                 annotator.parent_stab = Some(stability);
             }
@@ -465,6 +471,10 @@ pub fn local_stability(&self, id: HirId) -> Option<&'tcx Stability> {
         self.stab_map.get(&id).cloned()
     }
 
+    pub fn local_const_stability(&self, id: HirId) -> Option<&'tcx ConstStability> {
+        self.const_stab_map.get(&id).cloned()
+    }
+
     pub fn local_deprecation_entry(&self, id: HirId) -> Option<DeprecationEntry> {
         self.depr_map.get(&id).cloned()
     }
index 538b13c79ce1ccd45960bcf98850a44d5079321e..cc02165f605790230785be4629ddca8b39c5466b 100644 (file)
             eval_always
         }
         query lookup_stability(_: DefId) -> Option<&'tcx attr::Stability> {}
+        query lookup_const_stability(_: DefId) -> Option<&'tcx attr::ConstStability> {}
         query lookup_deprecation_entry(_: DefId) -> Option<DeprecationEntry> {}
         query item_attrs(_: DefId) -> Lrc<[ast::Attribute]> {}
     }
index 268015a56240e52290ecd360be42220da92a5108..0c87a53b3d0834b3b732c0eb472d000770f3d70d 100644 (file)
@@ -30,7 +30,12 @@ pub fn is_const_fn(self, def_id: DefId) -> bool {
     /// Whether the `def_id` is an unstable const fn and what feature gate is necessary to enable it
     pub fn is_unstable_const_fn(self, def_id: DefId) -> Option<Symbol> {
         if self.is_const_fn_raw(def_id) {
-            self.lookup_stability(def_id)?.const_stability
+            let const_stab = self.lookup_const_stability(def_id)?;
+            if const_stab.level.is_unstable() {
+                Some(const_stab.feature)
+            } else {
+                None
+            }
         } else {
             None
         }
@@ -83,15 +88,31 @@ pub fn is_min_const_fn(self, def_id: DefId) -> bool {
         }
 
         if self.features().staged_api {
-            // in order for a libstd function to be considered min_const_fn
-            // it needs to be stable and have no `rustc_const_unstable` attribute
-            match self.lookup_stability(def_id) {
-                // stable functions with unstable const fn aren't `min_const_fn`
-                Some(&attr::Stability { const_stability: Some(_), .. }) => false,
-                // unstable functions don't need to conform
-                Some(&attr::Stability { ref level, .. }) if level.is_unstable() => false,
-                // everything else needs to conform, because it would be callable from
-                // other `min_const_fn` functions
+            // In order for a libstd function to be considered min_const_fn
+            // it needs to be stable and have no `rustc_const_unstable` attribute.
+            match self.lookup_const_stability(def_id) {
+                // `rustc_const_unstable` functions don't need to conform.
+                Some(&attr::ConstStability { ref level, .. }) if level.is_unstable() => false,
+                None => if let Some(stab) = self.lookup_stability(def_id) {
+                    if stab.level.is_stable() {
+                        self.sess.span_err(
+                            self.def_span(def_id),
+                            "stable const functions must have either `rustc_const_stable` or \
+                            `rustc_const_unstable` attribute",
+                        );
+                        // While we errored above, because we don't know if we need to conform, we
+                        // err on the "safe" side and require min_const_fn.
+                        true
+                    } else {
+                        // Unstable functions need not conform to min const fn.
+                        false
+                    }
+                } else {
+                    // Unstable functions or internal functions need not conform to min const fn.
+                    false
+                },
+                // Everything else needs to conform, because it would be callable from
+                // other `min_const_fn` functions.
                 _ => true,
             }
         } else {
@@ -188,7 +209,7 @@ fn is_const_fn_raw(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
     }
 
     fn is_promotable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
-        tcx.is_const_fn(def_id) && match tcx.lookup_stability(def_id) {
+        tcx.is_const_fn(def_id) && match tcx.lookup_const_stability(def_id) {
             Some(stab) => {
                 if cfg!(debug_assertions) && stab.promotable {
                     let sig = tcx.fn_sig(def_id);
@@ -207,7 +228,7 @@ fn is_promotable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
 
     fn const_fn_is_allowed_fn_ptr(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
         tcx.is_const_fn(def_id) &&
-            tcx.lookup_stability(def_id)
+            tcx.lookup_const_stability(def_id)
                 .map(|stab| stab.allow_const_fn_ptr).unwrap_or(false)
     }
 
index f7e422b0403dcf88dd59a63a89e98fb69498001a..595ea40b2ffd5896e0f827737e4e68c1043adb91 100644 (file)
@@ -1066,8 +1066,12 @@ pub struct GlobalCtxt<'tcx> {
     /// Data layout specification for the current target.
     pub data_layout: TargetDataLayout,
 
+    /// `#[stable]` and `#[unstable]` attributes
     stability_interner: ShardedHashMap<&'tcx attr::Stability, ()>,
 
+    /// `#[rustc_const_stable]` and `#[rustc_const_unstable]` attributes
+    const_stability_interner: ShardedHashMap<&'tcx attr::ConstStability, ()>,
+
     /// Stores the value of constants (and deduplicates the actual memory)
     allocation_interner: ShardedHashMap<&'tcx Allocation, ()>,
 
@@ -1129,6 +1133,12 @@ pub fn intern_stability(self, stab: attr::Stability) -> &'tcx attr::Stability {
         })
     }
 
+    pub fn intern_const_stability(self, stab: attr::ConstStability) -> &'tcx attr::ConstStability {
+        self.const_stability_interner.intern(stab, |stab| {
+            self.arena.alloc(stab)
+        })
+    }
+
     pub fn intern_layout(self, layout: LayoutDetails) -> &'tcx LayoutDetails {
         self.layout_interner.intern(layout, |layout| {
             self.arena.alloc(layout)
@@ -1269,6 +1279,7 @@ pub fn create_global_ctxt(
             data_layout,
             layout_interner: Default::default(),
             stability_interner: Default::default(),
+            const_stability_interner: Default::default(),
             allocation_interner: Default::default(),
             alloc_map: Lock::new(interpret::AllocMap::new()),
             output_filenames: Arc::new(output_filenames.clone()),
@@ -2058,6 +2069,7 @@ pub fn print_debug_stats(self) {
         println!("InternalSubsts interner: #{}", self.interners.substs.len());
         println!("Region interner: #{}", self.interners.region.len());
         println!("Stability interner: #{}", self.stability_interner.len());
+        println!("Const Stability interner: #{}", self.const_stability_interner.len());
         println!("Allocation interner: #{}", self.allocation_interner.len());
         println!("Layout interner: #{}", self.layout_interner.len());
     }
@@ -2992,6 +3004,11 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
         let id = tcx.hir().definitions().def_index_to_hir_id(id.index);
         tcx.stability().local_stability(id)
     };
+    providers.lookup_const_stability = |tcx, id| {
+        assert_eq!(id.krate, LOCAL_CRATE);
+        let id = tcx.hir().definitions().def_index_to_hir_id(id.index);
+        tcx.stability().local_const_stability(id)
+    };
     providers.lookup_deprecation_entry = |tcx, id| {
         assert_eq!(id.krate, LOCAL_CRATE);
         let id = tcx.hir().definitions().def_index_to_hir_id(id.index);
index 0db2401aaead7bc4157f89c26be206f1afff8d5d..0a4fb8a224eecc1cd8e74b7177eb3e7ffacb73fc 100644 (file)
@@ -346,6 +346,8 @@ macro_rules! experimental {
     ),
     // FIXME(#14407)
     ungated!(rustc_const_unstable, Whitelisted, template!(List: r#"feature = "name""#)),
+    // FIXME(#14407)
+    ungated!(rustc_const_stable, Whitelisted, template!(List: r#"feature = "name""#)),
     gated!(
         allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."),
         "allow_internal_unstable side-steps feature gating and stability checks",
index 0107a22772fd225adb9c65290c792fda151547c3..a1f95e35cbef2d1b35a7d85be2b528eb77b8d0e4 100644 (file)
@@ -852,6 +852,10 @@ fn get_stability(&self, id: DefIndex) -> Option<attr::Stability> {
         }
     }
 
+    fn get_const_stability(&self, id: DefIndex) -> Option<attr::ConstStability> {
+        self.root.per_def.const_stability.get(self, id).map(|stab| stab.decode(self))
+    }
+
     fn get_deprecation(&self, id: DefIndex) -> Option<attr::Deprecation> {
         self.root.per_def.deprecation.get(self, id)
             .filter(|_| !self.is_proc_macro(id))
index 13db9a6fef9ca83b1cf5a6c808726f61c4a4517a..4a6b25930c869069d4b9f89397aaf7d6ba5b609c 100644 (file)
@@ -134,6 +134,9 @@ fn into_args(self) -> (DefId, DefId) { (self.0.as_def_id(), self.1) }
     lookup_stability => {
         cdata.get_stability(def_id.index).map(|s| tcx.intern_stability(s))
     }
+    lookup_const_stability => {
+        cdata.get_const_stability(def_id.index).map(|s| tcx.intern_const_stability(s))
+    }
     lookup_deprecation_entry => {
         cdata.get_deprecation(def_id.index).map(DeprecationEntry::external)
     }
index fb70e10c84f3dcef07b0976941aab4bd6bdf83c1..c1562a7734271dba1b354e3589842053b6986c92 100644 (file)
@@ -866,6 +866,7 @@ fn encode_info_for_trait_item(&mut self, def_id: DefId) {
         record!(self.per_def.span[def_id] <- ast_item.span);
         record!(self.per_def.attributes[def_id] <- &ast_item.attrs);
         self.encode_stability(def_id);
+        self.encode_const_stability(def_id);
         self.encode_deprecation(def_id);
         match trait_item.kind {
             ty::AssocKind::Const |
@@ -946,6 +947,7 @@ fn encode_info_for_impl_item(&mut self, def_id: DefId) {
         record!(self.per_def.span[def_id] <- ast_item.span);
         record!(self.per_def.attributes[def_id] <- &ast_item.attrs);
         self.encode_stability(def_id);
+        self.encode_const_stability(def_id);
         self.encode_deprecation(def_id);
         self.encode_item_type(def_id);
         if impl_item.kind == ty::AssocKind::Method {
@@ -1025,6 +1027,13 @@ fn encode_stability(&mut self, def_id: DefId) {
         }
     }
 
+    fn encode_const_stability(&mut self, def_id: DefId) {
+        debug!("EncodeContext::encode_const_stability({:?})", def_id);
+        if let Some(stab) = self.tcx.lookup_const_stability(def_id) {
+            record!(self.per_def.const_stability[def_id] <- stab)
+        }
+    }
+
     fn encode_deprecation(&mut self, def_id: DefId) {
         debug!("EncodeContext::encode_deprecation({:?})", def_id);
         if let Some(depr) = self.tcx.lookup_deprecation(def_id) {
@@ -1186,6 +1195,7 @@ fn encode_info_for_item(&mut self, def_id: DefId, item: &'tcx hir::Item) {
             _ => {}
         }
         self.encode_stability(def_id);
+        self.encode_const_stability(def_id);
         self.encode_deprecation(def_id);
         match item.kind {
             hir::ItemKind::Static(..) |
@@ -1545,6 +1555,7 @@ fn encode_info_for_foreign_item(
         record!(self.per_def.span[def_id] <- nitem.span);
         record!(self.per_def.attributes[def_id] <- &nitem.attrs);
         self.encode_stability(def_id);
+        self.encode_const_stability(def_id);
         self.encode_deprecation(def_id);
         self.encode_item_type(def_id);
         if let hir::ForeignItemKind::Fn(..) = nitem.kind {
index 5abae4293731d9c4f58dc9944e37c8a00da89856..e13edc2d621c56e0a1323eb7d0b3648fb7782cfd 100644 (file)
@@ -261,6 +261,7 @@ fn encode(&self, buf: &mut Encoder) -> LazyPerDefTables<'tcx> {
     attributes: Table<DefIndex, Lazy<[ast::Attribute]>>,
     children: Table<DefIndex, Lazy<[DefIndex]>>,
     stability: Table<DefIndex, Lazy<attr::Stability>>,
+    const_stability: Table<DefIndex, Lazy<attr::ConstStability>>,
     deprecation: Table<DefIndex, Lazy<attr::Deprecation>>,
     ty: Table<DefIndex, Lazy!(Ty<'tcx>)>,
     fn_sig: Table<DefIndex, Lazy!(ty::PolyFnSig<'tcx>)>,
index 6dcda98631014a1eed927bdcc5c5c7c73af702a7..14ca0423d8bc496c1b9d439cd293e158ac0cc5c2 100644 (file)
@@ -1065,7 +1065,8 @@ pub fn from_bytes_with_nul(bytes: &[u8])
     /// ```
     #[inline]
     #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
-    #[rustc_const_unstable(feature = "const_cstr_unchecked")]
+    #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_cstr_unchecked"))]
+    #[cfg_attr(not(bootstrap), rustc_const_unstable(feature = "const_cstr_unchecked", issue = "0"))]
     pub const unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr {
         &*(bytes as *const [u8] as *const CStr)
     }
@@ -1119,6 +1120,7 @@ pub fn from_bytes_with_nul(bytes: &[u8])
     /// [`CString`]: struct.CString.html
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_str_as_ptr", since = "1.32.0"))]
     pub const fn as_ptr(&self) -> *const c_char {
         self.inner.as_ptr()
     }
index e51a9b624498d16424c35261b28186897280fbfe..7d69f8f4b8d2fca23d558e131b459c15d617ea06 100644 (file)
@@ -319,6 +319,7 @@ impl Ipv4Addr {
     /// let addr = Ipv4Addr::new(127, 0, 0, 1);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_ipv4", since = "1.32.0"))]
     pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr {
         // FIXME: should just be u32::from_be_bytes([a, b, c, d]),
         // once that method is no longer rustc_const_unstable
@@ -406,6 +407,7 @@ pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr {
     /// assert_eq!(Ipv4Addr::new(45, 22, 13, 197).is_unspecified(), false);
     /// ```
     #[stable(feature = "ip_shared", since = "1.12.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_ipv4", since = "1.32.0"))]
     pub const fn is_unspecified(&self) -> bool {
         self.inner.s_addr == 0
     }
@@ -1015,6 +1017,7 @@ impl Ipv6Addr {
     /// let addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_ipv6", since = "1.32.0"))]
     pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16,
                      g: u16, h: u16) -> Ipv6Addr {
         Ipv6Addr {
@@ -1480,6 +1483,7 @@ pub fn to_ipv4(&self) -> Option<Ipv4Addr> {
     ///            [255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
     /// ```
     #[stable(feature = "ipv6_to_octets", since = "1.12.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_ipv6", since = "1.32.0"))]
     pub const fn octets(&self) -> [u8; 16] {
         self.inner.s6_addr
     }
index e8e395247f9c199dc5d2ca4e0e00c7a66c91a639..d8df09071cd69175d3038494a54f6005ca652385 100644 (file)
@@ -188,6 +188,7 @@ struct WaiterQueue<'a> {
 impl Once {
     /// Creates a new `Once` value.
     #[stable(feature = "once_new", since = "1.2.0")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_once_new", since = "1.32.0"))]
     pub const fn new() -> Once {
         Once { state_and_queue: AtomicUsize::new(INCOMPLETE), _marker: marker::PhantomData }
     }
index 3c10f27b60ae94532eba9919aa6de84de0ba7c8b..a37b27f67bcbd242c632d4279d3e8250408ab4a2 100644 (file)
@@ -120,17 +120,21 @@ pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Op
     })
 }
 
-/// Represents the #[stable], #[unstable], #[rustc_{deprecated,const_unstable}] attributes.
+/// Represents the #[stable], #[unstable], #[rustc_deprecated] attributes.
 #[derive(RustcEncodable, RustcDecodable, Copy, Clone, Debug,
          PartialEq, Eq, Hash, HashStable_Generic)]
 pub struct Stability {
     pub level: StabilityLevel,
     pub feature: Symbol,
     pub rustc_depr: Option<RustcDeprecation>,
-    /// `None` means the function is stable but needs to be a stable const fn, too
-    /// `Some` contains the feature gate required to be able to use the function
-    /// as const fn
-    pub const_stability: Option<Symbol>,
+}
+
+/// Represents the #[rustc_const_unstable] and #[rustc_const_stable] attributes.
+#[derive(RustcEncodable, RustcDecodable, Copy, Clone, Debug,
+         PartialEq, Eq, Hash, HashStable_Generic)]
+pub struct ConstStability {
+    pub level: StabilityLevel,
+    pub feature: Symbol,
     /// whether the function has a `#[rustc_promotable]` attribute
     pub promotable: bool,
     /// whether the function has a `#[rustc_allow_const_fn_ptr]` attribute
@@ -186,21 +190,21 @@ pub fn contains_feature_attr(attrs: &[Attribute], feature_name: Symbol) -> bool
 /// Collects stability info from all stability attributes in `attrs`.
 /// Returns `None` if no stability attributes are found.
 pub fn find_stability(sess: &ParseSess, attrs: &[Attribute],
-                      item_sp: Span) -> Option<Stability> {
+                      item_sp: Span) -> (Option<Stability>, Option<ConstStability>) {
     find_stability_generic(sess, attrs.iter(), item_sp)
 }
 
 fn find_stability_generic<'a, I>(sess: &ParseSess,
                                  attrs_iter: I,
                                  item_sp: Span)
-                                 -> Option<Stability>
+                                 -> (Option<Stability>, Option<ConstStability>)
     where I: Iterator<Item = &'a Attribute>
 {
     use StabilityLevel::*;
 
     let mut stab: Option<Stability> = None;
     let mut rustc_depr: Option<RustcDeprecation> = None;
-    let mut rustc_const_unstable: Option<Symbol> = None;
+    let mut const_stab: Option<ConstStability> = None;
     let mut promotable = false;
     let mut allow_const_fn_ptr = false;
     let diagnostic = &sess.span_diagnostic;
@@ -209,6 +213,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess,
         if ![
             sym::rustc_deprecated,
             sym::rustc_const_unstable,
+            sym::rustc_const_stable,
             sym::unstable,
             sym::stable,
             sym::rustc_promotable,
@@ -287,7 +292,8 @@ macro_rules! get_meta {
                 }
             }
 
-            match meta.name_or_empty() {
+            let meta_name = meta.name_or_empty();
+            match meta_name {
                 sym::rustc_deprecated => {
                     if rustc_depr.is_some() {
                         span_err!(diagnostic, item_sp, E0540,
@@ -315,23 +321,12 @@ macro_rules! get_meta {
                         }
                     }
                 }
-                sym::rustc_const_unstable => {
-                    if rustc_const_unstable.is_some() {
-                        span_err!(diagnostic, item_sp, E0553,
-                                  "multiple rustc_const_unstable attributes");
-                        continue 'outer
-                    }
-
-                    get_meta!(feature);
-                    if let Some(feature) = feature {
-                        rustc_const_unstable = Some(feature);
-                    } else {
-                        span_err!(diagnostic, attr.span, E0629, "missing 'feature'");
-                        continue
-                    }
-                }
+                sym::rustc_const_unstable |
                 sym::unstable => {
-                    if stab.is_some() {
+                    if meta_name == sym::unstable && stab.is_some() {
+                        handle_errors(sess, attr.span, AttrError::MultipleStabilityLevels);
+                        break
+                    } else if meta_name == sym::rustc_const_unstable && const_stab.is_some() {
                         handle_errors(sess, attr.span, AttrError::MultipleStabilityLevels);
                         break
                     }
@@ -398,18 +393,25 @@ macro_rules! get_meta {
                                     }
                                 }
                             };
-                            stab = Some(Stability {
-                                level: Unstable {
-                                    reason,
-                                    issue,
-                                    is_soft,
-                                },
-                                feature,
-                                rustc_depr: None,
-                                const_stability: None,
-                                promotable: false,
-                                allow_const_fn_ptr: false,
-                            })
+                            let level = Unstable {
+                                reason,
+                                issue,
+                                is_soft,
+                            };
+                            if sym::unstable == meta_name {
+                                stab = Some(Stability {
+                                    level,
+                                    feature,
+                                    rustc_depr: None,
+                                });
+                            } else {
+                                const_stab = Some(ConstStability {
+                                    level,
+                                    feature,
+                                    promotable: false,
+                                    allow_const_fn_ptr: false,
+                                });
+                            }
                         }
                         (None, _, _) => {
                             handle_errors(sess, attr.span, AttrError::MissingFeature);
@@ -421,8 +423,12 @@ macro_rules! get_meta {
                         }
                     }
                 }
+                sym::rustc_const_stable |
                 sym::stable => {
-                    if stab.is_some() {
+                    if meta_name == sym::stable && stab.is_some() {
+                        handle_errors(sess, attr.span, AttrError::MultipleStabilityLevels);
+                        break
+                    } else if meta_name == sym::rustc_const_stable &&const_stab.is_some() {
                         handle_errors(sess, attr.span, AttrError::MultipleStabilityLevels);
                         break
                     }
@@ -464,16 +470,21 @@ macro_rules! get_meta {
 
                     match (feature, since) {
                         (Some(feature), Some(since)) => {
-                            stab = Some(Stability {
-                                level: Stable {
-                                    since,
-                                },
-                                feature,
-                                rustc_depr: None,
-                                const_stability: None,
-                                promotable: false,
-                                allow_const_fn_ptr: false,
-                            })
+                            let level =  Stable { since };
+                            if sym::stable == meta_name {
+                                stab = Some(Stability {
+                                    level,
+                                    feature,
+                                    rustc_depr: None,
+                                });
+                            } else {
+                                const_stab = Some(ConstStability {
+                                    level,
+                                    feature,
+                                    promotable: false,
+                                    allow_const_fn_ptr: false,
+                                });
+                            }
                         }
                         (None, _) => {
                             handle_errors(sess, attr.span, AttrError::MissingFeature);
@@ -501,30 +512,20 @@ macro_rules! get_meta {
         }
     }
 
-    // Merge the const-unstable info into the stability info
-    if let Some(feature) = rustc_const_unstable {
-        if let Some(ref mut stab) = stab {
-            stab.const_stability = Some(feature);
-        } else {
-            span_err!(diagnostic, item_sp, E0630,
-                      "rustc_const_unstable attribute must be paired with \
-                       either stable or unstable attribute");
-        }
-    }
-
     // Merge the const-unstable info into the stability info
     if promotable || allow_const_fn_ptr {
-        if let Some(ref mut stab) = stab {
+        if let Some(ref mut stab) = const_stab {
             stab.promotable = promotable;
             stab.allow_const_fn_ptr = allow_const_fn_ptr;
         } else {
             span_err!(diagnostic, item_sp, E0717,
                       "rustc_promotable and rustc_allow_const_fn_ptr attributes \
-                      must be paired with either stable or unstable attribute");
+                      must be paired with either a rustc_const_unstable or a rustc_const_stable \
+                      attribute");
         }
     }
 
-    stab
+    (stab, const_stab)
 }
 
 pub fn find_crate_name(attrs: &[Attribute]) -> Option<Symbol> {
index a4449ca5b1d22dfab1052f83f612259d56601a62..c7dce93f91bebf625242775b223eee9f3114247d 100644 (file)
@@ -775,6 +775,10 @@ pub fn new(
         }
 
         let is_builtin = attr::contains_name(attrs, sym::rustc_builtin_macro);
+        let (stability, const_stability) = attr::find_stability(&sess, attrs, span);
+        if const_stability.is_some() {
+            sess.span_diagnostic.span_err(span, "macros can't have const stability attributes");
+        }
 
         SyntaxExtension {
             kind,
@@ -782,7 +786,7 @@ pub fn new(
             allow_internal_unstable,
             allow_internal_unsafe: attr::contains_name(attrs, sym::allow_internal_unsafe),
             local_inner_macros,
-            stability: attr::find_stability(&sess, attrs, span),
+            stability,
             deprecation: attr::find_deprecation(&sess, attrs, span),
             helper_attrs,
             edition,
index 92de56bd09a7acc4d150b75fb1020de360d22e3e..c7e4182de6b736a67fa38ad4ada9acf73440b6fd 100644 (file)
         rustc_builtin_macro,
         rustc_clean,
         rustc_const_unstable,
+        rustc_const_stable,
         rustc_conversion_suggestion,
         rustc_def_path,
         rustc_deprecated,
index e54cbb0980432c7a41f3b7de6af3bbe9701efb06..b1d5440b41a48d6ab3bdb1fc8c17d1364573ef04 100644 (file)
@@ -7,6 +7,7 @@
 
 #[rustc_promotable]
 #[stable(since="1.0.0", feature = "mep")]
+#[rustc_const_stable(since="1.0.0", feature = "mep")]
 #[inline]
 pub const fn foo() -> usize { 22 }
 
@@ -15,6 +16,7 @@ pub const fn foo() -> usize { 22 }
 
 impl Foo {
     #[stable(since="1.0.0", feature = "mep")]
+    #[rustc_const_stable(feature = "mep", since = "1.0.0")]
     #[inline]
     #[rustc_promotable]
     pub const fn foo() -> usize { 22 }
index f32e35d82af002f486838e7e9cded8bdb22a4025..830db55207f1ca207339823cd5ea2eb03f73124e 100644 (file)
@@ -7,5 +7,5 @@
 #![feature(staged_api)]
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature="foo")]
+#[rustc_const_unstable(feature="foo", issue = "0")]
 pub const fn foo() -> u32 { 42 }
index ea9c365410da780cc060a4ef240fa2e0af96247c..c4b89b50bc4ad5e9a025ebdb5f16273e316fa78c 100644 (file)
@@ -7,7 +7,7 @@
 #![feature(staged_api)]
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature="foo")]
+#[rustc_const_unstable(feature="foo", issue = "0")]
 const fn foo() -> u32 { 42 }
 
 fn meh() -> u32 { 42 }
index 3992607c387e11acb8a958d47aa6924b3146e6cc..937aae1a8e3997831f791b65416a577120b4a0a1 100644 (file)
@@ -1,10 +1,12 @@
 #![feature(rustc_attrs, staged_api)]
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_stable(since="1.0.0", feature = "mep")]
 const fn error(_: fn()) {} //~ ERROR function pointers in const fn are unstable
 
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_allow_const_fn_ptr]
+#[rustc_const_stable(since="1.0.0", feature = "mep")]
 const fn compiles(_: fn()) {}
 
 fn main() {}
index 6228b012dde38760096204cb8691d243fbd3dca0..0ede4229ade30fecef0689a4dd76a899e305fc87 100644 (file)
@@ -1,5 +1,5 @@
 error[E0723]: function pointers in const fn are unstable
-  --> $DIR/allow_const_fn_ptr.rs:4:16
+  --> $DIR/allow_const_fn_ptr.rs:5:16
    |
 LL | const fn error(_: fn()) {}
    |                ^
index 1d8b95ab1a2fdeddb1ab8061ea5268e5d966ab65..7aa9bd7e2dcdddeec9a76cdd29f9f14bd8bcf7fe 100644 (file)
@@ -5,6 +5,7 @@
 
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_allow_const_fn_ptr]
+#[rustc_const_stable(since="1.0.0", feature = "mep")]
 const fn takes_fn_ptr(_: fn()) {}
 
 const FN: fn() = || ();
index 6d53da50b3f76e542fdf866d82dc79c8647f022b..97e467aece2333ff8eee54fb56a641472f372afe 100644 (file)
@@ -7,10 +7,11 @@
 #![feature(staged_api)]
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature="foo")]
+#[rustc_const_unstable(feature="foo", issue = "0")]
 const fn foo() -> u32 { 42 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
 // can't call non-min_const_fn
 const fn bar() -> u32 { foo() } //~ ERROR can only call other `const fn`
 
@@ -18,10 +19,12 @@ const fn bar() -> u32 { foo() } //~ ERROR can only call other `const fn`
 const fn foo2() -> u32 { 42 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
 // can't call non-min_const_fn
 const fn bar2() -> u32 { foo2() } //~ ERROR can only call other `const fn`
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
 // conformity is required, even with `const_fn` feature gate
 const fn bar3() -> u32 { (5f32 + 6f32) as u32 } //~ ERROR only int, `bool` and `char` operations
 
@@ -30,6 +33,7 @@ const fn bar3() -> u32 { (5f32 + 6f32) as u32 } //~ ERROR only int, `bool` and `
 const fn foo2_gated() -> u32 { 42 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
 // can't call non-min_const_fn
 const fn bar2_gated() -> u32 { foo2_gated() } //~ ERROR can only call other `const fn`
 
index 0af5bdca815f9974791ff845e31d4251504a6f51..1da9b41aa5955647709dc8653bb66bf98ab6ae17 100644 (file)
@@ -1,5 +1,5 @@
 error[E0723]: can only call other `const fn` within a `const fn`, but `const foo` is not stable as `const fn`
-  --> $DIR/min_const_fn_libstd_stability.rs:15:25
+  --> $DIR/min_const_fn_libstd_stability.rs:16:25
    |
 LL | const fn bar() -> u32 { foo() }
    |                         ^^^^^
@@ -8,7 +8,7 @@ LL | const fn bar() -> u32 { foo() }
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: can only call other `const fn` within a `const fn`, but `const foo2` is not stable as `const fn`
-  --> $DIR/min_const_fn_libstd_stability.rs:22:26
+  --> $DIR/min_const_fn_libstd_stability.rs:24:26
    |
 LL | const fn bar2() -> u32 { foo2() }
    |                          ^^^^^^
@@ -17,7 +17,7 @@ LL | const fn bar2() -> u32 { foo2() }
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: only int, `bool` and `char` operations are stable in const fn
-  --> $DIR/min_const_fn_libstd_stability.rs:26:26
+  --> $DIR/min_const_fn_libstd_stability.rs:29:26
    |
 LL | const fn bar3() -> u32 { (5f32 + 6f32) as u32 }
    |                          ^^^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL | const fn bar3() -> u32 { (5f32 + 6f32) as u32 }
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: can only call other `const fn` within a `const fn`, but `const foo2_gated` is not stable as `const fn`
-  --> $DIR/min_const_fn_libstd_stability.rs:34:32
+  --> $DIR/min_const_fn_libstd_stability.rs:38:32
    |
 LL | const fn bar2_gated() -> u32 { foo2_gated() }
    |                                ^^^^^^^^^^^^
index f1f15a34c9e6919de53f121537f48c16b6c15704..102b380144113cb7631a5087f71fbaa8b37596d1 100644 (file)
@@ -7,10 +7,11 @@
 #![feature(staged_api)]
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature="foo")]
+#[rustc_const_unstable(feature="foo", issue = "0")]
 const unsafe fn foo() -> u32 { 42 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
 // can't call non-min_const_fn
 const unsafe fn bar() -> u32 { unsafe { foo() } } //~ ERROR can only call other `const fn`
 
 const unsafe fn foo2() -> u32 { 42 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
 // can't call non-min_const_fn
 const unsafe fn bar2() -> u32 { unsafe { foo2() } } //~ ERROR can only call other `const fn`
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
 // conformity is required, even with `const_fn` feature gate
 const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 } //~ ERROR only int, `bool` and `char` op
 
@@ -30,6 +33,7 @@
 const unsafe fn foo2_gated() -> u32 { 42 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
 // can't call non-min_const_fn
 const unsafe fn bar2_gated() -> u32 { unsafe { foo2_gated() } }
 //~^ ERROR can only call other `const fn`
index bc6f8c596060fb8612c00fc62c3f1eaf902126b9..ae92602d45f49e0cb6cc26a1d4bd95245843c857 100644 (file)
@@ -1,5 +1,5 @@
 error[E0723]: can only call other `const fn` within a `const fn`, but `const foo` is not stable as `const fn`
-  --> $DIR/min_const_unsafe_fn_libstd_stability.rs:15:41
+  --> $DIR/min_const_unsafe_fn_libstd_stability.rs:16:41
    |
 LL | const unsafe fn bar() -> u32 { unsafe { foo() } }
    |                                         ^^^^^
@@ -8,7 +8,7 @@ LL | const unsafe fn bar() -> u32 { unsafe { foo() } }
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: can only call other `const fn` within a `const fn`, but `const foo2` is not stable as `const fn`
-  --> $DIR/min_const_unsafe_fn_libstd_stability.rs:22:42
+  --> $DIR/min_const_unsafe_fn_libstd_stability.rs:24:42
    |
 LL | const unsafe fn bar2() -> u32 { unsafe { foo2() } }
    |                                          ^^^^^^
@@ -17,7 +17,7 @@ LL | const unsafe fn bar2() -> u32 { unsafe { foo2() } }
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: only int, `bool` and `char` operations are stable in const fn
-  --> $DIR/min_const_unsafe_fn_libstd_stability.rs:26:33
+  --> $DIR/min_const_unsafe_fn_libstd_stability.rs:29:33
    |
 LL | const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 }
    |                                 ^^^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL | const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 }
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: can only call other `const fn` within a `const fn`, but `const foo2_gated` is not stable as `const fn`
-  --> $DIR/min_const_unsafe_fn_libstd_stability.rs:34:48
+  --> $DIR/min_const_unsafe_fn_libstd_stability.rs:38:48
    |
 LL | const unsafe fn bar2_gated() -> u32 { unsafe { foo2_gated() } }
    |                                                ^^^^^^^^^^^^
index 2ac9e32e4a00ca6b29d3f17e42499a341ab441ad..121177f8366541fc0d8cd20db032ce4baa8c01bc 100644 (file)
@@ -7,10 +7,11 @@
 #![feature(staged_api)]
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature="foo")]
+#[rustc_const_unstable(feature="foo", issue = "0")]
 const fn foo() -> u32 { 42 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
 // can't call non-min_const_fn
 const unsafe fn bar() -> u32 { foo() } //~ ERROR can only call other `const fn`
 
@@ -18,6 +19,7 @@ const fn foo() -> u32 { 42 }
 const fn foo2() -> u32 { 42 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
 // can't call non-min_const_fn
 const unsafe fn bar2() -> u32 { foo2() } //~ ERROR can only call other `const fn`
 
@@ -26,6 +28,7 @@ const fn foo2() -> u32 { 42 }
 const fn foo2_gated() -> u32 { 42 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
 // can't call non-min_const_fn
 const unsafe fn bar2_gated() -> u32 { foo2_gated() } //~ ERROR can only call other `const fn`
 
index a14fd740c670a0572570d27903968150d4a98f3e..a0db74cfad65f9209fe6e53d1450c1e2a65c4cb8 100644 (file)
@@ -1,5 +1,5 @@
 error[E0723]: can only call other `const fn` within a `const fn`, but `const foo` is not stable as `const fn`
-  --> $DIR/min_const_unsafe_fn_libstd_stability2.rs:15:32
+  --> $DIR/min_const_unsafe_fn_libstd_stability2.rs:16:32
    |
 LL | const unsafe fn bar() -> u32 { foo() }
    |                                ^^^^^
@@ -8,7 +8,7 @@ LL | const unsafe fn bar() -> u32 { foo() }
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: can only call other `const fn` within a `const fn`, but `const foo2` is not stable as `const fn`
-  --> $DIR/min_const_unsafe_fn_libstd_stability2.rs:22:33
+  --> $DIR/min_const_unsafe_fn_libstd_stability2.rs:24:33
    |
 LL | const unsafe fn bar2() -> u32 { foo2() }
    |                                 ^^^^^^
@@ -17,7 +17,7 @@ LL | const unsafe fn bar2() -> u32 { foo2() }
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: can only call other `const fn` within a `const fn`, but `const foo2_gated` is not stable as `const fn`
-  --> $DIR/min_const_unsafe_fn_libstd_stability2.rs:30:39
+  --> $DIR/min_const_unsafe_fn_libstd_stability2.rs:33:39
    |
 LL | const unsafe fn bar2_gated() -> u32 { foo2_gated() }
    |                                       ^^^^^^^^^^^^
index cad1516fc78d0bec0b883983ce5fe2215e8ce53e..655ad7b548a30d0f5bf7b2ad63d4c34bccb0e3a0 100644 (file)
@@ -14,7 +14,7 @@ enum Opt<T> {
 }
 
 impl<T> Opt<T> {
-    #[rustc_const_unstable(feature = "foo")]
+    #[rustc_const_unstable(feature = "foo", issue = "0")]
     #[stable(feature = "rust1", since = "1.0.0")]
     const fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
     //~^ ERROR destructors cannot be evaluated at compile-time
index a87d105850327c911357c074af0e8b78fe908bbb..f88b3ea0a60bfee39f20640ed9ddab4b6ee4c321 100644 (file)
@@ -1,21 +1,15 @@
-error[E0725]: the feature `rustc_const_unstable` is not in the list of allowed features
-  --> $DIR/allow-features-empty.rs:4:12
-   |
-LL | #![feature(rustc_const_unstable)]
-   |            ^^^^^^^^^^^^^^^^^^^^
-
 error[E0725]: the feature `lang_items` is not in the list of allowed features
-  --> $DIR/allow-features-empty.rs:6:12
+  --> $DIR/allow-features-empty.rs:4:12
    |
 LL | #![feature(lang_items)]
    |            ^^^^^^^^^^
 
 error[E0725]: the feature `unknown_stdlib_feature` is not in the list of allowed features
-  --> $DIR/allow-features-empty.rs:8:12
+  --> $DIR/allow-features-empty.rs:6:12
    |
 LL | #![feature(unknown_stdlib_feature)]
    |            ^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0725`.
index 157dddf06ad1d6dbf28ebc214b1b16c0f4cbd9ee..9caf48dd1386b6700fcf391f5f88ce3ae06b332a 100644 (file)
@@ -1,15 +1,9 @@
-error[E0725]: the feature `rustc_const_unstable` is not in the list of allowed features
-  --> $DIR/allow-features.rs:4:12
-   |
-LL | #![feature(rustc_const_unstable)]
-   |            ^^^^^^^^^^^^^^^^^^^^
-
 error[E0725]: the feature `unknown_stdlib_feature` is not in the list of allowed features
-  --> $DIR/allow-features.rs:8:12
+  --> $DIR/allow-features.rs:6:12
    |
 LL | #![feature(unknown_stdlib_feature)]
    |            ^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0725`.
index d7b7cf72a266b35963491a8b9bbbfbf771d71bf7..9df926dcf90f5582980ecedb5052bb27e9fb7a9f 100644 (file)
@@ -1,11 +1,9 @@
-error[E0658]: the `#[rustc_const_unstable]` attribute is an internal feature
-  --> $DIR/feature-gate-rustc_const_unstable.rs:8:1
+error[E0734]: stability attributes may not be used outside of the standard library
+  --> $DIR/feature-gate-rustc_const_unstable.rs:5:1
    |
 LL | #[rustc_const_unstable(feature="fzzzzzt")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: add `#![feature(rustc_const_unstable)]` to the crate attributes to enable
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0658`.
+For more information about this error, try `rustc --explain E0734`.
index 91115ef74b8221c42f0dee9d63021996422a0d08..5d7664cefb33aa47522be9c7f308db19230c0300 100644 (file)
@@ -22,6 +22,7 @@
 // of the const fn kicks in, causing a different code path in the
 // compiler to be executed (see PR #66294).
 #[stable(feature = "rustc", since = "1.0.0")]
+#[rustc_const_stable(feature = "rustc", since = "1.0.0")]
 #[rustc_promotable]
 const fn bar(_: bool) -> usize { 0 - 1 }
 
index fc96d44bbb7d2796a0d60033995b599707efebd2..2e3d790d2d867b13da71a51295cbce4b9f4fa6a0 100644 (file)
@@ -60,11 +60,10 @@ fn multiple3() { }
 #[stable(feature = "a", since = "b")]
 #[rustc_deprecated(since = "b", reason = "text")]
 #[rustc_deprecated(since = "b", reason = "text")]
-#[rustc_const_unstable(feature = "c")]
-#[rustc_const_unstable(feature = "d")]
+#[rustc_const_unstable(feature = "c", issue = "0")]
+#[rustc_const_unstable(feature = "d", issue = "0")] //~ ERROR multiple stability levels
 pub const fn multiple4() { } //~ ERROR multiple rustc_deprecated attributes [E0540]
 //~^ ERROR Invalid stability or deprecation version found
-//~| ERROR multiple rustc_const_unstable attributes
 
 #[rustc_deprecated(since = "a", reason = "text")]
 fn deprecated_without_unstable_or_stable() { }
index 4b7ec821f458baebebc419ff0c60803d44eb9e86..552e078f45fde14de2e088f03a03e814b6237cd8 100644 (file)
@@ -88,11 +88,11 @@ error[E0540]: multiple rustc_deprecated attributes
 LL | pub const fn multiple4() { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0553]: multiple rustc_const_unstable attributes
-  --> $DIR/stability-attribute-sanity.rs:65:1
+error[E0544]: multiple stability levels
+  --> $DIR/stability-attribute-sanity.rs:64:1
    |
-LL | pub const fn multiple4() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[rustc_const_unstable(feature = "d", issue = "0")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: Invalid stability or deprecation version found
   --> $DIR/stability-attribute-sanity.rs:65:1
@@ -101,7 +101,7 @@ LL | pub const fn multiple4() { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0549]: rustc_deprecated attribute must be paired with either stable or unstable attribute
-  --> $DIR/stability-attribute-sanity.rs:70:1
+  --> $DIR/stability-attribute-sanity.rs:69:1
    |
 LL | fn deprecated_without_unstable_or_stable() { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index 41c4b618e60951bfa0cd8e03ec38953fffaf6fdf..311914ef23b37d4e357b39418da3bf18d48a1a19 100644 (file)
@@ -43,8 +43,6 @@
     "E0523",
     "E0554",
     "E0570",
-    "E0629",
-    "E0630",
     "E0640",
     "E0717",
     "E0727",