Skip to content

Commit bcadcd4

Browse files
Make async closures directly lower to ClosureKind::CoroutineClosure
1 parent fe99446 commit bcadcd4

File tree

12 files changed

+93
-88
lines changed

12 files changed

+93
-88
lines changed

compiler/rustc_ast_lowering/messages.ftl

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,6 @@ ast_lowering_never_pattern_with_guard =
117117
a guard on a never pattern will never be run
118118
.suggestion = remove this guard
119119
120-
ast_lowering_not_supported_for_lifetime_binder_async_closure =
121-
`for<...>` binders on `async` closures are not currently supported
122-
123120
ast_lowering_previously_used_here = previously used here
124121
125122
ast_lowering_register1 = register `{$reg1_name}`

compiler/rustc_ast_lowering/src/errors.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -326,13 +326,6 @@ pub struct MisplacedRelaxTraitBound {
326326
pub span: Span,
327327
}
328328

329-
#[derive(Diagnostic, Clone, Copy)]
330-
#[diag(ast_lowering_not_supported_for_lifetime_binder_async_closure)]
331-
pub struct NotSupportedForLifetimeBinderAsyncClosure {
332-
#[primary_span]
333-
pub span: Span,
334-
}
335-
336329
#[derive(Diagnostic)]
337330
#[diag(ast_lowering_match_arm_with_no_body)]
338331
pub struct MatchArmWithNoBody {

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ use super::errors::{
22
AsyncCoroutinesNotSupported, AwaitOnlyInAsyncFnAndBlocks, BaseExpressionDoubleDot,
33
ClosureCannotBeStatic, CoroutineTooManyParameters,
44
FunctionalRecordUpdateDestructuringAssignment, InclusiveRangeWithNoEnd, MatchArmWithNoBody,
5-
NeverPatternWithBody, NeverPatternWithGuard, NotSupportedForLifetimeBinderAsyncClosure,
6-
UnderscoreExprLhsAssign,
5+
NeverPatternWithBody, NeverPatternWithGuard, UnderscoreExprLhsAssign,
76
};
87
use super::ResolverAstLoweringExt;
98
use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs};
@@ -1027,30 +1026,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
10271026
fn_decl_span: Span,
10281027
fn_arg_span: Span,
10291028
) -> hir::ExprKind<'hir> {
1030-
if let &ClosureBinder::For { span, .. } = binder {
1031-
self.dcx().emit_err(NotSupportedForLifetimeBinderAsyncClosure { span });
1032-
}
1033-
10341029
let (binder_clause, generic_params) = self.lower_closure_binder(binder);
10351030

10361031
let body = self.with_new_scopes(fn_decl_span, |this| {
1032+
let inner_decl =
1033+
FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) };
1034+
10371035
// Transform `async |x: u8| -> X { ... }` into
10381036
// `|x: u8| || -> X { ... }`.
10391037
let body_id = this.lower_body(|this| {
1040-
let async_ret_ty = if let FnRetTy::Ty(ty) = &decl.output {
1041-
let itctx = ImplTraitContext::Disallowed(ImplTraitPosition::AsyncBlock);
1042-
Some(hir::FnRetTy::Return(this.lower_ty(ty, &itctx)))
1043-
} else {
1044-
None
1045-
};
1046-
10471038
let (parameters, expr) = this.lower_coroutine_body_with_moved_arguments(
1048-
decl,
1039+
&inner_decl,
10491040
|this| this.with_new_scopes(fn_decl_span, |this| this.lower_expr_mut(body)),
10501041
body.span,
10511042
coroutine_kind,
10521043
hir::CoroutineSource::Closure,
1053-
async_ret_ty,
10541044
);
10551045

10561046
let hir_id = this.lower_node_id(coroutine_kind.closure_id());
@@ -1061,15 +1051,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
10611051
body_id
10621052
});
10631053

1064-
let outer_decl =
1065-
FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) };
1066-
10671054
let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params);
10681055
// We need to lower the declaration outside the new scope, because we
10691056
// have to conserve the state of being inside a loop condition for the
10701057
// closure argument types.
10711058
let fn_decl =
1072-
self.lower_fn_decl(&outer_decl, closure_id, fn_decl_span, FnDeclKind::Closure, None);
1059+
self.lower_fn_decl(&decl, closure_id, fn_decl_span, FnDeclKind::Closure, None);
10731060

10741061
let c = self.arena.alloc(hir::Closure {
10751062
def_id: self.local_def_id(closure_id),
@@ -1080,7 +1067,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10801067
body,
10811068
fn_decl_span: self.lower_span(fn_decl_span),
10821069
fn_arg_span: Some(self.lower_span(fn_arg_span)),
1083-
kind: hir::ClosureKind::Closure,
1070+
kind: hir::ClosureKind::CoroutineClosure(hir::CoroutineDesugaring::Async),
10841071
constness: hir::Constness::NotConst,
10851072
});
10861073
hir::ExprKind::Closure(c)

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,7 +1089,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
10891089
body.span,
10901090
coroutine_kind,
10911091
hir::CoroutineSource::Fn,
1092-
None,
10931092
);
10941093

10951094
// FIXME(async_fn_track_caller): Can this be moved above?
@@ -1111,7 +1110,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
11111110
body_span: Span,
11121111
coroutine_kind: CoroutineKind,
11131112
coroutine_source: hir::CoroutineSource,
1114-
return_type_hint: Option<hir::FnRetTy<'hir>>,
11151113
) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>) {
11161114
let mut parameters: Vec<hir::Param<'_>> = Vec::new();
11171115
let mut statements: Vec<hir::Stmt<'_>> = Vec::new();
@@ -1287,7 +1285,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
12871285
// all async closures would default to `FnOnce` as their calling mode.
12881286
CaptureBy::Ref,
12891287
closure_id,
1290-
return_type_hint,
1288+
None,
12911289
body_span,
12921290
desugaring_kind,
12931291
coroutine_source,

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#![allow(internal_features)]
3434
#![feature(rustdoc_internals)]
3535
#![doc(rust_logo)]
36+
#![feature(assert_matches)]
3637
#![feature(box_patterns)]
3738
#![feature(let_chains)]
3839
#![deny(rustc::untranslatable_diagnostic)]
@@ -296,7 +297,6 @@ enum ImplTraitPosition {
296297
Path,
297298
Variable,
298299
Trait,
299-
AsyncBlock,
300300
Bound,
301301
Generic,
302302
ExternFnParam,
@@ -323,7 +323,6 @@ impl std::fmt::Display for ImplTraitPosition {
323323
ImplTraitPosition::Path => "paths",
324324
ImplTraitPosition::Variable => "the type of variable bindings",
325325
ImplTraitPosition::Trait => "traits",
326-
ImplTraitPosition::AsyncBlock => "async blocks",
327326
ImplTraitPosition::Bound => "bounds",
328327
ImplTraitPosition::Generic => "generics",
329328
ImplTraitPosition::ExternFnParam => "`extern fn` parameters",

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
856856
use crate::session_diagnostics::CaptureVarCause::*;
857857
match kind {
858858
hir::ClosureKind::Coroutine(_) => MoveUseInCoroutine { var_span },
859-
hir::ClosureKind::Closure => MoveUseInClosure { var_span },
859+
hir::ClosureKind::Closure | hir::ClosureKind::CoroutineClosure(_) => {
860+
MoveUseInClosure { var_span }
861+
}
860862
}
861863
});
862864

@@ -903,7 +905,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
903905
hir::ClosureKind::Coroutine(_) => {
904906
BorrowUsePlaceCoroutine { place: desc_place, var_span, is_single_var: true }
905907
}
906-
hir::ClosureKind::Closure => {
908+
hir::ClosureKind::Closure | hir::ClosureKind::CoroutineClosure(_) => {
907909
BorrowUsePlaceClosure { place: desc_place, var_span, is_single_var: true }
908910
}
909911
}
@@ -1054,7 +1056,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
10541056
var_span,
10551057
is_single_var: true,
10561058
},
1057-
hir::ClosureKind::Closure => BorrowUsePlaceClosure {
1059+
hir::ClosureKind::Closure
1060+
| hir::ClosureKind::CoroutineClosure(_) => BorrowUsePlaceClosure {
10581061
place: desc_place,
10591062
var_span,
10601063
is_single_var: true,
@@ -1138,7 +1141,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
11381141
var_span,
11391142
is_single_var: false,
11401143
},
1141-
hir::ClosureKind::Closure => {
1144+
hir::ClosureKind::Closure | hir::ClosureKind::CoroutineClosure(_) => {
11421145
BorrowUsePlaceClosure { place: desc_place, var_span, is_single_var: false }
11431146
}
11441147
}
@@ -1156,7 +1159,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
11561159
hir::ClosureKind::Coroutine(_) => {
11571160
FirstBorrowUsePlaceCoroutine { place: borrow_place_desc, var_span }
11581161
}
1159-
hir::ClosureKind::Closure => {
1162+
hir::ClosureKind::Closure | hir::ClosureKind::CoroutineClosure(_) => {
11601163
FirstBorrowUsePlaceClosure { place: borrow_place_desc, var_span }
11611164
}
11621165
}
@@ -1173,7 +1176,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
11731176
hir::ClosureKind::Coroutine(_) => {
11741177
SecondBorrowUsePlaceCoroutine { place: desc_place, var_span }
11751178
}
1176-
hir::ClosureKind::Closure => {
1179+
hir::ClosureKind::Closure | hir::ClosureKind::CoroutineClosure(_) => {
11771180
SecondBorrowUsePlaceClosure { place: desc_place, var_span }
11781181
}
11791182
}
@@ -2940,7 +2943,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
29402943
use crate::session_diagnostics::CaptureVarCause::*;
29412944
match kind {
29422945
hir::ClosureKind::Coroutine(_) => BorrowUseInCoroutine { var_span },
2943-
hir::ClosureKind::Closure => BorrowUseInClosure { var_span },
2946+
hir::ClosureKind::Closure | hir::ClosureKind::CoroutineClosure(_) => {
2947+
BorrowUseInClosure { var_span }
2948+
}
29442949
}
29452950
});
29462951

