@@ -57,6 +57,7 @@ pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredic
5757#[ instrument( level = "trace" , skip( tcx) , ret) ]
5858fn gather_explicit_predicates_of ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) -> ty:: GenericPredicates < ' _ > {
5959 use rustc_hir:: * ;
60+ use rustc_middle:: ty:: Ty ;
6061
6162 match tcx. opt_rpitit_info ( def_id. to_def_id ( ) ) {
6263 Some ( ImplTraitInTraitData :: Trait { fn_def_id, .. } ) => {
@@ -313,6 +314,24 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
313314 debug ! ( ?predicates) ;
314315 }
315316
317+ // add `Self::Effects: Compat<HOST>` to ensure non-const impls don't get called
318+ // in const contexts.
319+ if let Node :: TraitItem ( & TraitItem { kind : TraitItemKind :: Fn ( ..) , .. } ) = node
320+ && let Some ( host_effect_index) = generics. host_effect_index
321+ {
322+ let parent = generics. parent . unwrap ( ) ;
323+ let Some ( assoc_def_id) = tcx. associated_type_for_effects ( parent) else {
324+ bug ! ( "associated_type_for_effects returned None when there is host effect in generics" ) ;
325+ } ;
326+ let effects = Ty :: new_projection ( tcx, assoc_def_id, ty:: GenericArgs :: identity_for_item ( tcx, parent) ) ;
327+ let param = generics. param_at ( host_effect_index, tcx) ;
328+ let span = tcx. def_span ( param. def_id ) ;
329+ let host = ty:: Const :: new_param ( tcx, ty:: ParamConst :: for_def ( param) ) ;
330+ let compat = tcx. require_lang_item ( LangItem :: EffectsCompat , Some ( span) ) ;
331+ let trait_ref = ty:: TraitRef :: new ( tcx, compat, [ ty:: GenericArg :: from ( effects) , host. into ( ) ] ) ;
332+ predicates. push ( ( ty:: Binder :: dummy ( trait_ref) . upcast ( tcx) , span) ) ;
333+ }
334+
316335 ty:: GenericPredicates {
317336 parent : generics. parent ,
318337 predicates : tcx. arena . alloc_from_iter ( predicates) ,
0 commit comments