Auto merge of #67136 - oli-obk:const_stability, r=Centril

Require stable/unstable annotations for the constness of all stable fns with a const modifier

r? @RalfJung @Centril

Every `#[stable]` const fn now needs either a `#[rustc_const_unstable]` attribute or a `#[rustc_const_stable]` attribute. You can't silently stabilize the constness of a function anymore.
This commit is contained in:
bors 2019-12-14 10:21:32 +00:00
commit c8ea4ace92
66 changed files with 717 additions and 181 deletions

View 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 {

View File

@ -117,7 +117,7 @@
#![feature(unsized_locals)]
#![feature(allocator_internals)]
#![cfg_attr(bootstrap, feature(on_unimplemented))]
#![feature(rustc_const_unstable)]
#![cfg_attr(bootstrap, feature(rustc_const_unstable))]
#![feature(slice_partition_dedup)]
#![feature(maybe_uninit_extra, maybe_uninit_slice)]
#![feature(alloc_layout_extra)]

View 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() }

View 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 {

View 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) }

View 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>()

View 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

View 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

View 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

View File

@ -939,7 +939,11 @@
/// }
/// ```
#[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

View 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)
}

View File

@ -96,7 +96,7 @@
#![feature(prelude_import)]
#![feature(repr_simd, platform_intrinsics)]
#![feature(rustc_attrs)]
#![feature(rustc_const_unstable)]
#![cfg_attr(bootstrap, feature(rustc_const_unstable))]
#![feature(simd_ffi)]
#![feature(specialization)]
#![feature(staged_api)]

View 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

View 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> {

View 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>()
}

View 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

View 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 {

View 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

View 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

View 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) }

View 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

View 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

View 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,7 @@ macro_rules! atomic_int {
$stable_access:meta,
$stable_from:meta,
$stable_nand:meta,
$const_stable:meta,
$stable_init_const:meta,
$s_int_type:expr, $int_ref:expr,
$extra_feature:expr,
@ -1258,6 +1261,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 +1982,7 @@ 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"),
unstable(feature = "integer_atomics", issue = "32976"),
"i8", "../../../std/primitive.i8.html",
"",
@ -1995,6 +2000,7 @@ 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"),
unstable(feature = "integer_atomics", issue = "32976"),
"u8", "../../../std/primitive.u8.html",
"",
@ -2012,6 +2018,7 @@ 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"),
unstable(feature = "integer_atomics", issue = "32976"),
"i16", "../../../std/primitive.i16.html",
"",
@ -2029,6 +2036,7 @@ 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"),
unstable(feature = "integer_atomics", issue = "32976"),
"u16", "../../../std/primitive.u16.html",
"",
@ -2046,6 +2054,7 @@ 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"),
unstable(feature = "integer_atomics", issue = "32976"),
"i32", "../../../std/primitive.i32.html",
"",
@ -2063,6 +2072,7 @@ 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"),
unstable(feature = "integer_atomics", issue = "32976"),
"u32", "../../../std/primitive.u32.html",
"",
@ -2080,6 +2090,7 @@ 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"),
unstable(feature = "integer_atomics", issue = "32976"),
"i64", "../../../std/primitive.i64.html",
"",
@ -2097,6 +2108,7 @@ 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"),
unstable(feature = "integer_atomics", issue = "32976"),
"u64", "../../../std/primitive.u64.html",
"",
@ -2114,6 +2126,7 @@ 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_stable(feature = "const_integer_atomics", since = "1.34.0"),
unstable(feature = "integer_atomics", issue = "32976"),
"i128", "../../../std/primitive.i128.html",
"#![feature(integer_atomics)]\n\n",
@ -2131,6 +2144,7 @@ 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_stable(feature = "const_integer_atomics", since = "1.34.0"),
unstable(feature = "integer_atomics", issue = "32976"),
"u128", "../../../std/primitive.u128.html",
"#![feature(integer_atomics)]\n\n",
@ -2163,6 +2177,7 @@ 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"),
stable(feature = "rust1", since = "1.0.0"),
"isize", "../../../std/primitive.isize.html",
"",
@ -2180,6 +2195,7 @@ 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"),
stable(feature = "rust1", since = "1.0.0"),
"usize", "../../../std/primitive.usize.html",
"",

View 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 ()),

View 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

View 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 &&
@ -189,9 +196,15 @@ fn annotate<F>(&mut self, hir_id: HirId, attrs: &[Attribute],
}
} else {
// Emit errors for non-staged-api crates.
let unstable_attrs = [
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();
if [sym::unstable, sym::stable, sym::rustc_deprecated].contains(&name) {
if unstable_attrs.contains(&name) {
attr::mark_used(attr);
struct_span_err!(
self.tcx.sess,
@ -399,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(),
};
@ -440,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);
}
@ -460,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()
}

View File

@ -533,6 +533,7 @@
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]> {}
}

View 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,36 @@ 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 {
// Internal functions are forced to conform to min_const_fn.
// Annotate the internal function with a const stability attribute if
// you need to use unstable features.
// Note: this is an arbitrary choice that does not affect stability or const
// safety or anything, it just changes whether we need to annotate some
// internal functions with `rustc_const_stable` or with `rustc_const_unstable`
true
},
// Everything else needs to conform, because it would be callable from
// other `min_const_fn` functions.
_ => true,
}
} else {
@ -188,7 +214,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 +233,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)
}

View 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);

View File

