Rollup merge of #95354 - dtolnay:rustc_const_stable, r=lcnr

Handle rustc_const_stable attribute in library feature collector

The library feature collector in [compiler/rustc_passes/src/lib_features.rs](551b4fa395/compiler/rustc_passes/src/lib_features.rs) has only been looking at `#[stable(…)]`, `#[unstable(…)]`, and `#[rustc_const_unstable(…)]` attributes, while ignoring `#[rustc_const_stable(…)]`. The consequences of this were:

- When any const feature got stabilized (changing one or more `rustc_const_unstable` to `rustc_const_stable`), users who had previously enabled that unstable feature using `#![feature(…)]` would get told "unknown feature", rather than rustc's nicer "the feature … has been stable since … and no longer requires an attribute to enable".

    This can be seen in the way that https://github.com/rust-lang/rust/pull/93957#issuecomment-1079794660 failed after rebase:

    ```console
    error[E0635]: unknown feature `const_ptr_offset`
      --> $DIR/offset_from_ub.rs:1:35
       |
    LL | #![feature(const_ptr_offset_from, const_ptr_offset)]
       |                                   ^^^^^^^^^^^^^^^^
    ```

- We weren't enforcing that a particular feature is either stable everywhere or unstable everywhere, and that a feature that has been stabilized has the same stabilization version everywhere, both of which we enforce for the other stability attributes.

This PR updates the library feature collector to handle `rustc_const_stable`, and fixes places in the standard library and test suite where `rustc_const_stable` was being used in a way that does not meet the rules for a stability attribute.
This commit is contained in:
Dylan DPC 2022-04-02 03:34:21 +02:00 committed by GitHub
commit d7a24003d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 69 additions and 68 deletions

View File

