Auto merge of #129499 - fee1-dead-contrib:supereffects, r=compiler-errors
properly elaborate effects implied bounds for super traits Summary: This PR makes it so that we elaborate `<T as Tr>::Fx: EffectsCompat<somebool>` into `<T as SuperTr>::Fx: EffectsCompat<somebool>` when we know that `trait Tr: ~const SuperTr`. Some discussion at https://github.com/rust-lang/project-const-traits/issues/2. r? project-const-traits `@rust-lang/project-const-traits:` how do we feel about this approach?
This commit is contained in:
commit
4e91cedaed
11 changed files with 132 additions and 84 deletions
|
@ -91,12 +91,46 @@ impl<'tcx> Bounds<'tcx> {
|
|||
}
|
||||
tcx.consts.true_
|
||||
}
|
||||
(DefKind::Trait, ty::BoundConstness::ConstIfConst) => {
|
||||
// we are in a trait, where `bound_trait_ref` could be:
|
||||
// (1) a super trait `trait Foo: ~const Bar`.
|
||||
// - This generates `<Self as Foo>::Effects: TyCompat<<Self as Bar>::Effects>`
|
||||
//
|
||||
// (2) a where clause `where for<..> Something: ~const Bar`.
|
||||
// - This generates `for<..> <Self as Foo>::Effects: TyCompat<<Something as Bar>::Effects>`
|
||||
let Some(own_fx) = tcx.associated_type_for_effects(defining_def_id) else {
|
||||
tcx.dcx().span_delayed_bug(span, "should not have allowed `~const` on a trait that doesn't have `#[const_trait]`");
|
||||
return;
|
||||
};
|
||||
let own_fx_ty = Ty::new_projection(
|
||||
tcx,
|
||||
own_fx,
|
||||
ty::GenericArgs::identity_for_item(tcx, own_fx),
|
||||
);
|
||||
let Some(their_fx) = tcx.associated_type_for_effects(bound_trait_ref.def_id())
|
||||
else {
|
||||
tcx.dcx().span_delayed_bug(span, "`~const` on trait without Effects assoc");
|
||||
return;
|
||||
};
|
||||
let their_fx_ty =
|
||||
Ty::new_projection(tcx, their_fx, bound_trait_ref.skip_binder().args);
|
||||
let compat = tcx.require_lang_item(LangItem::EffectsTyCompat, Some(span));
|
||||
let clause = bound_trait_ref
|
||||
.map_bound(|_| {
|
||||
let trait_ref = ty::TraitRef::new(tcx, compat, [own_fx_ty, their_fx_ty]);
|
||||
ty::ClauseKind::Trait(ty::TraitPredicate {
|
||||
trait_ref,
|
||||
polarity: ty::PredicatePolarity::Positive,
|
||||
})
|
||||
})
|
||||
.upcast(tcx);
|
||||
|
||||
(
|
||||
DefKind::Trait | DefKind::Impl { of_trait: true },
|
||||
ty::BoundConstness::ConstIfConst,
|
||||
) => {
|
||||
// this is either a where clause on an impl/trait header or on a trait.
|
||||
self.clauses.push((clause, span));
|
||||
return;
|
||||
}
|
||||
|
||||
(DefKind::Impl { of_trait: true }, ty::BoundConstness::ConstIfConst) => {
|
||||
// this is a where clause on an impl header.
|
||||
// push `<T as Tr>::Effects` into the set for the `Min` bound.
|
||||
let Some(assoc) = tcx.associated_type_for_effects(bound_trait_ref.def_id()) else {
|
||||
tcx.dcx().span_delayed_bug(span, "`~const` on trait without Effects assoc");
|
||||
|
|
|
@ -360,33 +360,10 @@ pub(super) fn explicit_item_bounds_with_filter(
|
|||
None => {}
|
||||
}
|
||||
|
||||
if tcx.is_effects_desugared_assoc_ty(def_id.to_def_id()) {
|
||||
let mut predicates = Vec::new();
|
||||
|
||||
let parent = tcx.local_parent(def_id);
|
||||
|
||||
let preds = tcx.explicit_predicates_of(parent);
|
||||
|
||||
if let ty::AssocItemContainer::TraitContainer = tcx.associated_item(def_id).container {
|
||||
// for traits, emit `type Effects: TyCompat<<(T1::Effects, ..) as Min>::Output>`
|
||||
let tup = Ty::new(tcx, ty::Tuple(preds.effects_min_tys));
|
||||
// FIXME(effects) span
|
||||
let span = tcx.def_span(def_id);
|
||||
let assoc = tcx.require_lang_item(hir::LangItem::EffectsIntersectionOutput, Some(span));
|
||||
let proj = Ty::new_projection(tcx, assoc, [tup]);
|
||||
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));
|
||||
}
|
||||
return ty::EarlyBinder::bind(tcx.arena.alloc_from_iter(predicates));
|
||||
}
|
||||
|
||||
let bounds = match tcx.hir_node_by_def_id(def_id) {
|
||||
_ if tcx.is_effects_desugared_assoc_ty(def_id.to_def_id()) => {
|
||||
associated_type_bounds(tcx, def_id, &[], tcx.def_span(def_id), filter)
|
||||
}
|
||||
hir::Node::TraitItem(hir::TraitItem {
|
||||
kind: hir::TraitItemKind::Type(bounds, _),
|
||||
span,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue