Change:
let lifetime_params: Vec<(Span, ParamName)> = this.in_scope_lifetimes .iter().cloned() <del> .map(|ident| (ident.span, ParamName::Plain(ident))) </del> <ins> .map(|name| (name.ident().span, name)) </ins> .chain(this.lifetimes_to_define.iter().cloned()) .collect(); <ins> debug!("lower_async_fn_ret_ty: in_scope_lifetimes={:#?}", this.in_scope_lifetimes); debug!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", this.lifetimes_to_define); debug!("lower_async_fn_ret_ty: lifetime_params={:#?}", lifetime_params); </ins> let generic_params = lifetime_params .iter().cloned()

Discussion:
The following breaks on nightly (see ) With: CC: dtolnay/async-trait
Reduced:
Forgot to mention in case this helps, giving the inner fn a matching lifetime avoids this issue for some reason:
The reason this is happening is that the desugared version of applies all in-scope lifetimes to the returned existential type, which in this case is creating , which is invalid. I'm not sure exactly what the best fix is for this, though, since elided lifetimes in the impl signature are intentionally unnameable. The closest idea I have would be to create some special new lifetime that is but can refer to lifetimes originating from the impl header. cc who may have opinions.
Hmm wouldn't you expect the nested to not inherit anything from its enclosing scopes? Seems like a bug to me that it does? Am I confused about something?
The function in the middle is actually a bit of a source of confusion here, although it does indicate that there's a second bug since we shouldn't be inheriting generics since the nested isn't part of the . The bug I was focusing on is better illustrated by this example: which produces this error: This is because the code is transformed into and in that case does not refer back to the usage from the header.
I see. Indeed, I would expect that, internally, we'd have some way to refer back to the from the impl header. I believe this should be possible, no? In particular, the in impls expands (internally) to for some integer N, which I believe is basically treated like any other named lifetime.
Yep, I would've expected so as well-- I'm not sure why that isn't working, I'd have to take a look.
I was looking and I think the bug lies here: Probably needs to be a instead, or we need to use something else for this purpose.
A closer reading suggests I was mistaken. The lifetimes from the impl should show up in -- includes only the explicitly declared lifetimes written by the user on the impl. I'm not quite sure what the problem is yet.
OK, no, I was correct. When processing impl items, we convert the lifetimes into entries. EDIT: Er, I'm still not entirely sure. Reading more. =)
OK, I have a fix for the method issue, but not the nested async fn item issue.

I forked off for the method issue
I didn't prep a fix for this one yet. It seems obvious that some internal state is not being reset when we enter a new item.
but if you have a chance to investigate, would be appreciated
Presumably the problem is that doesn't "reset" the vector -- it only seems to extend it...
Indeed, in-band lifetimes are broken in the same way. This fails to compile ():
Working on a possible fix
Yep, have a fix.
Inband lifetimes looks similar to fwiw
thanks