You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Error with nested async fn and anonymous lifetimes #63225
error[E0261]: use of undeclared lifetime name `'_`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0261`.
error: Could not compile `playground`.
To learn more, run the command again with --verbose.
The reason this is happening is that the desugared version of async fn applies all in-scope lifetimes to the returned existential type, which in this case is creating -> Fut<'_>, 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 @nikomatsakis who may have opinions.
Hmm @cramertj wouldn't you expect the nested async fn to not inherit anything from its enclosing scopes? Seems like a bug to me that it does? Am I confused about something?
@nikomatsakis 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 async fn isn't part of the impl.
The bug I was focusing on is better illustrated by this example:
@cramertj 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 LifetimeName::Param(ParamName::Fresh(N)) for some integer N, which I believe is basically treated like any other named lifetime.
Activity
Centril commentedon Aug 2, 2019
Reduced:
udoprog commentedon Aug 2, 2019
Forgot to mention in case this helps, giving the inner fn a matching lifetime avoids this issue for some reason:
cramertj commentedon Aug 6, 2019
The reason this is happening is that the desugared version of
async fnapplies all in-scope lifetimes to the returned existential type, which in this case is creating-> Fut<'_>, 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 @nikomatsakis who may have opinions.nikomatsakis commentedon Aug 7, 2019
Hmm @cramertj wouldn't you expect the nested
async fnto not inherit anything from its enclosing scopes? Seems like a bug to me that it does? Am I confused about something?cramertj commentedon Aug 7, 2019
@nikomatsakis 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
async fnisn't part of theimpl.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 theimplheader.nikomatsakis commentedon Aug 12, 2019
@cramertj 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) toLifetimeName::Param(ParamName::Fresh(N))for some integer N, which I believe is basically treated like any other named lifetime.cramertj commentedon Aug 12, 2019
@nikomatsakis Yep, I would've expected so as well-- I'm not sure why that isn't working, I'd have to take a look.
nikomatsakis commentedon Aug 12, 2019
@cramertj I was looking and I think the bug lies here:
rust/src/librustc/hir/lowering.rs
Lines 2267 to 2272 in c01be67
Probably
in_scope_lifetimesneeds to be aVec<ParamName>instead, or we need to use something else for this purpose.2 remaining items
nikomatsakis commentedon Aug 12, 2019
OK, I have a fix for the
async fnmethod issue, but not the nested async fn item issue.nikomatsakis commentedon Aug 12, 2019
I forked off #63500 for the method issue
nikomatsakis commentedon Aug 12, 2019
@cramertj 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.
nikomatsakis commentedon Aug 12, 2019
but if you have a chance to investigate, would be appreciated
nikomatsakis commentedon Aug 12, 2019
Presumably the problem is that
visit_itemdoesn't "reset" thein_scope_lifetimesvector -- it only seems to extend it...rust/src/librustc/hir/lowering/item.rs
Line 70 in c01be67
nikomatsakis commentedon Aug 12, 2019
Indeed, in-band lifetimes are broken in the same way. This fails to compile (playground):
nikomatsakis commentedon Aug 12, 2019
Working on a possible fix
nikomatsakis commentedon Aug 13, 2019
Yep, have a fix.
Mark-Simulacrum commentedon Aug 13, 2019
Inband lifetimes looks similar to #52532 fwiw
nikomatsakis commentedon Aug 13, 2019
@Mark-Simulacrum thanks
Rollup merge of rust-lang#63501 - nikomatsakis:issue-63500-async-anon…
Rollup merge of rust-lang#63501 - nikomatsakis:issue-63500-async-anon…
Rollup merge of rust-lang#63209 - Centril:stabilize-async-await, r=cr…