diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 6d4db275191fb..fbb9d3f3f3c37 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -274,10 +274,14 @@ pub fn find_stability( /// Collects stability info from `rustc_const_stable`/`rustc_const_unstable`/`rustc_promotable` /// attributes in `attrs`. Returns `None` if no stability attributes are found. +/// +/// `inherited_feature_gate` says which feature gate this function should be under if it doesn't +/// declare a gate itself, but has `#[rustc_const_stable_indirect]`. pub fn find_const_stability( sess: &Session, attrs: &[Attribute], item_sp: Span, + inherited_feature_gate: Option, ) -> Option<(ConstStability, Span)> { let mut const_stab: Option<(ConstStability, Span)> = None; let mut promotable = false; @@ -351,8 +355,11 @@ pub fn find_const_stability( } } _ => { + // `#[rustc_const_stable_indirect]` implicitly makes the function unstably const, + // inheriting the feature gate from `#[unstable]` if it xists, or without any + // feature gate otherwise. let c = ConstStability { - feature: None, + feature: inherited_feature_gate, safe_to_expose_on_stable: true, promotable: false, level: StabilityLevel::Unstable { diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index d0552a754feb0..c28164fa15b49 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -865,7 +865,11 @@ impl SyntaxExtension { }) .unwrap_or_else(|| (None, helper_attrs)); let stability = attr::find_stability(sess, attrs, span); - let const_stability = attr::find_const_stability(sess, attrs, span); + // FIXME: this will give a different result than the normal stability computation, since we + // don't inherit stability from the parent. But that's true even for `stability` above so + // it's probably okay? + let const_stability = + attr::find_const_stability(sess, attrs, span, stability.map(|(s, _)| s.feature)); let body_stability = attr::find_body_stability(sess, attrs); if let Some((_, sp)) = const_stability { sess.dcx().emit_err(errors::MacroConstStability { diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 2b693b20eed8a..a36de35c698e4 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -95,6 +95,10 @@ passes_collapse_debuginfo = passes_confusables = attribute should be applied to an inherent method .label = not an inherent method +passes_const_stable_not_stable = + attribute `#[rustc_const_stable]` can only be applied to functions that are declared `#[stable]` + .label = attribute specified here + passes_continue_labeled_block = `continue` pointing to a labeled block .label = labeled blocks cannot be `continue`'d @@ -450,7 +454,7 @@ passes_may_dangle = passes_maybe_string_interpolation = you might have meant to use string interpolation in this string literal passes_missing_const_err = - attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` + attributes `#[rustc_const_unstable]`, `#[rustc_const_stable]` and `#[rustc_const_stable_indirect]` require the function or method to be `const` .help = make the function or method const .label = attribute specified here diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 29a087bf75975..42c8edf5bb765 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1544,6 +1544,7 @@ pub(crate) struct DuplicateFeatureErr { pub span: Span, pub feature: Symbol, } + #[derive(Diagnostic)] #[diag(passes_missing_const_err)] pub(crate) struct MissingConstErr { @@ -1554,6 +1555,15 @@ pub(crate) struct MissingConstErr { pub const_span: Span, } +#[derive(Diagnostic)] +#[diag(passes_const_stable_not_stable)] +pub(crate) struct ConstStableNotStable { + #[primary_span] + pub fn_sig_span: Span, + #[label] + pub const_span: Span, +} + #[derive(LintDiagnostic)] pub(crate) enum MultipleDeadCodes<'tcx> { #[diag(passes_dead_codes)] diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 3eb6be218a7cf..ec289d2ec69b0 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -162,19 +162,32 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { } let stab = attr::find_stability(self.tcx.sess, attrs, item_sp); - let const_stab = attr::find_const_stability(self.tcx.sess, attrs, item_sp); + let const_stab = attr::find_const_stability( + self.tcx.sess, + attrs, + item_sp, + // Compute the feature gate we inherit if this + // doesn't have its own feature gate. + self.parent_const_stab.and_then(|c| c.feature).or_else(|| { + // Infer the const feature gate from the regular feature gate, + // but only if that regular gate is unstable. + if let Some((s, _)) = stab { + s.is_unstable().then_some(s.feature) + } else if inherit_deprecation.yes() + && let Some(parent_stab) = self.parent_stab + && parent_stab.is_unstable() + { + Some(parent_stab.feature) + } else { + None + } + }), + ); let body_stab = attr::find_body_stability(self.tcx.sess, attrs); - let mut const_span = None; - - let const_stab = const_stab.map(|(const_stab, const_span_node)| { - self.index.const_stab_map.insert(def_id, const_stab); - const_span = Some(const_span_node); - const_stab - }); // If the current node is a function, has const stability attributes and if it doesn not have an intrinsic ABI, // check if the function/method is const or the parent impl block is const - if let (Some(const_span), Some(fn_sig)) = (const_span, fn_sig) + if let (Some((_, const_span)), Some(fn_sig)) = (const_stab, fn_sig) && fn_sig.header.abi != Abi::RustIntrinsic && !fn_sig.header.is_const() && (!self.in_trait_impl || !self.tcx.is_const_fn_raw(def_id.to_def_id())) @@ -184,6 +197,22 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { .emit_err(errors::MissingConstErr { fn_sig_span: fn_sig.span, const_span }); } + // If this is marked const *stable*, it must also be regular-stable. + if let Some((const_stab, const_span)) = const_stab + && let Some(fn_sig) = fn_sig + && const_stab.is_const_stable() + && !stab.is_some_and(|(s, _)| s.is_stable()) + { + self.tcx + .dcx() + .emit_err(errors::ConstStableNotStable { fn_sig_span: fn_sig.span, const_span }); + } + + let const_stab = const_stab.map(|(const_stab, _span)| { + self.index.const_stab_map.insert(def_id, const_stab); + const_stab + }); + // `impl const Trait for Type` items forward their const stability to their // immediate children. if const_stab.is_none() { @@ -274,8 +303,6 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { } } - // Every `const fn` that has stability should also have const-stability. - self.recurse_with_stability_attrs( depr.map(|(d, _)| DeprecationEntry::local(d, def_id)), stab, @@ -724,7 +751,15 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { if features.staged_api { let attrs = self.tcx.hir().attrs(item.hir_id()); let stab = attr::find_stability(self.tcx.sess, attrs, item.span); - let const_stab = attr::find_const_stability(self.tcx.sess, attrs, item.span); + // FIXME: this will give a different result than the normal stability + // computation, since we don't inherit stability from the parent. But that's + // true even for `stab` above so it's probably okay? + let const_stab = attr::find_const_stability( + self.tcx.sess, + attrs, + item.span, + stab.map(|(s, _)| s.feature), + ); // If this impl block has an #[unstable] attribute, give an // error if all involved types and traits are stable, because diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index 4a681a38144b1..ed170f1d09541 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -302,7 +302,6 @@ impl Layout { /// This can return at most `Alignment::MAX` (aka `isize::MAX + 1`) /// because the original size is at most `isize::MAX`. #[inline] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] const fn size_rounded_up_to_custom_align(&self, align: Alignment) -> usize { // SAFETY: // Rounded up value is: @@ -507,7 +506,6 @@ impl Layout { return inner(T::LAYOUT, n); #[inline] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] const fn inner(element_layout: Layout, n: usize) -> Result { let Layout { size: element_size, align } = element_layout; diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 15b00b9aa442c..0f4386190ee4c 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -137,11 +137,11 @@ enum FromBytesWithNulErrorKind { // FIXME: const stability attributes should not be required here, I think impl FromBytesWithNulError { - #[rustc_const_stable(feature = "const_cstr_methods", since = "1.72.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_cstr_methods", since = "1.72.0"))] const fn interior_nul(pos: usize) -> FromBytesWithNulError { FromBytesWithNulError { kind: FromBytesWithNulErrorKind::InteriorNul(pos) } } - #[rustc_const_stable(feature = "const_cstr_methods", since = "1.72.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_cstr_methods", since = "1.72.0"))] const fn not_nul_terminated() -> FromBytesWithNulError { FromBytesWithNulError { kind: FromBytesWithNulErrorKind::NotNulTerminated } } @@ -730,7 +730,7 @@ impl AsRef for CStr { /// located within `isize::MAX` from `ptr`. #[inline] #[unstable(feature = "cstr_internals", issue = "none")] -#[rustc_const_stable(feature = "const_cstr_from_ptr", since = "1.81.0")] +#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_cstr_from_ptr", since = "1.81.0"))] #[rustc_allow_const_fn_unstable(const_eval_select)] const unsafe fn strlen(ptr: *const c_char) -> usize { const fn strlen_ct(s: *const c_char) -> usize { diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 3486e7279e148..0fed281bf9fd0 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -943,7 +943,11 @@ extern "rust-intrinsic" { /// reach code marked with this function. /// /// The stabilized version of this intrinsic is [`core::hint::unreachable_unchecked`]. - #[rustc_const_stable(feature = "const_unreachable_unchecked", since = "1.57.0")] + #[cfg_attr( + bootstrap, + rustc_const_stable(feature = "const_unreachable_unchecked", since = "1.57.0") + )] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_nounwind] pub fn unreachable() -> !; } @@ -958,7 +962,8 @@ extern "rust-intrinsic" { /// own, or if it does not enable any significant optimizations. /// /// The stabilized version of this intrinsic is [`core::hint::assert_unchecked`]. -#[rustc_const_stable(feature = "const_assume", since = "1.77.0")] +#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_assume", since = "1.77.0"))] +#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] @@ -1043,7 +1048,8 @@ extern "rust-intrinsic" { /// This will statically either panic, or do nothing. /// /// This intrinsic does not have a stable counterpart. - #[rustc_const_stable(feature = "const_assert_type", since = "1.59.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_assert_type", since = "1.59.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn assert_inhabited(); @@ -1052,7 +1058,8 @@ extern "rust-intrinsic" { /// zero-initialization: This will statically either panic, or do nothing. /// /// This intrinsic does not have a stable counterpart. - #[rustc_const_stable(feature = "const_assert_type2", since = "1.75.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_assert_type2", since = "1.75.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn assert_zero_valid(); @@ -1060,7 +1067,8 @@ extern "rust-intrinsic" { /// A guard for `std::mem::uninitialized`. This will statically either panic, or do nothing. /// /// This intrinsic does not have a stable counterpart. - #[rustc_const_stable(feature = "const_assert_type2", since = "1.75.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_assert_type2", since = "1.75.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn assert_mem_uninitialized_valid(); @@ -1073,7 +1081,8 @@ extern "rust-intrinsic" { /// any safety invariants. /// /// Consider using [`core::panic::Location::caller`] instead. - #[rustc_const_stable(feature = "const_caller_location", since = "1.79.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_caller_location", since = "1.79.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn caller_location() -> &'static crate::panic::Location<'static>; @@ -1393,7 +1402,8 @@ extern "rust-intrinsic" { /// /// This is not expected to ever be exposed directly to users, rather it /// may eventually be exposed through some more-constrained API. - #[rustc_const_stable(feature = "const_transmute", since = "1.56.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_transmute", since = "1.56.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_nounwind] pub fn transmute_unchecked(src: Src) -> Dst; @@ -1410,7 +1420,8 @@ extern "rust-intrinsic" { /// any safety invariants. /// /// The stabilized version of this intrinsic is [`mem::needs_drop`](crate::mem::needs_drop). - #[rustc_const_stable(feature = "const_needs_drop", since = "1.40.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_needs_drop", since = "1.40.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn needs_drop() -> bool; @@ -1432,7 +1443,8 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is [`pointer::offset`]. #[must_use = "returns a new pointer rather than modifying its argument"] - #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_nounwind] pub fn offset(dst: Ptr, offset: Delta) -> Ptr; @@ -1450,7 +1462,8 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is [`pointer::wrapping_offset`]. #[must_use = "returns a new pointer rather than modifying its argument"] - #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_nounwind] pub fn arith_offset(dst: *const T, offset: isize) -> *const T; @@ -2232,7 +2245,8 @@ extern "rust-intrinsic" { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `count_ones` method. For example, /// [`u32::count_ones`] - #[rustc_const_stable(feature = "const_ctpop", since = "1.40.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ctpop", since = "1.40.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn ctpop(x: T) -> u32; @@ -2273,7 +2287,8 @@ extern "rust-intrinsic" { /// let num_leading = ctlz(x); /// assert_eq!(num_leading, 16); /// ``` - #[rustc_const_stable(feature = "const_ctlz", since = "1.40.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ctlz", since = "1.40.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn ctlz(x: T) -> u32; @@ -2295,7 +2310,8 @@ extern "rust-intrinsic" { /// let num_leading = unsafe { ctlz_nonzero(x) }; /// assert_eq!(num_leading, 3); /// ``` - #[rustc_const_stable(feature = "constctlz", since = "1.50.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "constctlz", since = "1.50.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_nounwind] pub fn ctlz_nonzero(x: T) -> u32; @@ -2335,7 +2351,8 @@ extern "rust-intrinsic" { /// let num_trailing = cttz(x); /// assert_eq!(num_trailing, 16); /// ``` - #[rustc_const_stable(feature = "const_cttz", since = "1.40.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_cttz", since = "1.40.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn cttz(x: T) -> u32; @@ -2357,7 +2374,8 @@ extern "rust-intrinsic" { /// let num_trailing = unsafe { cttz_nonzero(x) }; /// assert_eq!(num_trailing, 3); /// ``` - #[rustc_const_stable(feature = "const_cttz_nonzero", since = "1.53.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_cttz_nonzero", since = "1.53.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_nounwind] pub fn cttz_nonzero(x: T) -> u32; @@ -2371,7 +2389,8 @@ extern "rust-intrinsic" { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `swap_bytes` method. For example, /// [`u32::swap_bytes`] - #[rustc_const_stable(feature = "const_bswap", since = "1.40.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_bswap", since = "1.40.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn bswap(x: T) -> T; @@ -2386,7 +2405,8 @@ extern "rust-intrinsic" { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `reverse_bits` method. For example, /// [`u32::reverse_bits`] - #[rustc_const_stable(feature = "const_bitreverse", since = "1.40.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_bitreverse", since = "1.40.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn bitreverse(x: T) -> T; @@ -2412,7 +2432,8 @@ extern "rust-intrinsic" { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `overflowing_add` method. For example, /// [`u32::overflowing_add`] - #[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_overflow", since = "1.40.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn add_with_overflow(x: T, y: T) -> (T, bool); @@ -2427,7 +2448,8 @@ extern "rust-intrinsic" { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `overflowing_sub` method. For example, /// [`u32::overflowing_sub`] - #[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_overflow", since = "1.40.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn sub_with_overflow(x: T, y: T) -> (T, bool); @@ -2442,7 +2464,8 @@ extern "rust-intrinsic" { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `overflowing_mul` method. For example, /// [`u32::overflowing_mul`] - #[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_overflow", since = "1.40.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn mul_with_overflow(x: T, y: T) -> (T, bool); @@ -2461,7 +2484,11 @@ 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_div", since = "1.52.0")] + #[cfg_attr( + bootstrap, + rustc_const_stable(feature = "const_int_unchecked_div", since = "1.52.0") + )] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_nounwind] pub fn unchecked_div(x: T, y: T) -> T; /// Returns the remainder of an unchecked division, resulting in @@ -2470,7 +2497,11 @@ 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_rem", since = "1.52.0")] + #[cfg_attr( + bootstrap, + rustc_const_stable(feature = "const_int_unchecked_rem", since = "1.52.0") + )] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_nounwind] pub fn unchecked_rem(x: T, y: T) -> T; @@ -2480,7 +2511,8 @@ extern "rust-intrinsic" { /// Safe wrappers for this intrinsic are available on the integer /// primitives via the `checked_shl` method. For example, /// [`u32::checked_shl`] - #[rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_nounwind] pub fn unchecked_shl(x: T, y: U) -> T; /// Performs an unchecked right shift, resulting in undefined behavior when @@ -2489,7 +2521,8 @@ extern "rust-intrinsic" { /// Safe wrappers for this intrinsic are available on the integer /// primitives via the `checked_shr` method. For example, /// [`u32::checked_shr`] - #[rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_nounwind] pub fn unchecked_shr(x: T, y: U) -> T; @@ -2498,7 +2531,8 @@ extern "rust-intrinsic" { /// /// The stable counterpart of this intrinsic is `unchecked_add` on the various /// integer types, such as [`u16::unchecked_add`] and [`i64::unchecked_add`]. - #[rustc_const_stable(feature = "unchecked_math", since = "1.79.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "unchecked_math", since = "1.79.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_nounwind] pub fn unchecked_add(x: T, y: T) -> T; @@ -2507,7 +2541,8 @@ extern "rust-intrinsic" { /// /// The stable counterpart of this intrinsic is `unchecked_sub` on the various /// integer types, such as [`u16::unchecked_sub`] and [`i64::unchecked_sub`]. - #[rustc_const_stable(feature = "unchecked_math", since = "1.79.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "unchecked_math", since = "1.79.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_nounwind] pub fn unchecked_sub(x: T, y: T) -> T; @@ -2516,7 +2551,8 @@ extern "rust-intrinsic" { /// /// The stable counterpart of this intrinsic is `unchecked_mul` on the various /// integer types, such as [`u16::unchecked_mul`] and [`i64::unchecked_mul`]. - #[rustc_const_stable(feature = "unchecked_math", since = "1.79.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "unchecked_math", since = "1.79.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_nounwind] pub fn unchecked_mul(x: T, y: T) -> T; @@ -2530,7 +2566,8 @@ extern "rust-intrinsic" { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `rotate_left` method. For example, /// [`u32::rotate_left`] - #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_rotate", since = "1.40.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn rotate_left(x: T, shift: u32) -> T; @@ -2545,7 +2582,8 @@ extern "rust-intrinsic" { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `rotate_right` method. For example, /// [`u32::rotate_right`] - #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_rotate", since = "1.40.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn rotate_right(x: T, shift: u32) -> T; @@ -2560,7 +2598,8 @@ extern "rust-intrinsic" { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `wrapping_add` method. For example, /// [`u32::wrapping_add`] - #[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn wrapping_add(a: T, b: T) -> T; @@ -2574,7 +2613,8 @@ extern "rust-intrinsic" { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `wrapping_sub` method. For example, /// [`u32::wrapping_sub`] - #[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn wrapping_sub(a: T, b: T) -> T; @@ -2588,7 +2628,8 @@ extern "rust-intrinsic" { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `wrapping_mul` method. For example, /// [`u32::wrapping_mul`] - #[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn wrapping_mul(a: T, b: T) -> T; @@ -2603,7 +2644,8 @@ extern "rust-intrinsic" { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `saturating_add` method. For example, /// [`u32::saturating_add`] - #[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_saturating", since = "1.40.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn saturating_add(a: T, b: T) -> T; @@ -2617,7 +2659,8 @@ extern "rust-intrinsic" { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `saturating_sub` method. For example, /// [`u32::saturating_sub`] - #[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_saturating", since = "1.40.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn saturating_sub(a: T, b: T) -> T; @@ -2628,7 +2671,8 @@ extern "rust-intrinsic" { /// This intrinsic can *only* be called where the pointer is a local without /// projections (`read_via_copy(ptr)`, not `read_via_copy(*ptr)`) so that it /// trivially obeys runtime-MIR rules about derefs in operands. - #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_read", since = "1.71.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_nounwind] pub fn read_via_copy(ptr: *const T) -> T; @@ -2651,7 +2695,8 @@ extern "rust-intrinsic" { /// any safety invariants. /// /// The stabilized version of this intrinsic is [`core::mem::discriminant`]. - #[rustc_const_stable(feature = "const_discriminant", since = "1.75.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_discriminant", since = "1.75.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn discriminant_value(v: &T) -> ::Discriminant; @@ -2685,7 +2730,8 @@ extern "rust-intrinsic" { pub fn nontemporal_store(ptr: *mut T, val: T); /// See documentation of `<*const T>::offset_from` for details. - #[rustc_const_stable(feature = "const_ptr_offset_from", since = "1.65.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_offset_from", since = "1.65.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_nounwind] pub fn ptr_offset_from(ptr: *const T, base: *const T) -> isize; @@ -3038,7 +3084,8 @@ pub unsafe fn vtable_align(_ptr: *const ()) -> usize { /// The stabilized version of this intrinsic is [`core::mem::size_of`]. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[rustc_const_stable(feature = "const_size_of", since = "1.40.0")] +#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_size_of", since = "1.40.0"))] +#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn size_of() -> usize { @@ -3055,7 +3102,8 @@ pub const fn size_of() -> usize { /// The stabilized version of this intrinsic is [`core::mem::align_of`]. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[rustc_const_stable(feature = "const_min_align_of", since = "1.40.0")] +#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_min_align_of", since = "1.40.0"))] +#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn min_align_of() -> usize { @@ -3168,7 +3216,11 @@ pub const fn type_id() -> u128 { /// change the possible layouts of pointers. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")] +#[cfg_attr( + bootstrap, + rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION") +)] +#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn aggregate_raw_ptr, D, M>(_data: D, _meta: M) -> P { @@ -3193,7 +3245,14 @@ impl AggregateRawPtr<*mut T> for *mut P { /// This is used to implement functions like `ptr::metadata`. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")] +#[cfg_attr( + bootstrap, + cfg_attr( + bootstrap, + rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION") + ) +)] +#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn ptr_metadata + ?Sized, M>(_ptr: *const P) -> M { @@ -3300,7 +3359,11 @@ pub const fn ptr_metadata + ?Sized, M>(_ptr: *cons #[rustc_diagnostic_item = "ptr_copy_nonoverlapping"] pub const unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize) { extern "rust-intrinsic" { - #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")] + #[cfg_attr( + bootstrap, + rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION") + )] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_nounwind] pub fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize); } @@ -3402,7 +3465,11 @@ pub const unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: us #[rustc_diagnostic_item = "ptr_copy"] pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { extern "rust-intrinsic" { - #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")] + #[cfg_attr( + bootstrap, + rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION") + )] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_nounwind] fn copy(src: *const T, dst: *mut T, count: usize); } diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 51827d09251d9..5024dc0016cdc 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -1397,7 +1397,8 @@ from_str_radix_int_impl! { isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128 } #[doc(hidden)] #[inline(always)] #[unstable(issue = "none", feature = "std_internals")] -#[rustc_const_stable(feature = "const_int_from_str", since = "1.82.0")] +#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_from_str", since = "1.82.0"))] +#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] pub const fn can_not_overflow(radix: u32, is_signed_ty: bool, digits: &[u8]) -> bool { radix <= 16 && digits.len() <= mem::size_of::() * 2 - is_signed_ty as usize } diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index d9036abecc592..0b134670005c0 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -3009,7 +3009,8 @@ macro_rules! uint_impl { // overflow cases it instead ends up returning the maximum value // of the type, and can return 0 for 0. #[inline] - #[rustc_const_stable(feature = "const_int_pow", since = "1.50.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_pow", since = "1.50.0"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] const fn one_less_than_next_power_of_two(self) -> Self { if self <= 1 { return 0; } diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 72d11096ad225..48018efdfd2dd 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -50,7 +50,7 @@ const _: () = assert!(cfg!(panic = "abort"), "panic_immediate_abort requires -C #[track_caller] #[lang = "panic_fmt"] // needed for const-evaluated panics #[rustc_do_not_const_check] // hooked by const-eval -#[rustc_const_unstable(feature = "panic_internals", issue = "none")] +#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // exposed via macro pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { if cfg!(feature = "panic_immediate_abort") { @@ -85,7 +85,7 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { // and unwinds anyway, we will hit the "unwinding out of nounwind function" guard, // which causes a "panic in a function that cannot unwind". #[rustc_nounwind] -#[rustc_const_unstable(feature = "panic_internals", issue = "none")] +#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_allow_const_fn_unstable(const_eval_select)] pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: bool) -> ! { @@ -134,7 +134,7 @@ pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: boo #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[track_caller] -#[rustc_const_unstable(feature = "panic_internals", issue = "none")] +#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // exposed via macro #[lang = "panic"] // used by lints and miri for panics pub const fn panic(expr: &'static str) -> ! { @@ -173,8 +173,8 @@ macro_rules! panic_const { #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[track_caller] - #[rustc_const_unstable(feature = "panic_internals", issue = "none")] - #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // exposed via codegen + #[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // exposed via MIR lowering #[lang = stringify!($lang)] pub const fn $lang() -> ! { // Use Arguments::new_const instead of format_args!("{expr}") to potentially @@ -221,8 +221,8 @@ panic_const! { #[cfg_attr(feature = "panic_immediate_abort", inline)] #[lang = "panic_nounwind"] // needed by codegen for non-unwinding panics #[rustc_nounwind] -#[rustc_const_unstable(feature = "panic_internals", issue = "none")] -#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // exposed via codegen +#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] +#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // exposed via MIR lowering pub const fn panic_nounwind(expr: &'static str) -> ! { panic_nounwind_fmt(fmt::Arguments::new_const(&[expr]), /* force_no_backtrace */ false); } @@ -238,7 +238,7 @@ pub fn panic_nounwind_nobacktrace(expr: &'static str) -> ! { #[track_caller] #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] #[cfg_attr(feature = "panic_immediate_abort", inline)] -#[rustc_const_unstable(feature = "panic_internals", issue = "none")] +#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // exposed via macro pub const fn panic_explicit() -> ! { panic_display(&"explicit panic"); @@ -256,7 +256,7 @@ pub fn unreachable_display(x: &T) -> ! { #[inline] #[track_caller] #[rustc_diagnostic_item = "panic_str_2015"] -#[rustc_const_unstable(feature = "panic_internals", issue = "none")] +#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // exposed via macro pub const fn panic_str_2015(expr: &str) -> ! { panic_display(&expr); @@ -267,7 +267,7 @@ pub const fn panic_str_2015(expr: &str) -> ! { #[rustc_do_not_const_check] // hooked by const-eval // enforce a &&str argument in const-check and hook this by const-eval #[rustc_const_panic_str] -#[rustc_const_unstable(feature = "panic_internals", issue = "none")] +#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // exposed via macro pub const fn panic_display(x: &T) -> ! { panic_fmt(format_args!("{}", *x)); @@ -337,7 +337,7 @@ fn panic_in_cleanup() -> ! { /// This function is used instead of panic_fmt in const eval. #[lang = "const_panic_fmt"] // needed by const-eval machine to replace calls to `panic_fmt` lang item -#[rustc_const_unstable(feature = "panic_internals", issue = "none")] +#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // exposed via const-eval machine hook pub const fn const_panic_fmt(fmt: fmt::Arguments<'_>) -> ! { if let Some(msg) = fmt.as_str() { diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 12823f67a7e29..cf586f6187c2a 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -645,7 +645,11 @@ pub const fn null_mut() -> *mut T { /// see the [module documentation][crate::ptr] for details. #[inline(always)] #[must_use] -#[rustc_const_stable(feature = "stable_things_using_strict_provenance", since = "1.61.0")] +#[cfg_attr( + bootstrap, + rustc_const_stable(feature = "stable_things_using_strict_provenance", since = "1.61.0") +)] +#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[unstable(feature = "strict_provenance", issue = "95228")] pub const fn without_provenance(addr: usize) -> *const T { // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. @@ -667,7 +671,11 @@ pub const fn without_provenance(addr: usize) -> *const T { /// some other means. #[inline(always)] #[must_use] -#[rustc_const_stable(feature = "stable_things_using_strict_provenance", since = "1.61.0")] +#[cfg_attr( + bootstrap, + rustc_const_stable(feature = "stable_things_using_strict_provenance", since = "1.61.0") +)] +#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[unstable(feature = "strict_provenance", issue = "95228")] pub const fn dangling() -> *const T { without_provenance(mem::align_of::()) @@ -689,7 +697,11 @@ pub const fn dangling() -> *const T { /// see the [module documentation][crate::ptr] for details. #[inline(always)] #[must_use] -#[rustc_const_stable(feature = "stable_things_using_strict_provenance", since = "1.61.0")] +#[cfg_attr( + bootstrap, + rustc_const_stable(feature = "stable_things_using_strict_provenance", since = "1.61.0") +)] +#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[unstable(feature = "strict_provenance", issue = "95228")] pub const fn without_provenance_mut(addr: usize) -> *mut T { // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. @@ -711,7 +723,11 @@ pub const fn without_provenance_mut(addr: usize) -> *mut T { /// some other means. #[inline(always)] #[must_use] -#[rustc_const_stable(feature = "stable_things_using_strict_provenance", since = "1.61.0")] +#[cfg_attr( + bootstrap, + rustc_const_stable(feature = "stable_things_using_strict_provenance", since = "1.61.0") +)] +#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[unstable(feature = "strict_provenance", issue = "95228")] pub const fn dangling_mut() -> *mut T { without_provenance_mut(mem::align_of::()) diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs index be19c3d3bc153..5760462326261 100644 --- a/library/core/src/slice/memchr.rs +++ b/library/core/src/slice/memchr.rs @@ -15,7 +15,7 @@ const USIZE_BYTES: usize = mem::size_of::(); /// bytes where the borrow propagated all the way to the most significant /// bit." #[inline] -#[rustc_const_stable(feature = "const_memchr", since = "1.65.0")] +#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_memchr", since = "1.65.0"))] const fn contains_zero_byte(x: usize) -> bool { x.wrapping_sub(LO_USIZE) & !x & HI_USIZE != 0 } @@ -23,7 +23,7 @@ const fn contains_zero_byte(x: usize) -> bool { /// Returns the first index matching the byte `x` in `text`. #[inline] #[must_use] -#[rustc_const_stable(feature = "const_memchr", since = "1.65.0")] +#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_memchr", since = "1.65.0"))] pub const fn memchr(x: u8, text: &[u8]) -> Option { // Fast path for small slices. if text.len() < 2 * USIZE_BYTES { @@ -34,7 +34,7 @@ pub const fn memchr(x: u8, text: &[u8]) -> Option { } #[inline] -#[rustc_const_stable(feature = "const_memchr", since = "1.65.0")] +#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_memchr", since = "1.65.0"))] const fn memchr_naive(x: u8, text: &[u8]) -> Option { let mut i = 0; @@ -52,7 +52,7 @@ const fn memchr_naive(x: u8, text: &[u8]) -> Option { #[rustc_allow_const_fn_unstable(const_cmp)] #[rustc_allow_const_fn_unstable(const_align_offset)] -#[rustc_const_stable(feature = "const_memchr", since = "1.65.0")] +#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_memchr", since = "1.65.0"))] const fn memchr_aligned(x: u8, text: &[u8]) -> Option { // Scan for a single byte value by reading two `usize` words at a time. // diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index fc549abd43365..fc6cb03ea05a9 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -321,7 +321,7 @@ impl<'a> ContextBuilder<'a> { /// Creates a ContextBuilder from a Waker. #[inline] #[unstable(feature = "local_waker", issue = "118959")] - #[rustc_const_stable(feature = "const_waker", since = "1.82.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_waker", since = "1.82.0"))] pub const fn from_waker(waker: &'a Waker) -> Self { // SAFETY: LocalWaker is just Waker without thread safety let local_waker = unsafe { transmute(waker) }; @@ -379,7 +379,7 @@ impl<'a> ContextBuilder<'a> { /// Builds the `Context`. #[inline] #[unstable(feature = "local_waker", issue = "118959")] - #[rustc_const_stable(feature = "const_waker", since = "1.82.0")] + #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_waker", since = "1.82.0"))] pub const fn build(self) -> Context<'a> { let ContextBuilder { waker, local_waker, ext, _marker, _marker2 } = self; Context { waker, local_waker, ext: AssertUnwindSafe(ext), _marker, _marker2 } diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs index 6ce57972f8960..cc09596e8696d 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -237,7 +237,7 @@ impl LocalKey { reason = "recently added to create a key", issue = "none" )] - #[rustc_const_unstable(feature = "thread_local_internals", issue = "none")] + #[cfg_attr(bootstrap, rustc_const_unstable(feature = "thread_local_internals", issue = "none"))] #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // exposed via macro pub const unsafe fn new(inner: fn(Option<&mut Option>) -> *const T) -> LocalKey { LocalKey { inner } diff --git a/tests/ui/consts/auxiliary/unstable_but_const_stable.rs b/tests/ui/consts/auxiliary/unstable_but_const_stable.rs deleted file mode 100644 index 88044b0272c78..0000000000000 --- a/tests/ui/consts/auxiliary/unstable_but_const_stable.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![feature(staged_api, rustc_attrs, intrinsics)] -#![stable(since="1.0.0", feature = "stable")] - -extern "rust-intrinsic" { - #[unstable(feature = "unstable", issue = "42")] - #[rustc_const_stable(feature = "stable", since = "1.0.0")] - #[rustc_nounwind] - pub fn write_bytes(dst: *mut T, val: u8, count: usize); -} - -#[unstable(feature = "unstable", issue = "42")] -#[rustc_const_stable(feature = "stable", since = "1.0.0")] -pub const fn some_unstable_fn() {} diff --git a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs index 78ed94d55888f..d6f07994e8200 100644 --- a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs +++ b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs @@ -45,16 +45,24 @@ const fn foo2_gated() -> u32 { 42 } // can't call non-min_const_fn const fn bar2_gated() -> u32 { foo2_gated() } //~ ERROR cannot use `#[feature(foo2)]` -// Functions with the `rustc_const_stable_indirect` attribute -// are checked like stable functions. +// Functions without any attribute are checked like stable functions, +// even if they are in a stable module. +mod stable { + #![stable(feature = "rust1", since = "1.0.0")] + + pub(crate) const fn bar2_gated_stable_indirect() -> u32 { super::foo2_gated() } //~ ERROR cannot use `#[feature(foo2)]` +} +// And same for const-unstable functions that are marked as "stable_indirect". +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature="foo", issue = "none")] #[rustc_const_stable_indirect] -const fn bar2_gated_stable_indirect() -> u32 { foo2_gated() } //~ ERROR cannot use `#[feature(foo2)]` +const fn stable_indirect() -> u32 { foo2_gated() } //~ ERROR cannot use `#[feature(foo2)]` // These functiuons *can* be called from fully stable functions. #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "rust1", since = "1.0.0")] const fn bar2_gated_exposed() -> u32 { - bar2_gated_stable_indirect() + stable::bar2_gated_stable_indirect() + stable_indirect() } fn main() {} diff --git a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr index 19a109411945c..c8221de3112b3 100644 --- a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr +++ b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr @@ -84,21 +84,38 @@ LL | const fn bar2_gated() -> u32 { foo2_gated() } | error: const function that might be (indirectly) exposed to stable cannot use `#[feature(foo2)]` - --> $DIR/min_const_fn_libstd_stability.rs:51:48 + --> $DIR/min_const_fn_libstd_stability.rs:53:63 | -LL | const fn bar2_gated_stable_indirect() -> u32 { foo2_gated() } - | ^^^^^^^^^^^^ +LL | pub(crate) const fn bar2_gated_stable_indirect() -> u32 { super::foo2_gated() } + | ^^^^^^^^^^^^^^^^^^^ + | +help: if the function is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this what you probably want to do) + | +LL + #[rustc_const_unstable(feature = "...", issue = "...")] +LL | pub(crate) const fn bar2_gated_stable_indirect() -> u32 { super::foo2_gated() } + | +help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval) + | +LL + #[rustc_allow_const_fn_unstable(foo2)] +LL | pub(crate) const fn bar2_gated_stable_indirect() -> u32 { super::foo2_gated() } + | + +error: const function that might be (indirectly) exposed to stable cannot use `#[feature(foo2)]` + --> $DIR/min_const_fn_libstd_stability.rs:59:37 + | +LL | const fn stable_indirect() -> u32 { foo2_gated() } + | ^^^^^^^^^^^^ | help: if the function is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this what you probably want to do) | LL + #[rustc_const_unstable(feature = "...", issue = "...")] -LL | const fn bar2_gated_stable_indirect() -> u32 { foo2_gated() } +LL | const fn stable_indirect() -> u32 { foo2_gated() } | help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval) | LL + #[rustc_allow_const_fn_unstable(foo2)] -LL | const fn bar2_gated_stable_indirect() -> u32 { foo2_gated() } +LL | const fn stable_indirect() -> u32 { foo2_gated() } | -error: aborting due to 6 previous errors +error: aborting due to 7 previous errors diff --git a/tests/ui/consts/rustc-const-stability-require-const.rs b/tests/ui/consts/rustc-const-stability-require-const.rs index 4fb259b335c71..6cc3f0f0da12b 100644 --- a/tests/ui/consts/rustc-const-stability-require-const.rs +++ b/tests/ui/consts/rustc-const-stability-require-const.rs @@ -1,16 +1,16 @@ #![crate_type = "lib"] -#![feature(staged_api)] +#![feature(staged_api, rustc_attrs)] #![stable(feature = "foo", since = "1.0.0")] #[stable(feature = "foo", since = "1.0.0")] #[rustc_const_unstable(feature = "const_foo", issue = "none")] pub fn foo() {} -//~^ ERROR attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` +//~^ ERROR require the function or method to be `const` #[stable(feature = "bar", since = "1.0.0")] #[rustc_const_stable(feature = "const_bar", since = "1.0.0")] pub fn bar() {} -//~^ ERROR attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` +//~^ ERROR require the function or method to be `const` #[stable(feature = "potato", since = "1.0.0")] pub struct Potato; @@ -19,23 +19,23 @@ impl Potato { #[stable(feature = "salad", since = "1.0.0")] #[rustc_const_unstable(feature = "const_salad", issue = "none")] pub fn salad(&self) -> &'static str { "mmmmmm" } - //~^ ERROR attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` + //~^ ERROR require the function or method to be `const` #[stable(feature = "roasted", since = "1.0.0")] #[rustc_const_unstable(feature = "const_roasted", issue = "none")] pub fn roasted(&self) -> &'static str { "mmmmmmmmmm" } - //~^ ERROR attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` + //~^ ERROR require the function or method to be `const` } #[stable(feature = "bar", since = "1.0.0")] #[rustc_const_stable(feature = "const_bar", since = "1.0.0")] pub extern "C" fn bar_c() {} -//~^ ERROR attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` +//~^ ERROR require the function or method to be `const` #[stable(feature = "foo", since = "1.0.0")] #[rustc_const_unstable(feature = "const_foo", issue = "none")] pub extern "C" fn foo_c() {} -//~^ ERROR attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` +//~^ ERROR require the function or method to be `const` #[stable(feature = "foobar", since = "1.0.0")] @@ -45,3 +45,20 @@ pub const fn foobar() {} #[stable(feature = "barfoo", since = "1.0.0")] #[rustc_const_stable(feature = "barfoo_const", since = "1.0.0")] pub const fn barfoo() {} + +// `rustc_const_stable` also requires the function to be stable. + +#[rustc_const_stable(feature = "barfoo_const", since = "1.0.0")] +const fn barfoo_unmarked() {} +//~^ ERROR can only be applied to functions that are declared `#[stable]` + +#[unstable(feature = "unstable", issue = "none")] +#[rustc_const_stable(feature = "barfoo_const", since = "1.0.0")] +pub const fn barfoo_unstable() {} +//~^ ERROR can only be applied to functions that are declared `#[stable]` + +// `#[rustc_const_stable_indirect]` also requires a const fn +#[rustc_const_stable_indirect] +#[unstable(feature = "unstable", issue = "none")] +pub fn not_a_const_fn() {} +//~^ ERROR require the function or method to be `const` diff --git a/tests/ui/consts/rustc-const-stability-require-const.stderr b/tests/ui/consts/rustc-const-stability-require-const.stderr index 1027b9311b7a6..c539b89121f76 100644 --- a/tests/ui/consts/rustc-const-stability-require-const.stderr +++ b/tests/ui/consts/rustc-const-stability-require-const.stderr @@ -1,4 +1,4 @@ -error: attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` +error: attributes `#[rustc_const_unstable]`, `#[rustc_const_stable]` and `#[rustc_const_stable_indirect]` require the function or method to be `const` --> $DIR/rustc-const-stability-require-const.rs:7:1 | LL | #[rustc_const_unstable(feature = "const_foo", issue = "none")] @@ -12,7 +12,7 @@ help: make the function or method const LL | pub fn foo() {} | ^^^^^^^^^^^^ -error: attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` +error: attributes `#[rustc_const_unstable]`, `#[rustc_const_stable]` and `#[rustc_const_stable_indirect]` require the function or method to be `const` --> $DIR/rustc-const-stability-require-const.rs:12:1 | LL | #[rustc_const_stable(feature = "const_bar", since = "1.0.0")] @@ -26,7 +26,7 @@ help: make the function or method const LL | pub fn bar() {} | ^^^^^^^^^^^^ -error: attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` +error: attributes `#[rustc_const_unstable]`, `#[rustc_const_stable]` and `#[rustc_const_stable_indirect]` require the function or method to be `const` --> $DIR/rustc-const-stability-require-const.rs:21:5 | LL | #[rustc_const_unstable(feature = "const_salad", issue = "none")] @@ -40,7 +40,7 @@ help: make the function or method const LL | pub fn salad(&self) -> &'static str { "mmmmmm" } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` +error: attributes `#[rustc_const_unstable]`, `#[rustc_const_stable]` and `#[rustc_const_stable_indirect]` require the function or method to be `const` --> $DIR/rustc-const-stability-require-const.rs:26:5 | LL | #[rustc_const_unstable(feature = "const_roasted", issue = "none")] @@ -54,7 +54,7 @@ help: make the function or method const LL | pub fn roasted(&self) -> &'static str { "mmmmmmmmmm" } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` +error: attributes `#[rustc_const_unstable]`, `#[rustc_const_stable]` and `#[rustc_const_stable_indirect]` require the function or method to be `const` --> $DIR/rustc-const-stability-require-const.rs:32:1 | LL | #[rustc_const_stable(feature = "const_bar", since = "1.0.0")] @@ -68,7 +68,7 @@ help: make the function or method const LL | pub extern "C" fn bar_c() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` +error: attributes `#[rustc_const_unstable]`, `#[rustc_const_stable]` and `#[rustc_const_stable_indirect]` require the function or method to be `const` --> $DIR/rustc-const-stability-require-const.rs:37:1 | LL | #[rustc_const_unstable(feature = "const_foo", issue = "none")] @@ -82,5 +82,33 @@ help: make the function or method const LL | pub extern "C" fn foo_c() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 6 previous errors +error: attribute `#[rustc_const_stable]` can only be applied to functions that are declared `#[stable]` + --> $DIR/rustc-const-stability-require-const.rs:52:1 + | +LL | #[rustc_const_stable(feature = "barfoo_const", since = "1.0.0")] + | ---------------------------------------------------------------- attribute specified here +LL | const fn barfoo_unmarked() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: attribute `#[rustc_const_stable]` can only be applied to functions that are declared `#[stable]` + --> $DIR/rustc-const-stability-require-const.rs:57:1 + | +LL | #[rustc_const_stable(feature = "barfoo_const", since = "1.0.0")] + | ---------------------------------------------------------------- attribute specified here +LL | pub const fn barfoo_unstable() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: attributes `#[rustc_const_unstable]`, `#[rustc_const_stable]` and `#[rustc_const_stable_indirect]` require the function or method to be `const` + --> $DIR/rustc-const-stability-require-const.rs:63:1 + | +LL | pub fn not_a_const_fn() {} + | ^^^^^^^^^^^^^^^^^^^^^^^ attribute specified here + | +help: make the function or method const + --> $DIR/rustc-const-stability-require-const.rs:63:1 + | +LL | pub fn not_a_const_fn() {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 9 previous errors diff --git a/tests/ui/consts/unstable-const-stable.rs b/tests/ui/consts/unstable-const-stable.rs deleted file mode 100644 index f69e8d0efe593..0000000000000 --- a/tests/ui/consts/unstable-const-stable.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ aux-build:unstable_but_const_stable.rs - -extern crate unstable_but_const_stable; -use unstable_but_const_stable::*; - -fn main() { - some_unstable_fn(); //~ERROR use of unstable library feature - unsafe { write_bytes(4 as *mut u8, 0, 0) }; //~ERROR use of unstable library feature -} - -const fn const_main() { - some_unstable_fn(); //~ERROR use of unstable library feature - unsafe { write_bytes(4 as *mut u8, 0, 0) }; //~ERROR use of unstable library feature -} diff --git a/tests/ui/consts/unstable-const-stable.stderr b/tests/ui/consts/unstable-const-stable.stderr deleted file mode 100644 index c4ffbbb60db3c..0000000000000 --- a/tests/ui/consts/unstable-const-stable.stderr +++ /dev/null @@ -1,43 +0,0 @@ -error[E0658]: use of unstable library feature 'unstable' - --> $DIR/unstable-const-stable.rs:7:5 - | -LL | some_unstable_fn(); - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #42 for more information - = help: add `#![feature(unstable)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: use of unstable library feature 'unstable' - --> $DIR/unstable-const-stable.rs:8:14 - | -LL | unsafe { write_bytes(4 as *mut u8, 0, 0) }; - | ^^^^^^^^^^^ - | - = note: see issue #42 for more information - = help: add `#![feature(unstable)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: use of unstable library feature 'unstable' - --> $DIR/unstable-const-stable.rs:12:5 - | -LL | some_unstable_fn(); - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #42 for more information - = help: add `#![feature(unstable)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: use of unstable library feature 'unstable' - --> $DIR/unstable-const-stable.rs:13:14 - | -LL | unsafe { write_bytes(4 as *mut u8, 0, 0) }; - | ^^^^^^^^^^^ - | - = note: see issue #42 for more information - = help: add `#![feature(unstable)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr index 823ab69df9cb5..81612c87f8131 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr @@ -1,3 +1,18 @@ +error: attribute `#[rustc_const_stable]` can only be applied to functions that are declared `#[stable]` + --> $DIR/minicore.rs:521:1 + | +LL | #[rustc_const_stable(feature = "const_eval_select", since = "1.0.0")] + | --------------------------------------------------------------------- attribute specified here +... +LL | / const fn const_eval_select( +LL | | arg: ARG, +LL | | called_in_const: F, +LL | | called_at_rt: G, +... | +LL | | F: const FnOnce, +LL | | G: FnOnce, + | |_________________________________^ + error: the compiler unexpectedly panicked. this is a bug. query stack during panic: @@ -11,3 +26,5 @@ query stack during panic: #0 [check_well_formed] checking that `drop` is well-formed #1 [check_mod_type_wf] checking that types are well-formed in top-level module end of query stack +error: aborting due to 1 previous error +