2

Actually use the inferred `ClosureKind` from signature inference in coroutine-cl...

 3 weeks ago
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.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK