diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index fbb9d3f3f3c37..0b73822319ad0 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -16,9 +16,9 @@ use rustc_session::lint::BuiltinLintDiag; use rustc_session::lint::builtin::UNEXPECTED_CFGS; use rustc_session::parse::feature_err; use rustc_session::{RustcVersion, Session}; +use rustc_span::Span; use rustc_span::hygiene::Transparency; use rustc_span::symbol::{Symbol, kw, sym}; -use rustc_span::{DUMMY_SP, Span}; use crate::fluent_generated; use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause}; @@ -92,13 +92,15 @@ impl Stability { #[derive(HashStable_Generic)] pub struct ConstStability { pub level: StabilityLevel, - /// This can be `None` for functions that are not even const-unstable, but - /// are tracked here for the purpose of `safe_to_expose_on_stable`. + /// Says whether this function has an explicit `rustc_const_(un)stable` attribute. + /// If `false`, the const stability information was inferred from the regular + /// stability information. + pub has_const_stable_attr: bool, + /// This can be `None` for functions that are not const-callable from outside code under any + /// feature gate, but are tracked here for the purpose of `safe_to_expose_on_stable`. pub feature: Option, - /// A function that is marked as "safe to expose on stable" must not use any unstable const - /// language features or intrinsics, and all the functions it calls must also be safe to expose - /// on stable. If `level` is `Stable`, this must be `true`. - pub safe_to_expose_on_stable: bool, + /// This is true iff the `const_stable_indirect` attribute is present. + pub const_stable_indirect: bool, /// whether the function has a `#[rustc_promotable]` attribute pub promotable: bool, } @@ -275,22 +277,21 @@ 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]`. +/// The second component is the `const_stable_indirect` attribute if present, which can be meaningful +/// even if there is no `rustc_const_stable`/`rustc_const_unstable`. pub fn find_const_stability( sess: &Session, attrs: &[Attribute], item_sp: Span, - inherited_feature_gate: Option, -) -> Option<(ConstStability, Span)> { +) -> (Option<(ConstStability, Span)>, Option) { let mut const_stab: Option<(ConstStability, Span)> = None; let mut promotable = false; - let mut const_stable_indirect = false; + let mut const_stable_indirect = None; for attr in attrs { match attr.name_or_empty() { sym::rustc_promotable => promotable = true, - sym::rustc_const_stable_indirect => const_stable_indirect = true, + sym::rustc_const_stable_indirect => const_stable_indirect = Some(attr.span), sym::rustc_const_unstable => { if const_stab.is_some() { sess.dcx() @@ -302,8 +303,9 @@ pub fn find_const_stability( const_stab = Some(( ConstStability { level, + has_const_stable_attr: true, feature: Some(feature), - safe_to_expose_on_stable: false, + const_stable_indirect: false, promotable: false, }, attr.span, @@ -320,8 +322,9 @@ pub fn find_const_stability( const_stab = Some(( ConstStability { level, + has_const_stable_attr: true, feature: Some(feature), - safe_to_expose_on_stable: true, + const_stable_indirect: false, promotable: false, }, attr.span, @@ -343,11 +346,11 @@ pub fn find_const_stability( } } } - if const_stable_indirect { + if const_stable_indirect.is_some() { match &mut const_stab { Some((stab, _)) => { if stab.is_const_unstable() { - stab.safe_to_expose_on_stable = true; + stab.const_stable_indirect = true; } else { _ = sess.dcx().emit_err(session_diagnostics::RustcConstStableIndirectPairing { span: item_sp, @@ -355,26 +358,57 @@ 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: inherited_feature_gate, - safe_to_expose_on_stable: true, - promotable: false, - level: StabilityLevel::Unstable { - reason: UnstableReason::Default, - issue: None, - is_soft: false, - implied_by: None, - }, - }; - const_stab = Some((c, DUMMY_SP)); + // We ignore the `#[rustc_const_stable_indirect]` here, it should be picked up by + // the `default_const_unstable` logic. } } } - const_stab + (const_stab, const_stable_indirect) +} + +/// Called for `fn` that don't have a const stability. +/// +/// `effective_reg_stability` must be the effecive regular stability, i.e. after applying all the +/// rules about "inherited" stability. +pub fn default_const_stability( + _sess: &Session, + is_const_fn: bool, + const_stable_indirect: bool, + effective_reg_stability: Option<&Stability>, +) -> Option { + // Intrinsics are *not* `const fn` here, and yet we want to add a default const stability + // for them if they are marked `const_stable_indirect`. + if (is_const_fn || const_stable_indirect) + && let Some(reg_stability) = effective_reg_stability + && reg_stability.level.is_unstable() + { + // This has a feature gate, reuse that for const stability. + // We only want to do this if it is an unstable feature gate. + Some(ConstStability { + feature: Some(reg_stability.feature), + has_const_stable_attr: false, + const_stable_indirect, + promotable: false, + level: reg_stability.level, + }) + } else if const_stable_indirect { + // Make it const-unstable without a feature gate, to record the `const_stable_indirect`. + Some(ConstStability { + feature: None, + has_const_stable_attr: false, + const_stable_indirect, + promotable: false, + level: StabilityLevel::Unstable { + reason: UnstableReason::Default, + issue: None, + is_soft: false, + implied_by: None, + }, + }) + } else { + None + } } /// Collects stability info from `rustc_default_body_unstable` attributes in `attrs`. diff --git a/compiler/rustc_const_eval/src/check_consts/mod.rs b/compiler/rustc_const_eval/src/check_consts/mod.rs index dc5db2e63cb36..1a3bee3df2e13 100644 --- a/compiler/rustc_const_eval/src/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/check_consts/mod.rs @@ -117,18 +117,21 @@ pub fn is_safe_to_expose_on_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> b // Intrinsics default to "not exposed on stable". return false; } - // We allow calling unmarked local functions *in the current crate*. For the cross-crate - // case we require the other crate to explicitly add `#[rustc_const_stable_indirect]` as - // a promise that this function is meant to be indirectly const-stable, which will make - // `lookup_const_stability` return `Some`. + // We allow calling unmarked local functions *in the current crate*. This covers in + // particular all `const fn` whose inherited regular stability is `stable`, which means + // we don't infer any const stability for them. For the cross-crate case we require the + // other crate to explicitly add `#[rustc_const_stable_indirect]` as a promise that this + // function is meant to be indirectly const-stable, which will make + // `lookup_const_stability` return `Some`. This ensures that the other crate checked + // recursive const vailidty on that function, even if the other crate is not using + // `staged_api`. def_id.is_local() } Some(stab) => { - // `safe_to_expose_on_stable` implies `is_const_stable`. - if stab.is_const_stable() { - assert!(stab.safe_to_expose_on_stable); - } - stab.safe_to_expose_on_stable + stab.is_const_stable() || stab.const_stable_indirect || + // Non-intrinsic `const fn` without an explicit const stability attribute (i.e., + // with only the implied attribute) are safe to expose on stable. + (!stab.has_const_stable_attr && tcx.intrinsic(def_id).is_none()) } } } diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index c28164fa15b49..53b2537334e8b 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -865,11 +865,8 @@ impl SyntaxExtension { }) .unwrap_or_else(|| (None, helper_attrs)); let stability = attr::find_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 (const_stability, const_stable_indirect) = + attr::find_const_stability(sess, attrs, span); let body_stability = attr::find_body_stability(sess, attrs); if let Some((_, sp)) = const_stability { sess.dcx().emit_err(errors::MacroConstStability { @@ -877,6 +874,12 @@ impl SyntaxExtension { head_span: sess.source_map().guess_head_span(span), }); } + if let Some(sp) = const_stable_indirect { + sess.dcx().emit_err(errors::MacroConstStability { + span: sp, + head_span: sess.source_map().guess_head_span(span), + }); + } if let Some((_, sp)) = body_stability { sess.dcx().emit_err(errors::MacroBodyStability { span: sp, diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index a36de35c698e4..3058f1876aeb0 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -456,7 +456,6 @@ passes_maybe_string_interpolation = you might have meant to use string interpola passes_missing_const_err = 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 passes_missing_const_stab_attr = {$descr} has missing const stability attribute diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 42c8edf5bb765..5ad6ef275738f 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1551,8 +1551,6 @@ pub(crate) struct MissingConstErr { #[primary_span] #[help] pub fn_sig_span: Span, - #[label] - pub const_span: Span, } #[derive(Diagnostic)] diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index ec289d2ec69b0..62f4697c6e459 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -26,7 +26,6 @@ use rustc_session::lint; use rustc_session::lint::builtin::{INEFFECTIVE_UNSTABLE_TRAIT_IMPL, USELESS_DEPRECATED}; use rustc_span::Span; use rustc_span::symbol::{Symbol, sym}; -use rustc_target::spec::abi::Abi; use tracing::{debug, info}; use crate::errors; @@ -106,6 +105,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { def_id: LocalDefId, item_sp: Span, fn_sig: Option<&'tcx hir::FnSig<'tcx>>, + is_foreign_item: bool, kind: AnnotationKind, inherit_deprecation: InheritDeprecation, inherit_const_stability: InheritConstStability, @@ -162,41 +162,10 @@ 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, - // 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 (const_stab, const_stable_indirect) = + attr::find_const_stability(self.tcx.sess, attrs, item_sp); let body_stab = attr::find_body_stability(self.tcx.sess, attrs); - // 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_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())) - { - self.tcx - .dcx() - .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 @@ -219,7 +188,12 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { debug!("annotate: const_stab not found, parent = {:?}", self.parent_const_stab); if let Some(parent) = self.parent_const_stab { if parent.is_const_unstable() { - self.index.const_stab_map.insert(def_id, parent); + let mut inherited = parent; + // We have to manually apply `const_stable_indirect` here... this is such a mess. + if const_stable_indirect.is_some() { + inherited.const_stable_indirect = true; + } + self.index.const_stab_map.insert(def_id, inherited); } } } @@ -303,6 +277,34 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { } } + // If a `fn` ends up without const stability annotation, potentially add a default. + if let Some(fn_sig) = fn_sig + && !self.index.const_stab_map.contains_key(&def_id) + { + let stab = self.index.stab_map.get(&def_id); + if let Some(const_stab) = attr::default_const_stability( + self.tcx.sess, + fn_sig.header.is_const(), + const_stable_indirect.is_some(), + stab, + ) { + self.index.const_stab_map.insert(def_id, const_stab); + } + } + + // If the current node is a function with const stability attributes (directly given or + // implied), check if the function/method is const or the parent impl block is const. + if let Some(fn_sig) = fn_sig + && !fn_sig.header.is_const() + // We have to exclude foreign items as they might be intrinsics. Sadly we can't check + // their ABI; `fn_sig.abi` is *not* correct for foreign functions. + && !is_foreign_item + && self.index.const_stab_map.contains_key(&def_id) + && (!self.in_trait_impl || !self.tcx.is_const_fn_raw(def_id.to_def_id())) + { + self.tcx.dcx().emit_err(errors::MissingConstErr { fn_sig_span: fn_sig.span }); + } + self.recurse_with_stability_attrs( depr.map(|(d, _)| DeprecationEntry::local(d, def_id)), stab, @@ -385,6 +387,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { ctor_def_id, i.span, None, + /* is_foreign_item */ false, AnnotationKind::Required, InheritDeprecation::Yes, InheritConstStability::No, @@ -403,6 +406,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { i.owner_id.def_id, i.span, fn_sig, + /* is_foreign_item */ false, kind, InheritDeprecation::Yes, const_stab_inherit, @@ -422,6 +426,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { ti.owner_id.def_id, ti.span, fn_sig, + /* is_foreign_item */ false, AnnotationKind::Required, InheritDeprecation::Yes, InheritConstStability::No, @@ -445,6 +450,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { ii.owner_id.def_id, ii.span, fn_sig, + /* is_foreign_item */ false, kind, InheritDeprecation::Yes, InheritConstStability::No, @@ -460,6 +466,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { var.def_id, var.span, None, + /* is_foreign_item */ false, AnnotationKind::Required, InheritDeprecation::Yes, InheritConstStability::No, @@ -470,6 +477,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { ctor_def_id, var.span, None, + /* is_foreign_item */ false, AnnotationKind::Required, InheritDeprecation::Yes, InheritConstStability::No, @@ -488,6 +496,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { s.def_id, s.span, None, + /* is_foreign_item */ false, AnnotationKind::Required, InheritDeprecation::Yes, InheritConstStability::No, @@ -499,10 +508,15 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { } fn visit_foreign_item(&mut self, i: &'tcx hir::ForeignItem<'tcx>) { + let fn_sig = match &i.kind { + rustc_hir::ForeignItemKind::Fn(fn_sig, ..) => Some(fn_sig), + _ => None, + }; self.annotate( i.owner_id.def_id, i.span, - None, + fn_sig, + /* is_foreign_item */ true, AnnotationKind::Required, InheritDeprecation::Yes, InheritConstStability::No, @@ -525,6 +539,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { p.def_id, p.span, None, + /* is_foreign_item */ false, kind, InheritDeprecation::No, InheritConstStability::No, @@ -553,7 +568,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> { } } - fn check_missing_const_stability(&self, def_id: LocalDefId, span: Span) { + fn check_missing_or_wrong_const_stability(&self, def_id: LocalDefId, span: Span) { if !self.tcx.features().staged_api { return; } @@ -601,7 +616,7 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> { } // Ensure stable `const fn` have a const stability attribute. - self.check_missing_const_stability(i.owner_id.def_id, i.span); + self.check_missing_or_wrong_const_stability(i.owner_id.def_id, i.span); intravisit::walk_item(self, i) } @@ -615,7 +630,7 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> { let impl_def_id = self.tcx.hir().get_parent_item(ii.hir_id()); if self.tcx.impl_trait_ref(impl_def_id).is_none() { self.check_missing_stability(ii.owner_id.def_id, ii.span); - self.check_missing_const_stability(ii.owner_id.def_id, ii.span); + self.check_missing_or_wrong_const_stability(ii.owner_id.def_id, ii.span); } intravisit::walk_impl_item(self, ii); } @@ -684,6 +699,7 @@ fn stability_index(tcx: TyCtxt<'_>, (): ()) -> Index { CRATE_DEF_ID, tcx.hir().span(CRATE_HIR_ID), None, + /* is_foreign_item */ false, AnnotationKind::Required, InheritDeprecation::Yes, InheritConstStability::No, @@ -751,15 +767,8 @@ 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); - // 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), - ); + let (const_stab, _) = + attr::find_const_stability(self.tcx.sess, attrs, item.span); // 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 ed170f1d09541..f183bd204306b 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -75,7 +75,6 @@ impl Layout { } } - #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] const fn is_size_align_valid(size: usize, align: usize) -> bool { let Some(align) = Alignment::new(align) else { return false }; if size > Self::max_size_for_align(align) { @@ -85,7 +84,6 @@ impl Layout { } #[inline(always)] - #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[rustc_allow_const_fn_unstable(unchecked_math)] const fn max_size_for_align(align: Alignment) -> usize { // (power-of-two implies align != 0.) diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 760f032ce2ca9..f3b54230bc1a5 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -333,8 +333,10 @@ pub struct Arguments<'a> { #[unstable(feature = "fmt_internals", issue = "none")] impl<'a> Arguments<'a> { #[inline] - #[rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none")] - #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] + #[cfg_attr( + bootstrap, + rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none") + )] pub const fn new_const(pieces: &'a [&'static str; N]) -> Self { const { assert!(N <= 1) }; Arguments { pieces, fmt: None, args: &[] } diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 9e777765dbe45..78df51f2bc47d 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -506,8 +506,7 @@ pub const fn black_box(dummy: T) -> T { /// # } /// ``` #[unstable(feature = "hint_must_use", issue = "94745")] -#[rustc_const_unstable(feature = "hint_must_use", issue = "94745")] -#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // exposed via macro +#[cfg_attr(bootstrap, rustc_const_unstable(feature = "hint_must_use", issue = "94745"))] #[must_use] // <-- :) #[inline(always)] pub const fn must_use(value: T) -> T { diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index 86660f2e375c3..2cf2ea58fd4ee 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -346,7 +346,6 @@ pub trait IntoIterator { fn into_iter(self) -> Self::IntoIter; } -#[rustc_const_unstable(feature = "const_intoiterator_identity", issue = "90603")] #[stable(feature = "rust1", since = "1.0.0")] impl IntoIterator for I { type Item = I::Item; diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 166ddcfcaa446..e1585409d507f 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -107,6 +107,7 @@ // // Library features: // tidy-alphabetical-start +#![cfg_attr(bootstrap, feature(const_fmt_arguments_new))] #![feature(array_ptr_get)] #![feature(asm_experimental_arch)] #![feature(const_align_of_val)] @@ -122,10 +123,8 @@ #![feature(const_char_encode_utf8)] #![feature(const_eval_select)] #![feature(const_exact_div)] -#![feature(const_fmt_arguments_new)] #![feature(const_hash)] #![feature(const_heap)] -#![feature(const_index_range_slice_index)] #![feature(const_intrinsic_forget)] #![feature(const_ipv4)] #![feature(const_ipv6)] diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 5024dc0016cdc..4b344de98699f 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -1398,7 +1398,6 @@ from_str_radix_int_impl! { isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128 } #[inline(always)] #[unstable(issue = "none", feature = "std_internals")] #[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 0b134670005c0..8e62fd85912d7 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -3010,7 +3010,6 @@ macro_rules! uint_impl { // of the type, and can return 0 for 0. #[inline] #[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 48018efdfd2dd..7735f4a9b577a 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -51,7 +51,6 @@ const _: () = assert!(cfg!(panic = "abort"), "panic_immediate_abort requires -C #[lang = "panic_fmt"] // needed for const-evaluated panics #[rustc_do_not_const_check] // hooked by const-eval #[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") { super::intrinsics::abort() @@ -86,7 +85,6 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { // which causes a "panic in a function that cannot unwind". #[rustc_nounwind] #[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) -> ! { #[inline] // this should always be inlined into `panic_nounwind_fmt` @@ -135,7 +133,6 @@ pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: boo #[cfg_attr(feature = "panic_immediate_abort", inline)] #[track_caller] #[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) -> ! { // Use Arguments::new_const instead of format_args!("{expr}") to potentially @@ -174,7 +171,6 @@ macro_rules! panic_const { #[cfg_attr(feature = "panic_immediate_abort", inline)] #[track_caller] #[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 @@ -222,7 +218,6 @@ panic_const! { #[lang = "panic_nounwind"] // needed by codegen for non-unwinding panics #[rustc_nounwind] #[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); } @@ -239,7 +234,6 @@ pub fn panic_nounwind_nobacktrace(expr: &'static str) -> ! { #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[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"); } @@ -257,7 +251,6 @@ pub fn unreachable_display(x: &T) -> ! { #[track_caller] #[rustc_diagnostic_item = "panic_str_2015"] #[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); } @@ -268,7 +261,6 @@ pub const fn panic_str_2015(expr: &str) -> ! { // enforce a &&str argument in const-check and hook this by const-eval #[rustc_const_panic_str] #[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)); } @@ -338,7 +330,6 @@ 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 #[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() { // The panic_display function is hooked by const eval. diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs index 1f3b2f71608f6..2538d60a8eee9 100644 --- a/library/core/src/ptr/alignment.rs +++ b/library/core/src/ptr/alignment.rs @@ -55,7 +55,6 @@ impl Alignment { #[unstable(feature = "ptr_alignment_type", issue = "102070")] #[cfg_attr(bootstrap, rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070"))] #[inline] - #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] pub const fn new(align: usize) -> Option { if align.is_power_of_two() { // SAFETY: Just checked it only has one bit set diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index cf586f6187c2a..617ef5a8ab2de 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -649,7 +649,6 @@ pub const fn null_mut() -> *mut T { 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. @@ -675,7 +674,6 @@ pub const fn without_provenance(addr: usize) -> *const T { 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::()) @@ -701,7 +699,6 @@ pub const fn dangling() -> *const T { 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. @@ -727,7 +724,6 @@ pub const fn without_provenance_mut(addr: usize) -> *mut T { 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/index.rs b/library/core/src/slice/index.rs index 44881803a3a28..231ab7396adfd 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -313,7 +313,6 @@ unsafe impl SliceIndex<[T]> for usize { /// Because `IndexRange` guarantees `start <= end`, fewer checks are needed here /// than there are for a general `Range` (which might be `100..3`). -#[rustc_const_unstable(feature = "const_index_range_slice_index", issue = "none")] unsafe impl SliceIndex<[T]> for ops::IndexRange { type Output = [T]; diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs index cc09596e8696d..9edb3fa41933d 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -238,7 +238,6 @@ impl LocalKey { 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/borrowck/issue-64453.rs b/tests/ui/borrowck/issue-64453.rs index 33d55be5812e7..5f1f35d6ca9bb 100644 --- a/tests/ui/borrowck/issue-64453.rs +++ b/tests/ui/borrowck/issue-64453.rs @@ -3,7 +3,6 @@ struct Value; static settings_dir: String = format!(""); //~^ ERROR cannot call non-const fn -//~| ERROR is not yet stable as a const fn from_string(_: String) -> Value { Value diff --git a/tests/ui/borrowck/issue-64453.stderr b/tests/ui/borrowck/issue-64453.stderr index e671817633be4..98b05ead64918 100644 --- a/tests/ui/borrowck/issue-64453.stderr +++ b/tests/ui/borrowck/issue-64453.stderr @@ -1,12 +1,3 @@ -error: `Arguments::<'a>::new_const` is not yet stable as a const fn - --> $DIR/issue-64453.rs:4:31 - | -LL | static settings_dir: String = format!(""); - | ^^^^^^^^^^^ - | - = help: add `#![feature(const_fmt_arguments_new)]` to the crate attributes to enable - = note: this error originates in the macro `$crate::__export::format_args` which comes from the expansion of the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) - error[E0015]: cannot call non-const fn `format` in statics --> $DIR/issue-64453.rs:4:31 | @@ -18,7 +9,7 @@ LL | static settings_dir: String = format!(""); = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0507]: cannot move out of static item `settings_dir` - --> $DIR/issue-64453.rs:14:37 + --> $DIR/issue-64453.rs:13:37 | LL | let settings_data = from_string(settings_dir); | ^^^^^^^^^^^^ move occurs because `settings_dir` has type `String`, which does not implement the `Copy` trait @@ -28,7 +19,7 @@ help: consider cloning the value if the performance cost is acceptable LL | let settings_data = from_string(settings_dir.clone()); | ++++++++ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0015, E0507. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/const-eval/simd/insert_extract.rs b/tests/ui/consts/const-eval/simd/insert_extract.rs index f4f25327aaf11..57d4b4888caa9 100644 --- a/tests/ui/consts/const-eval/simd/insert_extract.rs +++ b/tests/ui/consts/const-eval/simd/insert_extract.rs @@ -11,8 +11,11 @@ #[repr(simd)] struct f32x4([f32; 4]); extern "rust-intrinsic" { + #[stable(feature = "foo", since = "1.3.37")] #[rustc_const_stable(feature = "foo", since = "1.3.37")] fn simd_insert(x: T, idx: u32, val: U) -> T; + + #[stable(feature = "foo", since = "1.3.37")] #[rustc_const_stable(feature = "foo", since = "1.3.37")] fn simd_extract(x: T, idx: u32) -> U; } diff --git a/tests/ui/consts/copy-intrinsic.rs b/tests/ui/consts/copy-intrinsic.rs index 805c03da546ab..62917c0b98b2c 100644 --- a/tests/ui/consts/copy-intrinsic.rs +++ b/tests/ui/consts/copy-intrinsic.rs @@ -5,9 +5,11 @@ use std::mem; extern "rust-intrinsic" { + #[stable(feature = "dummy", since = "1.0.0")] #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")] fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize); + #[stable(feature = "dummy", since = "1.0.0")] #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")] fn copy(src: *const T, dst: *mut T, count: usize); } diff --git a/tests/ui/consts/copy-intrinsic.stderr b/tests/ui/consts/copy-intrinsic.stderr index da8139129c9f3..29a88f6270bc6 100644 --- a/tests/ui/consts/copy-intrinsic.stderr +++ b/tests/ui/consts/copy-intrinsic.stderr @@ -1,23 +1,23 @@ error[E0080]: evaluation of constant value failed - --> $DIR/copy-intrinsic.rs:28:5 + --> $DIR/copy-intrinsic.rs:30:5 | LL | copy_nonoverlapping(0x100 as *const i32, dangle, 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: expected a pointer to 4 bytes of memory, but got 0x100[noalloc] which is a dangling pointer (it has no provenance) error[E0080]: evaluation of constant value failed - --> $DIR/copy-intrinsic.rs:37:5 + --> $DIR/copy-intrinsic.rs:39:5 | LL | copy_nonoverlapping(dangle, 0x100 as *mut i32, 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: expected a pointer to 4 bytes of memory, but got ALLOC0+0x28 which is at or beyond the end of the allocation of size 4 bytes error[E0080]: evaluation of constant value failed - --> $DIR/copy-intrinsic.rs:44:5 + --> $DIR/copy-intrinsic.rs:46:5 | LL | copy(&x, &mut y, 1usize << (mem::size_of::() * 8 - 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow computing total size of `copy` error[E0080]: evaluation of constant value failed - --> $DIR/copy-intrinsic.rs:50:5 + --> $DIR/copy-intrinsic.rs:52:5 | LL | copy_nonoverlapping(&x, &mut y, 1usize << (mem::size_of::() * 8 - 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow computing total size of `copy_nonoverlapping` diff --git a/tests/ui/consts/rustc-const-stability-require-const.stderr b/tests/ui/consts/rustc-const-stability-require-const.stderr index c539b89121f76..d9a7d37cbcd25 100644 --- a/tests/ui/consts/rustc-const-stability-require-const.stderr +++ b/tests/ui/consts/rustc-const-stability-require-const.stderr @@ -1,8 +1,6 @@ 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")] - | -------------------------------------------------------------- attribute specified here LL | pub fn foo() {} | ^^^^^^^^^^^^ | @@ -15,8 +13,6 @@ LL | pub fn foo() {} 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")] - | ------------------------------------------------------------- attribute specified here LL | pub fn bar() {} | ^^^^^^^^^^^^ | @@ -29,8 +25,6 @@ LL | pub fn bar() {} 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")] - | ---------------------------------------------------------------- attribute specified here LL | pub fn salad(&self) -> &'static str { "mmmmmm" } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | @@ -43,8 +37,6 @@ LL | pub fn salad(&self) -> &'static str { "mmmmmm" } 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")] - | ------------------------------------------------------------------ attribute specified here LL | pub fn roasted(&self) -> &'static str { "mmmmmmmmmm" } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | @@ -57,8 +49,6 @@ LL | pub fn roasted(&self) -> &'static str { "mmmmmmmmmm" } 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")] - | ------------------------------------------------------------- attribute specified here LL | pub extern "C" fn bar_c() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | @@ -71,8 +61,6 @@ LL | pub extern "C" fn bar_c() {} 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")] - | -------------------------------------------------------------- attribute specified here LL | pub extern "C" fn foo_c() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | @@ -102,7 +90,7 @@ error: attributes `#[rustc_const_unstable]`, `#[rustc_const_stable]` and `#[rust --> $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 diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.rs index b8b9e07b3bd60..cdefebc87d675 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.rs @@ -1,6 +1,5 @@ //@ compile-flags: -Znext-solver #![allow(incomplete_features)] -#![feature(const_fmt_arguments_new)] #![feature(const_trait_impl, effects)] #[const_trait] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.stderr index 9e6348d37ed5e..49f380c1a2b57 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.stderr @@ -1,5 +1,5 @@ error[E0015]: cannot call non-const fn `_print` in constant functions - --> $DIR/issue-79450.rs:11:9 + --> $DIR/issue-79450.rs:10:9 | LL | println!("lul"); | ^^^^^^^^^^^^^^^