@@ -162,19 +162,32 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
162162 }
163163
164164 let stab = attr:: find_stability ( self . tcx . sess , attrs, item_sp) ;
165- let const_stab = attr:: find_const_stability ( self . tcx . sess , attrs, item_sp) ;
165+ let const_stab = attr:: find_const_stability (
166+ self . tcx . sess ,
167+ attrs,
168+ item_sp,
169+ // Compute the feature gate we inherit if this
170+ // doesn't have its own feature gate.
171+ self . parent_const_stab . and_then ( |c| c. feature ) . or_else ( || {
172+ // Infer the const feature gate from the regular feature gate,
173+ // but only if that regular gate is unstable.
174+ if let Some ( ( s, _) ) = stab {
175+ s. is_unstable ( ) . then_some ( s. feature )
176+ } else if inherit_deprecation. yes ( )
177+ && let Some ( parent_stab) = self . parent_stab
178+ && parent_stab. is_unstable ( )
179+ {
180+ Some ( parent_stab. feature )
181+ } else {
182+ None
183+ }
184+ } ) ,
185+ ) ;
166186 let body_stab = attr:: find_body_stability ( self . tcx . sess , attrs) ;
167- let mut const_span = None ;
168-
169- let const_stab = const_stab. map ( |( const_stab, const_span_node) | {
170- self . index . const_stab_map . insert ( def_id, const_stab) ;
171- const_span = Some ( const_span_node) ;
172- const_stab
173- } ) ;
174187
175188 // If the current node is a function, has const stability attributes and if it doesn not have an intrinsic ABI,
176189 // check if the function/method is const or the parent impl block is const
177- if let ( Some ( const_span) , Some ( fn_sig) ) = ( const_span , fn_sig)
190+ if let ( Some ( ( _ , const_span) ) , Some ( fn_sig) ) = ( const_stab , fn_sig)
178191 && fn_sig. header . abi != Abi :: RustIntrinsic
179192 && !fn_sig. header . is_const ( )
180193 && ( !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> {
184197 . emit_err ( errors:: MissingConstErr { fn_sig_span : fn_sig. span , const_span } ) ;
185198 }
186199
200+ // If this is marked const *stable*, it must also be regular-stable.
201+ if let Some ( ( const_stab, const_span) ) = const_stab
202+ && let Some ( fn_sig) = fn_sig
203+ && const_stab. is_const_stable ( )
204+ && !stab. is_some_and ( |( s, _) | s. is_stable ( ) )
205+ {
206+ self . tcx
207+ . dcx ( )
208+ . emit_err ( errors:: ConstStableNotStable { fn_sig_span : fn_sig. span , const_span } ) ;
209+ }
210+
211+ let const_stab = const_stab. map ( |( const_stab, _span) | {
212+ self . index . const_stab_map . insert ( def_id, const_stab) ;
213+ const_stab
214+ } ) ;
215+
187216 // `impl const Trait for Type` items forward their const stability to their
188217 // immediate children.
189218 if const_stab. is_none ( ) {
@@ -274,8 +303,6 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
274303 }
275304 }
276305
277- // Every `const fn` that has stability should also have const-stability.
278-
279306 self . recurse_with_stability_attrs (
280307 depr. map ( |( d, _) | DeprecationEntry :: local ( d, def_id) ) ,
281308 stab,
@@ -724,7 +751,15 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
724751 if features. staged_api {
725752 let attrs = self . tcx . hir ( ) . attrs ( item. hir_id ( ) ) ;
726753 let stab = attr:: find_stability ( self . tcx . sess , attrs, item. span ) ;
727- let const_stab = attr:: find_const_stability ( self . tcx . sess , attrs, item. span ) ;
754+ // FIXME: this will give a different result than the normal stability
755+ // computation, since we don't inherit stability from the parent. But that's
756+ // true even for `stab` above so it's probably okay?
757+ let const_stab = attr:: find_const_stability (
758+ self . tcx . sess ,
759+ attrs,
760+ item. span ,
761+ stab. map ( |( s, _) | s. feature ) ,
762+ ) ;
728763
729764 // If this impl block has an #[unstable] attribute, give an
730765 // error if all involved types and traits are stable, because
0 commit comments