-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rework support for async closures; allow them to return futures that borrow from the closure's captures #120361
Conversation
This comment has been minimized.
This comment has been minimized.
6a12c64
to
6b33ee2
Compare
This comment has been minimized.
This comment has been minimized.
6b33ee2
to
a7e6d88
Compare
This comment has been minimized.
This comment has been minimized.
a7e6d88
to
5b3b359
Compare
This comment has been minimized.
This comment has been minimized.
5b3b359
to
7737047
Compare
Type relation code was changed Some changes occurred in need_type_info.rs cc @lcnr Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt Some changes might have occurred in exhaustiveness checking cc @Nadrieril This PR changes MIR cc @oli-obk, @RalfJung, @JakobDegen, @davidtwco, @celinval, @vakaras Some changes occurred in src/tools/clippy cc @rust-lang/clippy Some changes occurred in compiler/rustc_codegen_gcc Some changes occurred to the CTFE / Miri engine cc @rust-lang/miri Some changes occurred to the core trait solver cc @rust-lang/initiative-trait-system-refactor |
☔ The latest upstream changes (presumably #119968) made this pull request unmergeable. Please resolve the merge conflicts. |
Is there an issue tracking "closures should be able to return a value borrowed from their captures"? |
7737047
to
31c1675
Compare
This comment has been minimized.
This comment has been minimized.
31c1675
to
a9de24c
Compare
There was discussion $somewhere recently that the I see #119305 discusses this to some extent. I just wonder if we should track somewhere the idea of having LendingFn* eventually (or whether it is even possible to make the existing traits lending). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did a commit-by-commit review, I'll do another review of the entire diff in one go, too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add a mir-opt test showing this shim's MIR
a9de24c
to
4dc5109
Compare
@bors try |
This comment was marked as off-topic.
This comment was marked as off-topic.
☀️ Test successful - checks-actions |
Finished benchmarking commit (4a2fe44): comparison URL. Overall result: ❌ regressions - ACTION NEEDEDNext Steps: If you can justify the regressions found in this perf run, please indicate this with @rustbot label: +perf-regression Instruction countThis is a highly reliable metric that was used to determine the overall result at the top of this comment.
Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 661.097s -> 662.774s (0.25%) |
… r=oli-obk Print kind of coroutine closure Make sure that we print "async closure" when we have an async closure, rather than calling it generically a ["coroutine-closure"](rust-lang#120361). Fixes rust-lang#120886 r? oli-obk
Rollup merge of rust-lang#120896 - compiler-errors:coro-closure-kind, r=oli-obk Print kind of coroutine closure Make sure that we print "async closure" when we have an async closure, rather than calling it generically a ["coroutine-closure"](rust-lang#120361). Fixes rust-lang#120886 r? oli-obk
Print kind of coroutine closure Make sure that we print "async closure" when we have an async closure, rather than calling it generically a ["coroutine-closure"](rust-lang/rust#120361). Fixes #120886 r? oli-obk
Probably just codegen noise, the changes were reverted in followup commits. @rustbot label: +perf-regression-triaged |
… r=oli-obk An async closure may implement `FnMut`/`Fn` if it has no self-borrows There's no reason that async closures may not implement `FnMut` or `Fn` if they don't actually borrow anything with the closure's env lifetime. Specifically, rust-lang#123660 made it so that we don't always need to borrow captures from the closure's env. See the doc comment on `should_reborrow_from_env_of_parent_coroutine_closure`: https://github.com/rust-lang/rust/blob/c00957a3e269219413041a4e3565f33b1f9d0779/compiler/rustc_hir_typeck/src/upvar.rs#L1777-L1823 If there are no such borrows, then we are free to implement `FnMut` and `Fn` as permitted by our closure's inferred `ClosureKind`. As far as I can tell, this change makes `async || {}` work in precisely the set of places they used to work before rust-lang#120361. Fixes rust-lang#125247. r? oli-obk
… r=oli-obk An async closure may implement `FnMut`/`Fn` if it has no self-borrows There's no reason that async closures may not implement `FnMut` or `Fn` if they don't actually borrow anything with the closure's env lifetime. Specifically, rust-lang#123660 made it so that we don't always need to borrow captures from the closure's env. See the doc comment on `should_reborrow_from_env_of_parent_coroutine_closure`: https://github.com/rust-lang/rust/blob/c00957a3e269219413041a4e3565f33b1f9d0779/compiler/rustc_hir_typeck/src/upvar.rs#L1777-L1823 If there are no such borrows, then we are free to implement `FnMut` and `Fn` as permitted by our closure's inferred `ClosureKind`. As far as I can tell, this change makes `async || {}` work in precisely the set of places they used to work before rust-lang#120361. Fixes rust-lang#125247. r? oli-obk
Rollup merge of rust-lang#125259 - compiler-errors:fn-mut-as-a-treat, r=oli-obk An async closure may implement `FnMut`/`Fn` if it has no self-borrows There's no reason that async closures may not implement `FnMut` or `Fn` if they don't actually borrow anything with the closure's env lifetime. Specifically, rust-lang#123660 made it so that we don't always need to borrow captures from the closure's env. See the doc comment on `should_reborrow_from_env_of_parent_coroutine_closure`: https://github.com/rust-lang/rust/blob/c00957a3e269219413041a4e3565f33b1f9d0779/compiler/rustc_hir_typeck/src/upvar.rs#L1777-L1823 If there are no such borrows, then we are free to implement `FnMut` and `Fn` as permitted by our closure's inferred `ClosureKind`. As far as I can tell, this change makes `async || {}` work in precisely the set of places they used to work before rust-lang#120361. Fixes rust-lang#125247. r? oli-obk
This PR implements a new lowering for async closures via
TyKind::CoroutineClosure
which handles the curious relationship between the closure and the coroutine that it returns.I wrote up a bunch in this hackmd which will be copied to the dev guide after this PR lands, and hopefully left sufficient comments in the source code explaining why this change is as large as it is.
This also necessitates that they begin implementing the
AsyncFn
-family of traits, rather than theFn
-family of traits -- if you needFn
implementations, you should probably use the non-sugar|| async {}
syntax instead.Notably this PR does not yet implement
async Fn()
syntax sugar for bounds, but I expect to add those soon (edit: #120392). For now, users must useAsyncFn()
traits directly, which necessitates adding theasync_fn_traits
feature gate as well. I will add this as a follow-up very soon.r? oli-obk
This is based on top of #120322, but that PR is minimal.