@@ -301,7 +301,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
301301 let mut const_stab = const_stab. map ( |( stab, _span) | stab) ;
302302
303303 // If this is a const fn but not annotated with stability markers, see if we can inherit regular stability.
304- if fn_sig. is_some_and ( |s| s. header . is_const ( ) ) && const_stab. is_none ( ) &&
304+ if fn_sig. is_some_and ( |s| s. header . is_const ( ) ) && const_stab. is_none ( ) &&
305305 // We only ever inherit unstable features.
306306 let Some ( inherit_regular_stab) =
307307 final_stab. filter ( |s| s. is_unstable ( ) )
@@ -816,24 +816,54 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
816816 }
817817 }
818818
819- // `#![feature(const_trait_impl)]` is unstable, so any impl declared stable
820- // needs to have an error emitted.
821- if features. const_trait_impl ( )
822- && self . tcx . is_const_trait_impl ( item. owner_id . to_def_id ( ) )
823- && const_stab. is_some_and ( |( stab, _) | stab. is_const_stable ( ) )
824- {
825- self . tcx . dcx ( ) . emit_err ( errors:: TraitImplConstStable { span : item. span } ) ;
819+ if features. const_trait_impl ( ) && hir:: Constness :: Const == * constness {
820+ let stable_or_implied_stable = match const_stab {
821+ None => true ,
822+ Some ( ( stab, _) ) if stab. is_const_stable ( ) => {
823+ // `#![feature(const_trait_impl)]` is unstable, so any impl declared stable
824+ // needs to have an error emitted.
825+ // Note: Remove this error once `const_trait_impl` is stabilized
826+ self . tcx
827+ . dcx ( )
828+ . emit_err ( errors:: TraitImplConstStable { span : item. span } ) ;
829+ true
830+ }
831+ Some ( _) => false ,
832+ } ;
833+
834+ if let Some ( trait_id) = t. trait_def_id ( )
835+ && let Some ( const_stab) = self . tcx . lookup_const_stability ( trait_id)
836+ {
837+ // the const stability of a trait impl must match the const stability on the trait.
838+ if const_stab. is_const_stable ( ) != stable_or_implied_stable {
839+ let trait_span = self . tcx . def_ident_span ( trait_id) . unwrap ( ) ;
840+
841+ let impl_stability = if stable_or_implied_stable {
842+ errors:: ImplConstStability :: Stable { span : item. span }
843+ } else {
844+ errors:: ImplConstStability :: Unstable { span : item. span }
845+ } ;
846+ let trait_stability = if const_stab. is_const_stable ( ) {
847+ errors:: TraitConstStability :: Stable { span : trait_span }
848+ } else {
849+ errors:: TraitConstStability :: Unstable { span : trait_span }
850+ } ;
851+
852+ self . tcx . dcx ( ) . emit_err ( errors:: TraitImplConstStabilityMismatch {
853+ span : item. span ,
854+ impl_stability,
855+ trait_stability,
856+ } ) ;
857+ }
858+ }
826859 }
827860 }
828861
829- match constness {
830- rustc_hir:: Constness :: Const => {
831- if let Some ( def_id) = t. trait_def_id ( ) {
832- // FIXME(const_trait_impl): Improve the span here.
833- self . tcx . check_const_stability ( def_id, t. path . span , t. path . span ) ;
834- }
835- }
836- rustc_hir:: Constness :: NotConst => { }
862+ if let hir:: Constness :: Const = constness
863+ && let Some ( def_id) = t. trait_def_id ( )
864+ {
865+ // FIXME(const_trait_impl): Improve the span here.
866+ self . tcx . check_const_stability ( def_id, t. path . span , t. path . span ) ;
837867 }
838868
839869 for impl_item_ref in * items {
0 commit comments