Skip to content

Commit 48074ae

Browse files
committed
Auto merge of #120361 - compiler-errors:async-closures, r=oli-obk
Rework support for async closures; allow them to return futures that borrow from the closure's captures 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](https://hackmd.io/`@compiler-errors/S1HvqQxca)` 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 the `Fn`-family of traits -- if you need `Fn` 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 use `AsyncFn()` traits directly, which necessitates adding the `async_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.
2 parents ce6533a + f244ae0 commit 48074ae

File tree

3 files changed

+6
-2
lines changed

3 files changed

+6
-2
lines changed

clippy_lints/src/dereference.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,7 @@ impl TyCoercionStability {
881881
| ty::Coroutine(..)
882882
| ty::CoroutineWitness(..)
883883
| ty::Closure(..)
884+
| ty::CoroutineClosure(..)
884885
| ty::Never
885886
| ty::Tuple(_)
886887
| ty::Alias(ty::Projection, _) => Self::Deref,

clippy_lints/src/utils/author.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,9 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
490490
format!("ClosureKind::Coroutine(CoroutineKind::Coroutine(Movability::{movability:?})")
491491
},
492492
},
493+
ClosureKind::CoroutineClosure(desugaring) => format!(
494+
"ClosureKind::CoroutineClosure(CoroutineDesugaring::{desugaring:?})"
495+
),
493496
};
494497

495498
let ret_ty = match fn_decl.output {

tests/ui/author/blocks.stdout

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ if let ExprKind::Block(block, None) = expr.kind
4040
{
4141
// report your lint here
4242
}
43-
if let ExprKind::Closure { capture_clause: CaptureBy::Value { .. }, fn_decl: fn_decl, body: body_id, closure_kind: ClosureKind::Closure, .. } = expr.kind
43+
if let ExprKind::Closure { capture_clause: CaptureBy::Value { .. }, fn_decl: fn_decl, body: body_id, closure_kind: ClosureKind::CoroutineClosure(CoroutineDesugaring::Async), .. } = expr.kind
4444
&& let FnRetTy::DefaultReturn(_) = fn_decl.output
4545
&& expr1 = &cx.tcx.hir().body(body_id).value
46-
&& let ExprKind::Closure { capture_clause: CaptureBy::Value { .. }, fn_decl: fn_decl1, body: body_id1, closure_kind: ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Closure)), .. } = expr1.kind
46+
&& let ExprKind::Closure { capture_clause: CaptureBy::Ref, fn_decl: fn_decl1, body: body_id1, closure_kind: ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Closure)), .. } = expr1.kind
4747
&& let FnRetTy::DefaultReturn(_) = fn_decl1.output
4848
&& expr2 = &cx.tcx.hir().body(body_id1).value
4949
&& let ExprKind::Block(block, None) = expr2.kind

0 commit comments

Comments
 (0)