@ -29,10 +29,11 @@ impl<'tcx> LibFeatureCollector<'tcx> {
}
fn extract(&self, attr: &Attribute) -> Option<(Symbol, Option<Symbol>, Span)> {
let stab_attrs = [sym::stable, sym::unstable, sym::rustc_const_unstable];
let stab_attrs =
[sym::stable, sym::unstable, sym::rustc_const_stable, sym::rustc_const_unstable];
// Find a stability attribute (i.e., `#[stable (..)]`, `#[unstable (..)]`,
// `#[rustc_const_unstable (..)]`).
// Find a stability attribute: one of #[stable(…)], #[unstable(…)],
// #[rustc_const_stable(…)], or #[rustc_const_unstable(…)].
if let Some(stab_attr) = stab_attrs.iter().find(|stab_attr| attr.has_name(**stab_attr)) {
let meta_kind = attr.meta_kind();
if let Some(MetaItemKind::List(ref metas)) = meta_kind {
@ -52,7 +53,9 @@ impl<'tcx> LibFeatureCollector<'tcx> {
// This additional check for stability is to make sure we
// don't emit additional, irrelevant errors for malformed
// attributes.
if *stab_attr != sym::stable || since.is_some() {
let is_unstable =
matches!(*stab_attr, sym::unstable | sym::rustc_const_unstable);
if since.is_some() || is_unstable {
return Some((feature, since, attr.span));
}
}

View File

@ -56,7 +56,7 @@ impl Layout {
/// must not overflow (i.e., the rounded value must be less than
/// or equal to `usize::MAX`).
#[stable(feature = "alloc_layout", since = "1.28.0")]
#[rustc_const_stable(feature = "const_alloc_layout", since = "1.50.0")]
#[rustc_const_stable(feature = "const_alloc_layout_size_align", since = "1.50.0")]
#[inline]
pub const fn from_size_align(size: usize, align: usize) -> Result<Self, LayoutError> {
if !align.is_power_of_two() {
@ -93,7 +93,7 @@ impl Layout {
/// This function is unsafe as it does not verify the preconditions from
/// [`Layout::from_size_align`].
#[stable(feature = "alloc_layout", since = "1.28.0")]
#[rustc_const_stable(feature = "alloc_layout", since = "1.36.0")]
#[rustc_const_stable(feature = "const_alloc_layout_unchecked", since = "1.36.0")]
#[must_use]
#[inline]
pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
@ -103,7 +103,7 @@ impl Layout {
/// The minimum size in bytes for a memory block of this layout.
#[stable(feature = "alloc_layout", since = "1.28.0")]
#[rustc_const_stable(feature = "const_alloc_layout", since = "1.50.0")]
#[rustc_const_stable(feature = "const_alloc_layout_size_align", since = "1.50.0")]
#[must_use]
#[inline]
pub const fn size(&self) -> usize {
@ -112,7 +112,7 @@ impl Layout {
/// The minimum byte alignment for a memory block of this layout.
#[stable(feature = "alloc_layout", since = "1.28.0")]
#[rustc_const_stable(feature = "const_alloc_layout", since = "1.50.0")]
#[rustc_const_stable(feature = "const_alloc_layout_size_align", since = "1.50.0")]
#[must_use = "this returns the minimum alignment, \
without modifying the layout"]
#[inline]

View File

@ -1092,7 +1092,7 @@ impl char {
/// ```
#[must_use]
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.32.0")]
#[rustc_const_stable(feature = "const_char_is_ascii", since = "1.32.0")]
#[inline]
pub const fn is_ascii(&self) -> bool {
*self as u32 <= 0x7F

View File

@ -1638,7 +1638,7 @@ extern "rust-intrinsic" {
/// let num_trailing = unsafe { cttz_nonzero(x) };
/// assert_eq!(num_trailing, 3);
/// ```
#[rustc_const_stable(feature = "const_cttz", since = "1.53.0")]
#[rustc_const_stable(feature = "const_cttz_nonzero", since = "1.53.0")]
pub fn cttz_nonzero<T: Copy>(x: T) -> T;
/// Reverses the bytes in an integer type `T`.
@ -1718,7 +1718,7 @@ extern "rust-intrinsic" {
/// Safe wrappers for this intrinsic are available on the integer
/// primitives via the `checked_div` method. For example,
/// [`u32::checked_div`]
#[rustc_const_stable(feature = "const_int_unchecked_arith", since = "1.52.0")]
#[rustc_const_stable(feature = "const_int_unchecked_div", since = "1.52.0")]
pub fn unchecked_div<T: Copy>(x: T, y: T) -> T;
/// Returns the remainder of an unchecked division, resulting in
/// undefined behavior when `y == 0` or `x == T::MIN && y == -1`
@ -1726,7 +1726,7 @@ extern "rust-intrinsic" {
/// Safe wrappers for this intrinsic are available on the integer
/// primitives via the `checked_rem` method. For example,
/// [`u32::checked_rem`]
#[rustc_const_stable(feature = "const_int_unchecked_arith", since = "1.52.0")]
#[rustc_const_stable(feature = "const_int_unchecked_rem", since = "1.52.0")]
pub fn unchecked_rem<T: Copy>(x: T, y: T) -> T;
/// Performs an unchecked left shift, resulting in undefined behavior when

View File

@ -97,7 +97,6 @@
// Library features:
#![feature(const_align_offset)]
#![feature(const_align_of_val)]
#![feature(const_alloc_layout)]
#![feature(const_arguments_as_str)]
#![feature(const_array_into_iter_constructors)]
#![feature(const_bigint_helper_methods)]

View File

@ -622,7 +622,7 @@ impl<T> MaybeUninit<T> {
/// // `x` had not been initialized yet, so this last line caused undefined behavior. ⚠️
/// ```
#[stable(feature = "maybe_uninit", since = "1.36.0")]
#[rustc_const_stable(feature = "const_maybe_uninit_assume_init", since = "1.59.0")]
#[rustc_const_stable(feature = "const_maybe_uninit_assume_init_by_value", since = "1.59.0")]
#[inline(always)]
#[rustc_diagnostic_item = "assume_init"]
#[track_caller]
@ -788,7 +788,7 @@ impl<T> MaybeUninit<T> {
/// }
/// ```
#[stable(feature = "maybe_uninit_ref", since = "1.55.0")]
#[rustc_const_stable(feature = "const_maybe_uninit_assume_init", since = "1.59.0")]
#[rustc_const_stable(feature = "const_maybe_uninit_assume_init_ref", since = "1.59.0")]
#[inline(always)]
pub const unsafe fn assume_init_ref(&self) -> &T {
// SAFETY: the caller must guarantee that `self` is initialized.

View File

@ -299,7 +299,7 @@ pub fn forget_unsized<T: ?Sized>(t: T) {
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_promotable]
#[rustc_const_stable(feature = "const_size_of", since = "1.24.0")]
#[rustc_const_stable(feature = "const_mem_size_of", since = "1.24.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "mem_size_of")]
pub const fn size_of<T>() -> usize {
intrinsics::size_of::<T>()
@ -581,7 +581,7 @@ pub const unsafe fn align_of_val_raw<T: ?Sized>(val: *const T) -> usize {
#[inline]
#[must_use]
#[stable(feature = "needs_drop", since = "1.21.0")]
#[rustc_const_stable(feature = "const_needs_drop", since = "1.36.0")]
#[rustc_const_stable(feature = "const_mem_needs_drop", since = "1.36.0")]
#[rustc_diagnostic_item = "needs_drop"]
pub const fn needs_drop<T>() -> bool {
intrinsics::needs_drop::<T>()

View File

@ -270,7 +270,7 @@ macro_rules! int_impl {
#[doc = concat!("assert_eq!(0, 0", stringify!($SelfT), ".reverse_bits());")]
/// ```
#[stable(feature = "reverse_bits", since = "1.37.0")]
#[rustc_const_stable(feature = "const_int_methods", since = "1.37.0")]
#[rustc_const_stable(feature = "reverse_bits", since = "1.37.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
@ -603,7 +603,7 @@ macro_rules! int_impl {
#[doc = concat!("assert_eq!((1", stringify!($SelfT), ").checked_div(0), None);")]
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_checked_int_methods", since = "1.52.0")]
#[rustc_const_stable(feature = "const_checked_int_div", since = "1.52.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
@ -656,7 +656,7 @@ macro_rules! int_impl {
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.checked_rem(-1), None);")]
/// ```
#[stable(feature = "wrapping", since = "1.7.0")]
#[rustc_const_stable(feature = "const_checked_int_methods", since = "1.52.0")]
#[rustc_const_stable(feature = "const_checked_int_div", since = "1.52.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]

View File

@ -281,7 +281,7 @@ impl u8 {
/// ```
#[must_use]
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.43.0")]
#[rustc_const_stable(feature = "const_u8_is_ascii", since = "1.43.0")]
#[inline]
pub const fn is_ascii(&self) -> bool {
*self & 128 == 0

View File

@ -74,7 +74,7 @@ macro_rules! nonzero_integers {
/// Returns the value as a primitive type.
#[$stability]
#[inline]
#[rustc_const_stable(feature = "nonzero", since = "1.34.0")]
#[rustc_const_stable(feature = "const_nonzero_get", since = "1.34.0")]
pub const fn get(self) -> $Int {
self.0
}

View File

@ -273,7 +273,7 @@ macro_rules! uint_impl {
#[doc = concat!("assert_eq!(0, 0", stringify!($SelfT), ".reverse_bits());")]
/// ```
#[stable(feature = "reverse_bits", since = "1.37.0")]
#[rustc_const_stable(feature = "const_math", since = "1.37.0")]
#[rustc_const_stable(feature = "reverse_bits", since = "1.37.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
@ -591,7 +591,7 @@ macro_rules! uint_impl {
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_div(0), None);")]
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_checked_int_methods", since = "1.52.0")]
#[rustc_const_stable(feature = "const_checked_int_div", since = "1.52.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
@ -642,7 +642,7 @@ macro_rules! uint_impl {
#[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_rem(0), None);")]
/// ```
#[stable(feature = "wrapping", since = "1.7.0")]
#[rustc_const_stable(feature = "const_checked_int_methods", since = "1.52.0")]
#[rustc_const_stable(feature = "const_checked_int_div", since = "1.52.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]

View File

@ -549,7 +549,7 @@ impl<T> Option<T> {
#[must_use = "if you intended to assert that this has a value, consider `.unwrap()` instead"]
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_option", since = "1.48.0")]
#[rustc_const_stable(feature = "const_option_basics", since = "1.48.0")]
pub const fn is_some(&self) -> bool {
matches!(*self, Some(_))
}
@ -592,7 +592,7 @@ impl<T> Option<T> {
`.and_then(|_| panic!(\"`Option` had a value when expected `None`\"))` instead"]
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_option", since = "1.48.0")]
#[rustc_const_stable(feature = "const_option_basics", since = "1.48.0")]
pub const fn is_none(&self) -> bool {
!self.is_some()
}
@ -621,7 +621,7 @@ impl<T> Option<T> {
/// println!("still can print text: {text:?}");
/// ```
#[inline]
#[rustc_const_stable(feature = "const_option", since = "1.48.0")]
#[rustc_const_stable(feature = "const_option_basics", since = "1.48.0")]
#[stable(feature = "rust1", since = "1.0.0")]
pub const fn as_ref(&self) -> Option<&T> {
match *self {

View File

@ -510,7 +510,7 @@ pub const fn null_mut<T>() -> *mut T {
/// see the [module documentation][crate::ptr] for details.
#[inline(always)]
#[must_use]
#[rustc_const_stable(feature = "strict_provenance", since = "1.61.0")]
#[rustc_const_stable(feature = "stable_things_using_strict_provenance", since = "1.61.0")]
#[unstable(feature = "strict_provenance", issue = "95228")]
pub const fn invalid<T>(addr: usize) -> *const T {
// FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
@ -537,7 +537,7 @@ pub const fn invalid<T>(addr: usize) -> *const T {
/// see the [module documentation][crate::ptr] for details.
#[inline(always)]
#[must_use]
#[rustc_const_stable(feature = "strict_provenance", since = "1.61.0")]
#[rustc_const_stable(feature = "stable_things_using_strict_provenance", since = "1.61.0")]
#[unstable(feature = "strict_provenance", issue = "95228")]
pub const fn invalid_mut<T>(addr: usize) -> *mut T {
// FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.

View File

@ -536,7 +536,7 @@ impl<T, E> Result<T, E> {
/// assert_eq!(x.is_ok(), false);
/// ```
#[must_use = "if you intended to assert that this is ok, consider `.unwrap()` instead"]
#[rustc_const_stable(feature = "const_result", since = "1.48.0")]
#[rustc_const_stable(feature = "const_result_basics", since = "1.48.0")]
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub const fn is_ok(&self) -> bool {
@ -580,7 +580,7 @@ impl<T, E> Result<T, E> {
/// assert_eq!(x.is_err(), true);
/// ```
#[must_use = "if you intended to assert that this is err, consider `.unwrap_err()` instead"]
#[rustc_const_stable(feature = "const_result", since = "1.48.0")]
#[rustc_const_stable(feature = "const_result_basics", since = "1.48.0")]
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub const fn is_err(&self) -> bool {
@ -698,7 +698,7 @@ impl<T, E> Result<T, E> {
/// assert_eq!(x.as_ref(), Err(&"Error"));
/// ```
#[inline]
#[rustc_const_stable(feature = "const_result", since = "1.48.0")]
#[rustc_const_stable(feature = "const_result_basics", since = "1.48.0")]
#[stable(feature = "rust1", since = "1.0.0")]
pub const fn as_ref(&self) -> Result<&T, &E> {
match *self {

View File

@ -2498,7 +2498,7 @@ macro_rules! atomic_int_ptr_sized {
stable(feature = "atomic_access", since = "1.15.0"),
stable(feature = "atomic_from", since = "1.23.0"),
stable(feature = "atomic_nand", since = "1.27.0"),
rustc_const_stable(feature = "const_integer_atomics", since = "1.24.0"),
rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"),
stable(feature = "rust1", since = "1.0.0"),
"isize",
"",
@ -2518,7 +2518,7 @@ macro_rules! atomic_int_ptr_sized {
stable(feature = "atomic_access", since = "1.15.0"),
stable(feature = "atomic_from", since = "1.23.0"),
stable(feature = "atomic_nand", since = "1.27.0"),
rustc_const_stable(feature = "const_integer_atomics", since = "1.24.0"),
rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"),
stable(feature = "rust1", since = "1.0.0"),
"usize",
"",

View File

@ -333,7 +333,7 @@ impl Duration {
///
/// [`subsec_nanos`]: Duration::subsec_nanos
#[stable(feature = "duration", since = "1.3.0")]
#[rustc_const_stable(feature = "duration", since = "1.32.0")]
#[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
#[must_use]
#[inline]
pub const fn as_secs(&self) -> u64 {
@ -356,7 +356,7 @@ impl Duration {
/// assert_eq!(duration.subsec_millis(), 432);
/// ```
#[stable(feature = "duration_extras", since = "1.27.0")]
#[rustc_const_stable(feature = "duration_extras", since = "1.32.0")]
#[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
#[must_use]
#[inline]
pub const fn subsec_millis(&self) -> u32 {
@ -379,7 +379,7 @@ impl Duration {
/// assert_eq!(duration.subsec_micros(), 234_567);
/// ```
#[stable(feature = "duration_extras", since = "1.27.0")]
#[rustc_const_stable(feature = "duration_extras", since = "1.32.0")]
#[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
#[must_use]
#[inline]
pub const fn subsec_micros(&self) -> u32 {
@ -402,7 +402,7 @@ impl Duration {
/// assert_eq!(duration.subsec_nanos(), 10_000_000);
/// ```
#[stable(feature = "duration", since = "1.3.0")]
#[rustc_const_stable(feature = "duration", since = "1.32.0")]
#[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
#[must_use]
#[inline]
pub const fn subsec_nanos(&self) -> u32 {

View File

@ -13,7 +13,6 @@
#![feature(const_convert)]
#![feature(const_heap)]
#![feature(const_maybe_uninit_as_mut_ptr)]
#![feature(const_maybe_uninit_assume_init)]
#![feature(const_maybe_uninit_assume_init_read)]
#![feature(const_nonnull_new)]
#![feature(const_num_from_num)]

View File

@ -235,7 +235,7 @@ impl IpAddr {
/// assert_eq!(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)).is_unspecified(), true);
/// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)).is_unspecified(), true);
/// ```
#[rustc_const_stable(feature = "const_ip", since = "1.50.0")]
#[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
#[stable(feature = "ip_shared", since = "1.12.0")]
#[must_use]
#[inline]
@ -259,7 +259,7 @@ impl IpAddr {
/// assert_eq!(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)).is_loopback(), true);
/// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1)).is_loopback(), true);
/// ```
#[rustc_const_stable(feature = "const_ip", since = "1.50.0")]
#[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
#[stable(feature = "ip_shared", since = "1.12.0")]
#[must_use]
#[inline]
@ -309,7 +309,7 @@ impl IpAddr {
/// assert_eq!(IpAddr::V4(Ipv4Addr::new(224, 254, 0, 0)).is_multicast(), true);
/// assert_eq!(IpAddr::V6(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0)).is_multicast(), true);
/// ```
#[rustc_const_stable(feature = "const_ip", since = "1.50.0")]
#[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
#[stable(feature = "ip_shared", since = "1.12.0")]
#[must_use]
#[inline]
@ -387,7 +387,7 @@ impl IpAddr {
/// assert_eq!(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 6)).is_ipv4(), true);
/// assert_eq!(IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0)).is_ipv4(), false);
/// ```
#[rustc_const_stable(feature = "const_ip", since = "1.50.0")]
#[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
#[stable(feature = "ipaddr_checker", since = "1.16.0")]
#[must_use]
#[inline]
@ -408,7 +408,7 @@ impl IpAddr {
/// assert_eq!(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 6)).is_ipv6(), false);
/// assert_eq!(IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0)).is_ipv6(), true);
/// ```
#[rustc_const_stable(feature = "const_ip", since = "1.50.0")]
#[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
#[stable(feature = "ipaddr_checker", since = "1.16.0")]
#[must_use]
#[inline]
@ -454,7 +454,7 @@ impl Ipv4Addr {
///
/// let addr = Ipv4Addr::new(127, 0, 0, 1);
/// ```
#[rustc_const_stable(feature = "const_ipv4", since = "1.32.0")]
#[rustc_const_stable(feature = "const_ip_32", since = "1.32.0")]
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use]
#[inline]
@ -516,7 +516,7 @@ impl Ipv4Addr {
/// let addr = Ipv4Addr::new(127, 0, 0, 1);
/// assert_eq!(addr.octets(), [127, 0, 0, 1]);
/// ```
#[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
#[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use]
#[inline]
@ -540,7 +540,7 @@ impl Ipv4Addr {
/// assert_eq!(Ipv4Addr::new(0, 0, 0, 0).is_unspecified(), true);
/// assert_eq!(Ipv4Addr::new(45, 22, 13, 197).is_unspecified(), false);
/// ```
#[rustc_const_stable(feature = "const_ipv4", since = "1.32.0")]
#[rustc_const_stable(feature = "const_ip_32", since = "1.32.0")]
#[stable(feature = "ip_shared", since = "1.12.0")]
#[must_use]
#[inline]
@ -562,7 +562,7 @@ impl Ipv4Addr {
/// assert_eq!(Ipv4Addr::new(127, 0, 0, 1).is_loopback(), true);
/// assert_eq!(Ipv4Addr::new(45, 22, 13, 197).is_loopback(), false);
/// ```
#[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
#[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
#[stable(since = "1.7.0", feature = "ip_17")]
#[must_use]
#[inline]
@ -593,7 +593,7 @@ impl Ipv4Addr {
/// assert_eq!(Ipv4Addr::new(192, 168, 0, 2).is_private(), true);
/// assert_eq!(Ipv4Addr::new(192, 169, 0, 2).is_private(), false);
/// ```
#[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
#[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
#[stable(since = "1.7.0", feature = "ip_17")]
#[must_use]
#[inline]
@ -621,7 +621,7 @@ impl Ipv4Addr {
/// assert_eq!(Ipv4Addr::new(169, 254, 10, 65).is_link_local(), true);
/// assert_eq!(Ipv4Addr::new(16, 89, 10, 65).is_link_local(), false);
/// ```
#[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
#[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
#[stable(since = "1.7.0", feature = "ip_17")]
#[must_use]
#[inline]
@ -823,7 +823,7 @@ impl Ipv4Addr {
/// assert_eq!(Ipv4Addr::new(236, 168, 10, 65).is_multicast(), true);
/// assert_eq!(Ipv4Addr::new(172, 16, 10, 65).is_multicast(), false);
/// ```
#[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
#[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
#[stable(since = "1.7.0", feature = "ip_17")]
#[must_use]
#[inline]
@ -845,7 +845,7 @@ impl Ipv4Addr {
/// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_broadcast(), true);
/// assert_eq!(Ipv4Addr::new(236, 168, 10, 65).is_broadcast(), false);
/// ```
#[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
#[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
#[stable(since = "1.7.0", feature = "ip_17")]
#[must_use]
#[inline]
@ -873,7 +873,7 @@ impl Ipv4Addr {
/// assert_eq!(Ipv4Addr::new(203, 0, 113, 6).is_documentation(), true);
/// assert_eq!(Ipv4Addr::new(193, 34, 17, 19).is_documentation(), false);
/// ```
#[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
#[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
#[stable(since = "1.7.0", feature = "ip_17")]
#[must_use]
#[inline]
@ -901,7 +901,7 @@ impl Ipv4Addr {
/// Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0xc000, 0x2ff)
/// );
/// ```
#[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
#[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
@ -928,7 +928,7 @@ impl Ipv4Addr {
/// assert_eq!(Ipv4Addr::new(192, 0, 2, 255).to_ipv6_mapped(),
/// Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x2ff));
/// ```
#[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
#[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
@ -1216,7 +1216,7 @@ impl Ipv6Addr {
///
/// let addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff);
/// ```
#[rustc_const_stable(feature = "const_ipv6", since = "1.32.0")]
#[rustc_const_stable(feature = "const_ip_32", since = "1.32.0")]
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use]
#[inline]
@ -1278,7 +1278,7 @@ impl Ipv6Addr {
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).segments(),
/// [0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff]);
/// ```
#[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")]
#[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use]
#[inline]
@ -1315,7 +1315,7 @@ impl Ipv6Addr {
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unspecified(), false);
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0).is_unspecified(), true);
/// ```
#[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")]
#[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
#[stable(since = "1.7.0", feature = "ip_17")]
#[must_use]
#[inline]
@ -1339,7 +1339,7 @@ impl Ipv6Addr {
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_loopback(), false);
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1).is_loopback(), true);
/// ```
#[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")]
#[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
#[stable(since = "1.7.0", feature = "ip_17")]
#[must_use]
#[inline]
@ -1624,7 +1624,7 @@ impl Ipv6Addr {
/// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).is_multicast(), true);
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_multicast(), false);
/// ```
#[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")]
#[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
#[stable(since = "1.7.0", feature = "ip_17")]
#[must_use]
#[inline]
@ -1693,7 +1693,7 @@ impl Ipv6Addr {
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).to_ipv4(),
/// Some(Ipv4Addr::new(0, 0, 0, 1)));
/// ```
#[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")]
#[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
@ -1740,7 +1740,7 @@ impl Ipv6Addr {
/// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).octets(),
/// [255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
/// ```
#[rustc_const_stable(feature = "const_ipv6", since = "1.32.0")]
#[rustc_const_stable(feature = "const_ip_32", since = "1.32.0")]
#[stable(feature = "ipv6_to_octets", since = "1.12.0")]
#[must_use]
#[inline]

View File

@ -64,7 +64,7 @@ impl Foo {
// @has 'foo/struct.Foo.html' '//*[@id="method.stable_impl"]/h4[@class="code-header"]' 'pub const fn stable_impl() -> u32'
// @has - '//span[@class="since"]' '1.0.0 (const: 1.2.0)'
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "rust1", since = "1.2.0")]
#[rustc_const_stable(feature = "const2", since = "1.2.0")]
pub const fn stable_impl() -> u32 { 42 }
}
@ -75,12 +75,12 @@ impl Bar {
// Do not show non-const stabilities that are the same as the enclosing item.
// @matches 'foo/struct.Bar.html' '//span[@class="since"]' '^const: 1.2.0$'
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "rust1", since = "1.2.0")]
#[rustc_const_stable(feature = "const2", since = "1.2.0")]
pub const fn stable_impl() -> u32 { 42 }
// Show const-stability even for unstable functions.
// @matches 'foo/struct.Bar.html' '//span[@class="since"]' '^const: 1.3.0$'
#[unstable(feature = "foo2", issue = "none")]
#[rustc_const_stable(feature = "rust1", since = "1.3.0")]
#[rustc_const_stable(feature = "const3", since = "1.3.0")]
pub const fn const_stable_unstable() -> u32 { 42 }
}

View File

@ -1,7 +1,7 @@
// error-pattern: any use of this value will cause an error
#![feature(never_type)]
#![feature(const_maybe_uninit_assume_init, const_assert_type2)]
#![feature(const_assert_type2)]
#![feature(core_intrinsics)]
use std::intrinsics;

View File

@ -2,7 +2,7 @@
#![feature(repr_simd)]
#![feature(platform_intrinsics)]
#![feature(staged_api)]
#![stable(feature = "foo", since = "1.33.7")]
#![stable(feature = "foo", since = "1.3.37")]
#![allow(non_camel_case_types)]
#[repr(simd)] struct i8x1(i8);