@@ -2956,7 +2961,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
29562961
use crate::session_diagnostics::CaptureVarCause::*;
29572962
match kind {
29582963
hir::ClosureKind::Coroutine(_) => BorrowUseInCoroutine { var_span },
2959-
hir::ClosureKind::Closure => BorrowUseInClosure { var_span },
2964+
hir::ClosureKind::Closure | hir::ClosureKind::CoroutineClosure(_) => {
2965+
BorrowUseInClosure { var_span }
2966+
}
29602967
}
29612968
});
29622969

compiler/rustc_borrowck/src/diagnostics/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ impl UseSpans<'_> {
614614
PartialAssignment => AssignPartInCoroutine { path_span },
615615
});
616616
}
617-
hir::ClosureKind::Closure => {
617+
hir::ClosureKind::Closure | hir::ClosureKind::CoroutineClosure(_) => {
618618
err.subdiagnostic(match action {
619619
Borrow => BorrowInClosure { path_span },
620620
MatchOn | Use => UseInClosure { path_span },
@@ -1253,7 +1253,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
12531253
hir::ClosureKind::Coroutine(_) => {
12541254
CaptureVarCause::PartialMoveUseInCoroutine { var_span, is_partial }
12551255
}
1256-
hir::ClosureKind::Closure => {
1256+
hir::ClosureKind::Closure | hir::ClosureKind::CoroutineClosure(_) => {
12571257
CaptureVarCause::PartialMoveUseInClosure { var_span, is_partial }
12581258
}
12591259
})

compiler/rustc_borrowck/src/diagnostics/region_name.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
692692
hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
693693
hir::CoroutineDesugaring::Async,
694694
hir::CoroutineSource::Closure,
695-
)) => " of async closure",
695+
))
696+
| hir::ClosureKind::CoroutineClosure(hir::CoroutineDesugaring::Async) => {
697+
" of async closure"
698+
}
696699

697700
hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
698701
hir::CoroutineDesugaring::Async,
@@ -719,7 +722,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
719722
hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
720723
hir::CoroutineDesugaring::Gen,
721724
hir::CoroutineSource::Closure,
722-
)) => " of gen closure",
725+
))
726+
| hir::ClosureKind::CoroutineClosure(hir::CoroutineDesugaring::Gen) => {
727+
" of gen closure"
728+
}
723729

724730
hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
725731
hir::CoroutineDesugaring::Gen,
@@ -743,7 +749,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
743749
hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
744750
hir::CoroutineDesugaring::AsyncGen,
745751
hir::CoroutineSource::Closure,
746-
)) => " of async gen closure",
752+
))
753+
| hir::ClosureKind::CoroutineClosure(hir::CoroutineDesugaring::AsyncGen) => {
754+
" of async gen closure"
755+
}
747756

748757
hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
749758
hir::CoroutineDesugaring::AsyncGen,

compiler/rustc_hir/src/hir.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,11 @@ pub enum ClosureKind {
963963
/// usage (e.g. `let x = || { yield (); }`) or from a desugared expression
964964
/// (e.g. `async` and `gen` blocks).
965965
Coroutine(CoroutineKind),
966+
/// This is a coroutine-closure, which is a special sugared closure that
967+
/// returns one of the sugared coroutine (`async`/`gen`/`async gen`). It
968+
/// additionally allows capturing the coroutine's upvars by ref, and therefore
969+
/// needs to be specially treated during analysis and borrowck.
970+
CoroutineClosure(CoroutineDesugaring),
966971
}
967972

968973
/// A block of statements `{ .. }`, which may have a label (in this case the

compiler/rustc_hir_analysis/src/collect/generics_of.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
349349
ClosureKind::Coroutine(_) => {
350350
&["<resume_ty>", "<yield_ty>", "<return_ty>", "<witness>", "<upvars>"][..]
351351
}
352+
ClosureKind::CoroutineClosure(_) => todo!(),
352353
};
353354

354355
params.extend(dummy_args.iter().map(|&arg| ty::GenericParamDef {

compiler/rustc_hir_typeck/src/closure.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
192192
Some(CoroutineTypes { resume_ty, yield_ty }),
193193
)
194194
}
195+
hir::ClosureKind::CoroutineClosure(_) => todo!(),
195196
};
196197

197198
check_fn(
@@ -690,7 +691,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
690691
_,
691692
))
692693
| hir::ClosureKind::Coroutine(hir::CoroutineKind::Coroutine(_))
693-
| hir::ClosureKind::Closure => astconv.ty_infer(None, decl.output.span()),
694+
| hir::ClosureKind::Closure
695+
| hir::ClosureKind::CoroutineClosure(_) => {
696+
astconv.ty_infer(None, decl.output.span())
697+
}
694698
},
695699
};
696700

0 commit comments

Comments
 (0)