Implement `Self::Effects: Compat<HOST>` desugaring

This commit is contained in:
Deadbeef 2024-06-25 09:19:23 +00:00
parent b9886c6872
commit f852a2c173
2 changed files with 20 additions and 3 deletions

View File

@ -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));

View File

@ -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<HOST>` 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),