fn find_and_apply_rpit_args<'tcx>(
    tcx: TyCtxt<'tcx>,
    hidden_ty: Ty<'tcx>,
    function: DefId,
    opaque: DefId
) -> Result<Ty<'tcx>, ErrorGuaranteed>
Expand description

In case it is in a nested opaque type, find that opaque type’s usage in the function signature and use the generic arguments from the usage site. We need to do because RPITs ignore the lifetimes of the function, as they have their own copies of all the lifetimes they capture. So the only way to get the lifetimes represented in terms of the function, is to look how they are used in the function signature (or do some other fancy recording of this mapping at ast -> hir lowering time).

As an example:

trait Id {
    type Assoc;
}
impl<'a> Id for &'a () {
    type Assoc = &'a ();
}
fn func<'a>(x: &'a ()) -> impl Id<Assoc = impl Sized + 'a> { x }
// desugared to
fn func<'a>(x: &'a () -> Outer<'a> where <Outer<'a> as Id>::Assoc = Inner<'a> {
    // Note that in contrast to other nested items, RPIT type aliases can
    // access their parents' generics.

    // hidden type is `&'aDupOuter ()`
    // During wfcheck the hidden type of `Inner<'aDupOuter>` is `&'a ()`, but
    // `typeof(Inner<'aDupOuter>) = &'aDupOuter ()`.
    // So we walk the signature of `func` to find the use of `Inner<'a>`
    // and then use that to replace the lifetimes in the hidden type, obtaining
    // `&'a ()`.
    type Outer<'aDupOuter> = impl Id<Assoc = Inner<'aDupOuter>>;

    // hidden type is `&'aDupInner ()`
    type Inner<'aDupInner> = impl Sized + 'aDupInner;

    x
}