Function rustc_trait_selection::traits::specialize::translate_substs
source · pub fn translate_substs<'tcx>(
infcx: &InferCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
source_impl: DefId,
source_substs: SubstsRef<'tcx>,
target_node: Node
) -> SubstsRef<'tcx>
Expand description
Given a subst for the requested impl, translate it to a subst appropriate for the actual item definition (whether it be in that impl, a parent impl, or the trait).
When we have selected one impl, but are actually using item definitions from
a parent impl providing a default, we need a way to translate between the
type parameters of the two impls. Here the source_impl
is the one we’ve
selected, and source_substs
is a substitution of its generics.
And target_node
is the impl/trait we’re actually going to get the
definition from. The resulting substitution will map from target_node
’s
generics to source_impl
’s generics as instantiated by source_subst
.
For example, consider the following scenario:
trait Foo { ... }
impl<T, U> Foo for (T, U) { ... } // target impl
impl<V> Foo for (V, V) { ... } // source impl
Suppose we have selected “source impl” with V
instantiated with u32
.
This function will produce a substitution with T
and U
both mapping to u32
.
where-clauses add some trickiness here, because they can be used to “define” an argument indirectly:
impl<'a, I, T: 'a> Iterator for Cloned<I>
where I: Iterator<Item = &'a T>, T: Clone
In a case like this, the substitution for T
is determined indirectly,
through associated type projection. We deal with such cases by using
fulfillment to relate the two impls, requiring that all projections are
resolved.