diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 707a3f2d3c7..c8c82c711de 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -130,7 +130,6 @@ pub(super) fn explicit_item_bounds_with_filter( let parent = tcx.local_parent(def_id); - let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); let preds = tcx.explicit_predicates_of(parent); if let ty::AssocItemContainer::TraitContainer = tcx.associated_item(def_id).container { @@ -141,8 +140,7 @@ pub(super) fn explicit_item_bounds_with_filter( let span = tcx.def_span(def_id); let assoc = tcx.require_lang_item(hir::LangItem::EffectsMinOutput, Some(span)); let proj = Ty::new_projection(tcx, assoc, [tup]); - // TODO this is bad - let self_proj = Ty::new_projection(tcx, def_id.to_def_id(), identity_args); + let self_proj = Ty::new_projection(tcx, def_id.to_def_id(), ty::GenericArgs::identity_for_item(tcx, def_id)); let trait_ = tcx.require_lang_item(hir::LangItem::EffectsTyCompat, Some(span)); let trait_ref = ty::TraitRef::new(tcx, trait_, [self_proj, proj]); predicates.push((ty::Binder::dummy(trait_ref).upcast(tcx), span)); diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 9a5feaf3d3c..cc3078f037a 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -57,6 +57,7 @@ pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredic #[instrument(level = "trace", skip(tcx), ret)] fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::GenericPredicates<'_> { use rustc_hir::*; + use rustc_middle::ty::Ty; match tcx.opt_rpitit_info(def_id.to_def_id()) { Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) => { @@ -313,6 +314,24 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen debug!(?predicates); } + // add `Self::Effects: Compat` to ensure non-const impls don't get called + // in const contexts. + if let Node::TraitItem(&TraitItem { kind: TraitItemKind::Fn(..), .. }) = node + && let Some(host_effect_index) = generics.host_effect_index + { + let parent = generics.parent.unwrap(); + let Some(assoc_def_id) = tcx.associated_type_for_effects(parent) else { + bug!("associated_type_for_effects returned None when there is host effect in generics"); + }; + let effects = Ty::new_projection(tcx, assoc_def_id, ty::GenericArgs::identity_for_item(tcx, parent)); + let param = generics.param_at(host_effect_index, tcx); + let span = tcx.def_span(param.def_id); + let host = ty::Const::new_param(tcx, ty::ParamConst::for_def(param)); + let compat = tcx.require_lang_item(LangItem::EffectsCompat, Some(span)); + let trait_ref = ty::TraitRef::new(tcx, compat, [ty::GenericArg::from(effects), host.into()]); + predicates.push((ty::Binder::dummy(trait_ref).upcast(tcx), span)); + } + ty::GenericPredicates { parent: generics.parent, predicates: tcx.arena.alloc_from_iter(predicates),