Actually use the inferred `ClosureKind` from signature inference in coroutine-cl...
source link: https://github.com/rust-lang/rust/pull/123350
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Conversation
Member
A follow-up to #123349, which fixes another subtle bug: We were not taking into account the async closure kind we infer during closure signature inference.
When I pass a closure directly to an arg like fn(x: impl async FnOnce())
, that should have the side-effect of artificially restricting the kind of the async closure to ClosureKind::FnOnce
. We weren't doing this -- that's a quick fix; however, it uncovers a second, more subtle bug with the way that move
, async closures, and FnOnce
interact.
Specifically, when we have an async closure like:
let x = Struct;
let c = infer_as_fnonce(async move || {
println!("{x:?}");
}
The outer closure captures x
by move, but the inner coroutine still immutably borrows x
from the outer closure. Since we've forced the closure to by async FnOnce()
, we can't actually do a self borrow, since the signature of AsyncFnOnce::call_once
doesn't have a borrowed lifetime. This means that all async move
closures that are constrained to FnOnce
will fail borrowck.
We can fix that by detecting this case specifically, and making the inner async closure move
as well. This is always beneficial to closure analysis, since if we have an async FnOnce()
that's move
, there's no reason to ever borrow anything, so move
isn't artificially restrictive.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK