fn param_env_with_gat_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
impl_ty: AssocItem,
impl_trait_ref: TraitRef<'tcx>,
) -> ParamEnv<'tcx>
Expand description
Install projection predicates that allow GATs to project to their own definition types. This is not allowed in general in cases of default associated types in trait definitions, or when specialization is involved, but is needed when checking these definition types actually satisfy the trait bounds of the GAT.
ยงHow it works
impl<A, B> Foo<u32> for (A, B) {
type Bar<C> = Wrapper<A, B, C>
}
impl_trait_ref
would be<(A, B) as Foo<u32>>
normalize_impl_ty_args
would be[A, B, ^0.0]
(^0.0
here is the bound var with db 0 and index 0)normalize_impl_ty
would beWrapper<A, B, ^0.0>
rebased_args
would be[(A, B), u32, ^0.0]
, combining the args from the trait with the generic associated type parameters (as bound vars).
A note regarding the use of bound vars here: Imagine as an example
trait Family {
type Member<C: Eq>;
}
impl Family for VecFamily {
type Member<C: Eq> = i32;
}
Here, we would generate
forall<C> { Normalize(<VecFamily as Family>::Member<C> => i32) }
when we really would like to generate
forall<C> { Normalize(<VecFamily as Family>::Member<C> => i32) :- Implemented(C: Eq) }
But, this is probably fine, because although the first clause can be used with types C
that
do not implement Eq
, for it to cause some kind of problem, there would have to be a
VecFamily::Member<X>
for some type X
where !(X: Eq)
, that appears in the value of type
Member<C: Eq> = ....
That type would fail a well-formedness check that we ought to be doing
elsewhere, which would check that any <T as Family>::Member<X>
meets the bounds declared in
the trait (notably, that X: Eq
and T: Family
).