@@ -313,7 +313,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
313313 . map ( |( stab, _span) | ConstStability :: from_partial ( stab, const_stability_indirect) ) ;
314314
315315 // If this is a const fn but not annotated with stability markers, see if we can inherit regular stability.
316- if fn_sig. is_some_and ( |s| s. header . is_const ( ) ) && const_stab. is_none ( ) &&
316+ if fn_sig. is_some_and ( |s| s. header . is_const ( ) ) && const_stab. is_none ( ) &&
317317 // We only ever inherit unstable features.
318318 let Some ( inherit_regular_stab) =
319319 final_stab. filter ( |s| s. is_unstable ( ) )
@@ -826,24 +826,56 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
826826 }
827827 }
828828
829- // `#![feature(const_trait_impl)]` is unstable, so any impl declared stable
830- // needs to have an error emitted.
831829 if features. const_trait_impl ( )
832- && self . tcx . is_const_trait_impl ( item. owner_id . to_def_id ( ) )
833- && const_stab. is_some_and ( |stab| stab. is_const_stable ( ) )
830+ && let hir:: Constness :: Const = constness
834831 {
835- self . tcx . dcx ( ) . emit_err ( errors:: TraitImplConstStable { span : item. span } ) ;
832+ let stable_or_implied_stable = match const_stab {
833+ None => true ,
834+ Some ( stab) if stab. is_const_stable ( ) => {
835+ // `#![feature(const_trait_impl)]` is unstable, so any impl declared stable
836+ // needs to have an error emitted.
837+ // Note: Remove this error once `const_trait_impl` is stabilized
838+ self . tcx
839+ . dcx ( )
840+ . emit_err ( errors:: TraitImplConstStable { span : item. span } ) ;
841+ true
842+ }
843+ Some ( _) => false ,
844+ } ;
845+
846+ if let Some ( trait_id) = t. trait_def_id ( )
847+ && let Some ( const_stab) = self . tcx . lookup_const_stability ( trait_id)
848+ {
849+ // the const stability of a trait impl must match the const stability on the trait.
850+ if const_stab. is_const_stable ( ) != stable_or_implied_stable {
851+ let trait_span = self . tcx . def_ident_span ( trait_id) . unwrap ( ) ;
852+
853+ let impl_stability = if stable_or_implied_stable {
854+ errors:: ImplConstStability :: Stable { span : item. span }
855+ } else {
856+ errors:: ImplConstStability :: Unstable { span : item. span }
857+ } ;
858+ let trait_stability = if const_stab. is_const_stable ( ) {
859+ errors:: TraitConstStability :: Stable { span : trait_span }
860+ } else {
861+ errors:: TraitConstStability :: Unstable { span : trait_span }
862+ } ;
863+
864+ self . tcx . dcx ( ) . emit_err ( errors:: TraitImplConstStabilityMismatch {
865+ span : item. span ,
866+ impl_stability,
867+ trait_stability,
868+ } ) ;
869+ }
870+ }
836871 }
837872 }
838873
839- match constness {
840- rustc_hir:: Constness :: Const => {
841- if let Some ( def_id) = t. trait_def_id ( ) {
842- // FIXME(const_trait_impl): Improve the span here.
843- self . tcx . check_const_stability ( def_id, t. path . span , t. path . span ) ;
844- }
845- }
846- rustc_hir:: Constness :: NotConst => { }
874+ if let hir:: Constness :: Const = constness
875+ && let Some ( def_id) = t. trait_def_id ( )
876+ {
877+ // FIXME(const_trait_impl): Improve the span here.
878+ self . tcx . check_const_stability ( def_id, t. path . span , t. path . span ) ;
847879 }
848880
849881 for impl_item_ref in * items {
0 commit comments