Skip to content

Commit d7a2400

Browse files
authored
Rollup merge of rust-lang#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](https://github.com/rust-lang/rust/blob/551b4fa395fa588d91cbecfb0cdfe1baa02670cf/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 rust-lang#93957 (comment) 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.
2 parents eb82fac + 971ecff commit d7a2400

File tree

21 files changed

+69
-68
lines changed

21 files changed

+69
-68
lines changed

compiler/rustc_passes/src/lib_features.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ impl<'tcx> LibFeatureCollector<'tcx> {
2929
}
3030

3131
fn extract(&self, attr: &Attribute) -> Option<(Symbol, Option<Symbol>, Span)> {
32-
let stab_attrs = [sym::stable, sym::unstable, sym::rustc_const_unstable];
32+
let stab_attrs =
33+
[sym::stable, sym::unstable, sym::rustc_const_stable, sym::rustc_const_unstable];
3334

34-
// Find a stability attribute (i.e., `#[stable (..)]`, `#[unstable (..)]`,
35-
// `#[rustc_const_unstable (..)]`).
35+
// Find a stability attribute: one of #[stable(…)], #[unstable(…)],
36+
// #[rustc_const_stable(…)], or #[rustc_const_unstable(…)].
3637
if let Some(stab_attr) = stab_attrs.iter().find(|stab_attr| attr.has_name(**stab_attr)) {
3738
let meta_kind = attr.meta_kind();
3839
if let Some(MetaItemKind::List(ref metas)) = meta_kind {
@@ -52,7 +53,9 @@ impl<'tcx> LibFeatureCollector<'tcx> {
5253
// This additional check for stability is to make sure we
5354
// don't emit additional, irrelevant errors for malformed
5455
// attributes.
55-
if *stab_attr != sym::stable || since.is_some() {
56+
let is_unstable =
57+
matches!(*stab_attr, sym::unstable | sym::rustc_const_unstable);
58+
if since.is_some() || is_unstable {
5659
return Some((feature, since, attr.span));
5760
}
5861
}

library/core/src/alloc/layout.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ impl Layout {
5656
/// must not overflow (i.e., the rounded value must be less than
5757
/// or equal to `usize::MAX`).
5858
#[stable(feature = "alloc_layout", since = "1.28.0")]
59-
#[rustc_const_stable(feature = "const_alloc_layout", since = "1.50.0")]
59+
#[rustc_const_stable(feature = "const_alloc_layout_size_align", since = "1.50.0")]
6060
#[inline]
6161
pub const fn from_size_align(size: usize, align: usize) -> Result<Self, LayoutError> {
6262
if !align.is_power_of_two() {
@@ -93,7 +93,7 @@ impl Layout {
9393
/// This function is unsafe as it does not verify the preconditions from
9494
/// [`Layout::from_size_align`].
9595
#[stable(feature = "alloc_layout", since = "1.28.0")]
96-
#[rustc_const_stable(feature = "alloc_layout", since = "1.36.0")]
96+
#[rustc_const_stable(feature = "const_alloc_layout_unchecked", since = "1.36.0")]
9797
#[must_use]
9898
#[inline]
9999
pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
@@ -103,7 +103,7 @@ impl Layout {
103103

104104
/// The minimum size in bytes for a memory block of this layout.
105105
#[stable(feature = "alloc_layout", since = "1.28.0")]
106-
#[rustc_const_stable(feature = "const_alloc_layout", since = "1.50.0")]
106+
#[rustc_const_stable(feature = "const_alloc_layout_size_align", since = "1.50.0")]
107107
#[must_use]
108108
#[inline]
109109
pub const fn size(&self) -> usize {
@@ -112,7 +112,7 @@ impl Layout {
112112

113113
/// The minimum byte alignment for a memory block of this layout.
114114
#[stable(feature = "alloc_layout", since = "1.28.0")]
115-
#[rustc_const_stable(feature = "const_alloc_layout", since = "1.50.0")]
115+
#[rustc_const_stable(feature = "const_alloc_layout_size_align", since = "1.50.0")]
116116
#[must_use = "this returns the minimum alignment, \
117117
without modifying the layout"]
118118
#[inline]

library/core/src/char/methods.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1092,7 +1092,7 @@ impl char {
10921092
/// ```
10931093
#[must_use]
10941094
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
1095-
#[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.32.0")]
1095+
#[rustc_const_stable(feature = "const_char_is_ascii", since = "1.32.0")]
10961096
#[inline]
10971097
pub const fn is_ascii(&self) -> bool {
10981098
*self as u32 <= 0x7F

library/core/src/intrinsics.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1638,7 +1638,7 @@ extern "rust-intrinsic" {
16381638
/// let num_trailing = unsafe { cttz_nonzero(x) };
16391639
/// assert_eq!(num_trailing, 3);
16401640
/// ```
1641-
#[rustc_const_stable(feature = "const_cttz", since = "1.53.0")]
1641+
#[rustc_const_stable(feature = "const_cttz_nonzero", since = "1.53.0")]
16421642
pub fn cttz_nonzero<T: Copy>(x: T) -> T;
16431643

16441644
/// Reverses the bytes in an integer type `T`.
@@ -1718,15 +1718,15 @@ extern "rust-intrinsic" {
17181718
/// Safe wrappers for this intrinsic are available on the integer
17191719
/// primitives via the `checked_div` method. For example,
17201720
/// [`u32::checked_div`]
1721-
#[rustc_const_stable(feature = "const_int_unchecked_arith", since = "1.52.0")]
1721+
#[rustc_const_stable(feature = "const_int_unchecked_div", since = "1.52.0")]
17221722
pub fn unchecked_div<T: Copy>(x: T, y: T) -> T;
17231723
/// Returns the remainder of an unchecked division, resulting in
17241724
/// undefined behavior when `y == 0` or `x == T::MIN && y == -1`
17251725
///
17261726
/// Safe wrappers for this intrinsic are available on the integer
17271727
/// primitives via the `checked_rem` method. For example,
17281728
/// [`u32::checked_rem`]
1729-
#[rustc_const_stable(feature = "const_int_unchecked_arith", since = "1.52.0")]
1729+
#[rustc_const_stable(feature = "const_int_unchecked_rem", since = "1.52.0")]
17301730
pub fn unchecked_rem<T: Copy>(x: T, y: T) -> T;
17311731

17321732
/// Performs an unchecked left shift, resulting in undefined behavior when

library/core/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@
9797
// Library features:
9898
#![feature(const_align_offset)]
9999
#![feature(const_align_of_val)]
100-
#![feature(const_alloc_layout)]
101100
#![feature(const_arguments_as_str)]
102101
#![feature(const_array_into_iter_constructors)]
103102
#![feature(const_bigint_helper_methods)]

library/core/src/mem/maybe_uninit.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ impl<T> MaybeUninit<T> {
622622
/// // `x` had not been initialized yet, so this last line caused undefined behavior. ⚠️
623623
/// ```
624624
#[stable(feature = "maybe_uninit", since = "1.36.0")]
625-
#[rustc_const_stable(feature = "const_maybe_uninit_assume_init", since = "1.59.0")]
625+
#[rustc_const_stable(feature = "const_maybe_uninit_assume_init_by_value", since = "1.59.0")]
626626
#[inline(always)]
627627
#[rustc_diagnostic_item = "assume_init"]
628628
#[track_caller]
@@ -788,7 +788,7 @@ impl<T> MaybeUninit<T> {
788788
/// }
789789
/// ```
790790
#[stable(feature = "maybe_uninit_ref", since = "1.55.0")]
791-
#[rustc_const_stable(feature = "const_maybe_uninit_assume_init", since = "1.59.0")]
791+
#[rustc_const_stable(feature = "const_maybe_uninit_assume_init_ref", since = "1.59.0")]
792792
#[inline(always)]
793793
pub const unsafe fn assume_init_ref(&self) -> &T {
794794
// SAFETY: the caller must guarantee that `self` is initialized.

library/core/src/mem/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ pub fn forget_unsized<T: ?Sized>(t: T) {
299299
#[must_use]
300300
#[stable(feature = "rust1", since = "1.0.0")]
301301
#[rustc_promotable]
302-
#[rustc_const_stable(feature = "const_size_of", since = "1.24.0")]
302+
#[rustc_const_stable(feature = "const_mem_size_of", since = "1.24.0")]
303303
#[cfg_attr(not(test), rustc_diagnostic_item = "mem_size_of")]
304304
pub const fn size_of<T>() -> usize {
305305
intrinsics::size_of::<T>()
@@ -581,7 +581,7 @@ pub const unsafe fn align_of_val_raw<T: ?Sized>(val: *const T) -> usize {
581581
#[inline]
582582
#[must_use]
583583
#[stable(feature = "needs_drop", since = "1.21.0")]
584-
#[rustc_const_stable(feature = "const_needs_drop", since = "1.36.0")]
584+
#[rustc_const_stable(feature = "const_mem_needs_drop", since = "1.36.0")]
585585
#[rustc_diagnostic_item = "needs_drop"]
586586
pub const fn needs_drop<T>() -> bool {
587587
intrinsics::needs_drop::<T>()

library/core/src/num/int_macros.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ macro_rules! int_impl {
270270
#[doc = concat!("assert_eq!(0, 0", stringify!($SelfT), ".reverse_bits());")]
271271
/// ```
272272
#[stable(feature = "reverse_bits", since = "1.37.0")]
273-
#[rustc_const_stable(feature = "const_int_methods", since = "1.37.0")]
273+
#[rustc_const_stable(feature = "reverse_bits", since = "1.37.0")]
274274
#[must_use = "this returns the result of the operation, \
275275
without modifying the original"]
276276
#[inline(always)]
@@ -603,7 +603,7 @@ macro_rules! int_impl {
603603
#[doc = concat!("assert_eq!((1", stringify!($SelfT), ").checked_div(0), None);")]
604604
/// ```
605605
#[stable(feature = "rust1", since = "1.0.0")]
606-
#[rustc_const_stable(feature = "const_checked_int_methods", since = "1.52.0")]
606+
#[rustc_const_stable(feature = "const_checked_int_div", since = "1.52.0")]
607607
#[must_use = "this returns the result of the operation, \
608608
without modifying the original"]
609609
#[inline]
@@ -656,7 +656,7 @@ macro_rules! int_impl {
656656
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.checked_rem(-1), None);")]
657657
/// ```
658658
#[stable(feature = "wrapping", since = "1.7.0")]
659-
#[rustc_const_stable(feature = "const_checked_int_methods", since = "1.52.0")]
659+
#[rustc_const_stable(feature = "const_checked_int_div", since = "1.52.0")]
660660
#[must_use = "this returns the result of the operation, \
661661
without modifying the original"]
662662
#[inline]

library/core/src/num/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ impl u8 {
281281
/// ```
282282
#[must_use]
283283
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
284-
#[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.43.0")]
284+
#[rustc_const_stable(feature = "const_u8_is_ascii", since = "1.43.0")]
285285
#[inline]
286286
pub const fn is_ascii(&self) -> bool {
287287
*self & 128 == 0

library/core/src/num/nonzero.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ macro_rules! nonzero_integers {
7474
/// Returns the value as a primitive type.
7575
#[$stability]
7676
#[inline]
77-
#[rustc_const_stable(feature = "nonzero", since = "1.34.0")]
77+
#[rustc_const_stable(feature = "const_nonzero_get", since = "1.34.0")]
7878
pub const fn get(self) -> $Int {
7979
self.0
8080
}

library/core/src/num/uint_macros.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ macro_rules! uint_impl {
273273
#[doc = concat!("assert_eq!(0, 0", stringify!($SelfT), ".reverse_bits());")]
274274
/// ```
275275
#[stable(feature = "reverse_bits", since = "1.37.0")]
276-
#[rustc_const_stable(feature = "const_math", since = "1.37.0")]
276+
#[rustc_const_stable(feature = "reverse_bits", since = "1.37.0")]
277277
#[must_use = "this returns the result of the operation, \
278278
without modifying the original"]
279279
#[inline(always)]
@@ -591,7 +591,7 @@ macro_rules! uint_impl {
591591
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_div(0), None);")]
592592
/// ```
593593
#[stable(feature = "rust1", since = "1.0.0")]
594-
#[rustc_const_stable(feature = "const_checked_int_methods", since = "1.52.0")]
594+
#[rustc_const_stable(feature = "const_checked_int_div", since = "1.52.0")]
595595
#[must_use = "this returns the result of the operation, \
596596
without modifying the original"]
597597
#[inline]
@@ -642,7 +642,7 @@ macro_rules! uint_impl {
642642
#[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_rem(0), None);")]
643643
/// ```
644644
#[stable(feature = "wrapping", since = "1.7.0")]
645-
#[rustc_const_stable(feature = "const_checked_int_methods", since = "1.52.0")]
645+
#[rustc_const_stable(feature = "const_checked_int_div", since = "1.52.0")]
646646
#[must_use = "this returns the result of the operation, \
647647
without modifying the original"]
648648
#[inline]

library/core/src/option.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ impl<T> Option<T> {
549549
#[must_use = "if you intended to assert that this has a value, consider `.unwrap()` instead"]
550550
#[inline]
551551
#[stable(feature = "rust1", since = "1.0.0")]
552-
#[rustc_const_stable(feature = "const_option", since = "1.48.0")]
552+
#[rustc_const_stable(feature = "const_option_basics", since = "1.48.0")]
553553
pub const fn is_some(&self) -> bool {
554554
matches!(*self, Some(_))
555555
}
@@ -592,7 +592,7 @@ impl<T> Option<T> {
592592
`.and_then(|_| panic!(\"`Option` had a value when expected `None`\"))` instead"]
593593
#[inline]
594594
#[stable(feature = "rust1", since = "1.0.0")]
595-
#[rustc_const_stable(feature = "const_option", since = "1.48.0")]
595+
#[rustc_const_stable(feature = "const_option_basics", since = "1.48.0")]
596596
pub const fn is_none(&self) -> bool {
597597
!self.is_some()
598598
}
@@ -621,7 +621,7 @@ impl<T> Option<T> {
621621
/// println!("still can print text: {text:?}");
622622
/// ```
623623
#[inline]
624-
#[rustc_const_stable(feature = "const_option", since = "1.48.0")]
624+
#[rustc_const_stable(feature = "const_option_basics", since = "1.48.0")]
625625
#[stable(feature = "rust1", since = "1.0.0")]
626626
pub const fn as_ref(&self) -> Option<&T> {
627627
match *self {

library/core/src/ptr/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ pub const fn null_mut<T>() -> *mut T {
510510
/// see the [module documentation][crate::ptr] for details.
511511
#[inline(always)]
512512
#[must_use]
513-
#[rustc_const_stable(feature = "strict_provenance", since = "1.61.0")]
513+
#[rustc_const_stable(feature = "stable_things_using_strict_provenance", since = "1.61.0")]
514514
#[unstable(feature = "strict_provenance", issue = "95228")]
515515
pub const fn invalid<T>(addr: usize) -> *const T {
516516
// 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 {
537537
/// see the [module documentation][crate::ptr] for details.
538538
#[inline(always)]
539539
#[must_use]
540-
#[rustc_const_stable(feature = "strict_provenance", since = "1.61.0")]
540+
#[rustc_const_stable(feature = "stable_things_using_strict_provenance", since = "1.61.0")]
541541
#[unstable(feature = "strict_provenance", issue = "95228")]
542542
pub const fn invalid_mut<T>(addr: usize) -> *mut T {
543543
// FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.

library/core/src/result.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ impl<T, E> Result<T, E> {
536536
/// assert_eq!(x.is_ok(), false);
537537
/// ```
538538
#[must_use = "if you intended to assert that this is ok, consider `.unwrap()` instead"]
539-
#[rustc_const_stable(feature = "const_result", since = "1.48.0")]
539+
#[rustc_const_stable(feature = "const_result_basics", since = "1.48.0")]
540540
#[inline]
541541
#[stable(feature = "rust1", since = "1.0.0")]
542542
pub const fn is_ok(&self) -> bool {
@@ -580,7 +580,7 @@ impl<T, E> Result<T, E> {
580580
/// assert_eq!(x.is_err(), true);
581581
/// ```
582582
#[must_use = "if you intended to assert that this is err, consider `.unwrap_err()` instead"]
583-
#[rustc_const_stable(feature = "const_result", since = "1.48.0")]
583+
#[rustc_const_stable(feature = "const_result_basics", since = "1.48.0")]
584584
#[inline]
585585
#[stable(feature = "rust1", since = "1.0.0")]
586586
pub const fn is_err(&self) -> bool {
@@ -698,7 +698,7 @@ impl<T, E> Result<T, E> {
698698
/// assert_eq!(x.as_ref(), Err(&"Error"));
699699
/// ```
700700
#[inline]
701-
#[rustc_const_stable(feature = "const_result", since = "1.48.0")]
701+
#[rustc_const_stable(feature = "const_result_basics", since = "1.48.0")]
702702
#[stable(feature = "rust1", since = "1.0.0")]
703703
pub const fn as_ref(&self) -> Result<&T, &E> {
704704
match *self {

library/core/src/sync/atomic.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2498,7 +2498,7 @@ macro_rules! atomic_int_ptr_sized {
24982498
stable(feature = "atomic_access", since = "1.15.0"),
24992499
stable(feature = "atomic_from", since = "1.23.0"),
25002500
stable(feature = "atomic_nand", since = "1.27.0"),
2501-
rustc_const_stable(feature = "const_integer_atomics", since = "1.24.0"),
2501+
rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"),
25022502
stable(feature = "rust1", since = "1.0.0"),
25032503
"isize",
25042504
"",
@@ -2518,7 +2518,7 @@ macro_rules! atomic_int_ptr_sized {
25182518
stable(feature = "atomic_access", since = "1.15.0"),
25192519
stable(feature = "atomic_from", since = "1.23.0"),
25202520
stable(feature = "atomic_nand", since = "1.27.0"),
2521-
rustc_const_stable(feature = "const_integer_atomics", since = "1.24.0"),
2521+
rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"),
25222522
stable(feature = "rust1", since = "1.0.0"),
25232523
"usize",
25242524
"",

library/core/src/time.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ impl Duration {
333333
///
334334
/// [`subsec_nanos`]: Duration::subsec_nanos
335335
#[stable(feature = "duration", since = "1.3.0")]
336-
#[rustc_const_stable(feature = "duration", since = "1.32.0")]
336+
#[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
337337
#[must_use]
338338
#[inline]
339339
pub const fn as_secs(&self) -> u64 {
@@ -356,7 +356,7 @@ impl Duration {
356356
/// assert_eq!(duration.subsec_millis(), 432);
357357
/// ```
358358
#[stable(feature = "duration_extras", since = "1.27.0")]
359-
#[rustc_const_stable(feature = "duration_extras", since = "1.32.0")]
359+
#[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
360360
#[must_use]
361361
#[inline]
362362
pub const fn subsec_millis(&self) -> u32 {
@@ -379,7 +379,7 @@ impl Duration {
379379
/// assert_eq!(duration.subsec_micros(), 234_567);
380380
/// ```
381381
#[stable(feature = "duration_extras", since = "1.27.0")]
382-
#[rustc_const_stable(feature = "duration_extras", since = "1.32.0")]
382+
#[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
383383
#[must_use]
384384
#[inline]
385385
pub const fn subsec_micros(&self) -> u32 {
@@ -402,7 +402,7 @@ impl Duration {
402402
/// assert_eq!(duration.subsec_nanos(), 10_000_000);
403403
/// ```
404404
#[stable(feature = "duration", since = "1.3.0")]
405-
#[rustc_const_stable(feature = "duration", since = "1.32.0")]
405+
#[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
406406
#[must_use]
407407
#[inline]
408408
pub const fn subsec_nanos(&self) -> u32 {

library/core/tests/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#![feature(const_convert)]
1414
#![feature(const_heap)]
1515
#![feature(const_maybe_uninit_as_mut_ptr)]
16-
#![feature(const_maybe_uninit_assume_init)]
1716
#![feature(const_maybe_uninit_assume_init_read)]
1817
#![feature(const_nonnull_new)]
1918
#![feature(const_num_from_num)]

0 commit comments

Comments
 (0)