diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 34f1ca55c7875..55f3dceb6a8ce 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -300,11 +300,27 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { // const stability: inherit feature gate from regular stability. let mut const_stab = const_stab.map(|(stab, _span)| stab); + // `impl const Trait for Type` items forward their const stability to their + // immediate children. + // FIXME(const_trait_impl): how is this supposed to interact with `#[rustc_const_stable_indirect]`? + // Currently, once that is set, we do not inherit anything from the parent any more. + if const_stab.is_none() + && let Some(parent) = self.parent_const_stab + && parent.is_const_unstable() + { + // For now, `const fn` in const traits/trait impls does not exist. + assert!( + fn_sig.is_none_or(|s| !s.header.is_const()), + "should never have parent const stability for a const fn" + ); + self.index.const_stab_map.insert(def_id, parent); + } + // If this is a const fn but not annotated with stability markers, see if we can inherit regular stability. - if fn_sig.is_some_and(|s| s.header.is_const()) && const_stab.is_none() && + if fn_sig.is_some_and(|s| s.header.is_const()) + && const_stab.is_none() // We only ever inherit unstable features. - let Some(inherit_regular_stab) = - final_stab.filter(|s| s.is_unstable()) + && let Some(inherit_regular_stab) = final_stab.filter(|s| s.is_unstable()) { const_stab = Some(ConstStability { // We subject these implicitly-const functions to recursive const stability. @@ -329,19 +345,6 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { self.index.implications.insert(implied_by, feature); } - // `impl const Trait for Type` items forward their const stability to their - // immediate children. - // FIXME(const_trait_impl): how is this supposed to interact with `#[rustc_const_stable_indirect]`? - // Currently, once that is set, we do not inherit anything from the parent any more. - if const_stab.is_none() { - 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); - } - } - } - self.recurse_with_stability_attrs( depr.map(|(d, _)| DeprecationEntry::local(d, def_id)), stab, @@ -418,6 +421,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { kind = AnnotationKind::DeprecationProhibited; const_stab_inherit = InheritConstStability::Yes; } + hir::ItemKind::Trait(..) => { + const_stab_inherit = InheritConstStability::Yes; + } hir::ItemKind::Struct(ref sd, _) => { if let Some(ctor_def_id) = sd.ctor_def_id() { self.annotate( diff --git a/tests/ui/traits/const-traits/auxiliary/staged-api.rs b/tests/ui/traits/const-traits/auxiliary/staged-api.rs index 933a25769dca2..f6f4075e8374c 100644 --- a/tests/ui/traits/const-traits/auxiliary/staged-api.rs +++ b/tests/ui/traits/const-traits/auxiliary/staged-api.rs @@ -9,6 +9,13 @@ pub trait MyTrait { #[stable(feature = "rust1", since = "1.0.0")] fn func(); + + #[stable(feature = "rust1", since = "1.0.0")] + fn default() { + // This call is const-unstable, but permitted here since we inherit + // the `rustc_const_unstable` above. + T::func(); + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -18,6 +25,12 @@ pub struct Unstable; #[rustc_const_unstable(feature = "unstable", issue = "none")] impl const MyTrait for Unstable { fn func() {} + + fn default() { + // This call is const-unstable, but permitted here since we inherit + // the `rustc_const_unstable` above. + T::func(); + } } #[stable(feature = "rust1", since = "1.0.0")]