pub fn translate_args<'tcx>(
infcx: &InferCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
source_impl: DefId,
source_args: GenericArgsRef<'tcx>,
target_node: Node,
) -> GenericArgsRef<'tcx>
Expand description
Given the generic parameters for the requested impl, translate it to the generic parameters 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_args
is its generic parameters.
And target_node
is the impl/trait we’re actually going to get the
definition from. The resulting instantiation will map from target_node
’s
generics to source_impl
’s generics as instantiated by source_args
.
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 an instantiation 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 instantiation 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.