@ -111,10 +111,6 @@ pub fn set(&self, features: &mut Features, span: Span) {
/// macros disappear).
(active, allow_internal_unsafe, "1.0.0", None, None),
/// Allows using `#[rustc_const_unstable(feature = "foo", ..)]` which
/// lets a function to be `const` when opted into with `#![feature(foo)]`.
(active, rustc_const_unstable, "1.0.0", None, None),
/// no-tracking-issue-end
/// Allows using `#[link_name="llvm.*"]`.

View File

@ -344,10 +344,10 @@ macro_rules! experimental {
unstable, Whitelisted,
template!(List: r#"feature = "name", reason = "...", issue = "N""#),
),
gated!(
rustc_const_unstable, Normal, template!(List: r#"feature = "name""#),
"the `#[rustc_const_unstable]` attribute is an internal feature",
),
// 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",

View 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))

View 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)
}

View 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 {

View 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>)>,

View 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()
}

View File

@ -293,7 +293,7 @@
#![feature(raw)]
#![feature(renamed_spin_loop)]
#![feature(rustc_attrs)]
#![feature(rustc_const_unstable)]
#![cfg_attr(bootstrap, feature(rustc_const_unstable))]
#![feature(rustc_private)]
#![feature(shrink_to)]
#![feature(slice_concat_ext)]

View 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
}

View 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 }
}

View 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> {

View 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 cannot 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,

View File

@ -605,6 +605,7 @@
rustc_builtin_macro,
rustc_clean,
rustc_const_unstable,
rustc_const_stable,
rustc_conversion_suggestion,
rustc_def_path,
rustc_deprecated,

View File

@ -4,12 +4,12 @@
reason = "who ever let humans program computers, we're apparently really bad at it",
issue = "0")]
#![feature(rustc_const_unstable, const_fn, foo, foo2)]
#![feature(foo, foo2)]
#![feature(staged_api)]
// @has 'foo/fn.foo.html' '//pre' 'pub unsafe fn foo() -> u32'
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature="foo")]
#[rustc_const_unstable(feature="foo", issue = "0")]
pub const unsafe fn foo() -> u32 { 42 }
// @has 'foo/fn.foo2.html' '//pre' 'pub fn foo2() -> u32'
@ -18,6 +18,7 @@ pub const fn foo2() -> u32 { 42 }
// @has 'foo/fn.bar2.html' '//pre' 'pub const fn bar2() -> u32'
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
pub const fn bar2() -> u32 { 42 }
// @has 'foo/fn.foo2_gated.html' '//pre' 'pub unsafe fn foo2_gated() -> u32'
@ -26,6 +27,7 @@ pub const fn bar2() -> u32 { 42 }
// @has 'foo/fn.bar2_gated.html' '//pre' 'pub const unsafe fn bar2_gated() -> u32'
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
pub const unsafe fn bar2_gated() -> u32 { 42 }
// @has 'foo/fn.bar_not_gated.html' '//pre' 'pub unsafe fn bar_not_gated() -> u32'

View 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 }

View File

@ -3,9 +3,9 @@
#![crate_type="rlib"]
#![stable(feature = "rust1", since = "1.0.0")]
#![feature(rustc_const_unstable, const_fn)]
#![feature(const_fn)]
#![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 }

View File

@ -3,11 +3,11 @@
we're apparently really bad at it",
issue = "0")]
#![feature(rustc_const_unstable, const_fn)]
#![feature(const_fn)]
#![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 }

View 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() {}

View 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()) {}
| ^

View 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() = || ();

View File

@ -3,14 +3,15 @@
we're apparently really bad at it",
issue = "0")]
#![feature(rustc_const_unstable, const_fn, foo, foo2)]
#![feature(const_fn, foo, foo2)]
#![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`

View 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() }
| ^^^^^^^^^^^^

View File

@ -3,14 +3,15 @@
we're apparently really bad at it",
issue = "0")]
#![feature(rustc_const_unstable, const_fn, foo, foo2)]
#![feature(const_fn, foo, foo2)]
#![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`
@ -18,10 +19,12 @@
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`

View 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() } }
| ^^^^^^^^^^^^

View File

@ -3,14 +3,15 @@
we're apparently really bad at it",
issue = "0")]
#![feature(rustc_const_unstable, const_fn, foo, foo2)]
#![feature(const_fn, foo, foo2)]
#![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`

View 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() }
| ^^^^^^^^^^^^

View 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

View File

@ -1,8 +1,6 @@
// compile-flags: -Z allow_features=
// Note: This test uses rustc internal flags because they will never stabilize.
#![feature(rustc_const_unstable)] //~ ERROR
#![feature(lang_items)] //~ ERROR
#![feature(unknown_stdlib_feature)] //~ ERROR

View 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`.

View File

@ -1,8 +1,6 @@
// compile-flags: -Z allow_features=lang_items
// Note: This test uses rustc internal flags because they will never stabilize.
#![feature(rustc_const_unstable)] //~ ERROR
#![feature(lang_items)]
#![feature(unknown_stdlib_feature)] //~ ERROR

View 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`.

View File

@ -1,11 +1,8 @@
// Test internal const fn feature gate.
#![feature(staged_api)]
#![feature(const_fn)]
//#![feature(rustc_const_unstable)]
#[stable(feature="zing", since="1.0.0")]
#[rustc_const_unstable(feature="fzzzzzt")] //~ERROR internal feature
#[rustc_const_unstable(feature="fzzzzzt")] //~ stability attributes may not be used outside
pub const fn bazinga() {}
fn main() {

View 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`.

View 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 }

View File

@ -1,6 +1,6 @@
// Various checks that stability attributes are used correctly, per RFC 507
#![feature(const_fn, staged_api, rustc_const_unstable)]
#![feature(const_fn, staged_api)]
#![stable(feature = "rust1", since = "1.0.0")]
@ -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() { }

View 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() { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -41,6 +41,7 @@
"E0514",
"E0519",
"E0523",
"E0553",
"E0554",
"E0570",
"E0629",