Skip to content

Commit 1ab7831

Browse files
committedDec 26, 2023
Auto merge of #119258 - compiler-errors:closure-kind, r=eholk
Make closures carry their own ClosureKind Right now, we use the "`movability`" field of `hir::Closure` to distinguish a closure and a coroutine. This is paired together with the `CoroutineKind`, which is located not in the `hir::Closure`, but the `hir::Body`. This is strange and redundant. This PR introduces `ClosureKind` with two variants -- `Closure` and `Coroutine`, which is put into `hir::Closure`. The `CoroutineKind` is thus removed from `hir::Body`, and `Option<Movability>` no longer needs to be a stand-in for "is this a closure or a coroutine". r? eholk
2 parents 2271c26 + ba91285 commit 1ab7831

File tree

47 files changed

+570
-488
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+570
-488
lines changed
 

Diff for: ‎compiler/rustc_ast_lowering/src/expr.rs

+38-27
Original file line numberDiff line numberDiff line change
@@ -668,11 +668,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
668668
};
669669
let params = arena_vec![self; param];
670670

671+
let coroutine_kind =
672+
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, async_coroutine_source);
671673
let body = self.lower_body(move |this| {
672-
this.coroutine_kind = Some(hir::CoroutineKind::Desugared(
673-
hir::CoroutineDesugaring::Async,
674-
async_coroutine_source,
675-
));
674+
this.coroutine_kind = Some(coroutine_kind);
676675

677676
let old_ctx = this.task_context;
678677
this.task_context = Some(task_context_hid);
@@ -691,7 +690,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
691690
body,
692691
fn_decl_span: self.lower_span(span),
693692
fn_arg_span: None,
694-
movability: Some(hir::Movability::Static),
693+
kind: hir::ClosureKind::Coroutine(coroutine_kind),
695694
constness: hir::Constness::NotConst,
696695
}))
697696
}
@@ -725,11 +724,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
725724
lifetime_elision_allowed: false,
726725
});
727726

727+
let coroutine_kind =
728+
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, coroutine_source);
728729
let body = self.lower_body(move |this| {
729-
this.coroutine_kind = Some(hir::CoroutineKind::Desugared(
730-
hir::CoroutineDesugaring::Gen,
731-
coroutine_source,
732-
));
730+
this.coroutine_kind = Some(coroutine_kind);
733731

734732
let res = body(this);
735733
(&[], res)
@@ -745,7 +743,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
745743
body,
746744
fn_decl_span: self.lower_span(span),
747745
fn_arg_span: None,
748-
movability: Some(Movability::Movable),
746+
kind: hir::ClosureKind::Coroutine(coroutine_kind),
749747
constness: hir::Constness::NotConst,
750748
}))
751749
}
@@ -806,11 +804,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
806804
};
807805
let params = arena_vec![self; param];
808806

807+
let coroutine_kind = hir::CoroutineKind::Desugared(
808+
hir::CoroutineDesugaring::AsyncGen,
809+
async_coroutine_source,
810+
);
809811
let body = self.lower_body(move |this| {
810-
this.coroutine_kind = Some(hir::CoroutineKind::Desugared(
811-
hir::CoroutineDesugaring::AsyncGen,
812-
async_coroutine_source,
813-
));
812+
this.coroutine_kind = Some(coroutine_kind);
814813

815814
let old_ctx = this.task_context;
816815
this.task_context = Some(task_context_hid);
@@ -829,7 +828,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
829828
body,
830829
fn_decl_span: self.lower_span(span),
831830
fn_arg_span: None,
832-
movability: Some(hir::Movability::Static),
831+
kind: hir::ClosureKind::Coroutine(coroutine_kind),
833832
constness: hir::Constness::NotConst,
834833
}))
835834
}
@@ -898,7 +897,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
898897
let is_async_gen = match self.coroutine_kind {
899898
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) => false,
900899
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _)) => true,
901-
Some(hir::CoroutineKind::Coroutine)
900+
Some(hir::CoroutineKind::Coroutine(_))
902901
| Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
903902
| None => {
904903
return hir::ExprKind::Err(self.dcx().emit_err(AwaitOnlyInAsyncFnAndBlocks {
@@ -1086,15 +1085,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
10861085
) -> hir::ExprKind<'hir> {
10871086
let (binder_clause, generic_params) = self.lower_closure_binder(binder);
10881087

1089-
let (body_id, coroutine_option) = self.with_new_scopes(fn_decl_span, move |this| {
1088+
let (body_id, closure_kind) = self.with_new_scopes(fn_decl_span, move |this| {
10901089
let mut coroutine_kind = None;
10911090
let body_id = this.lower_fn_body(decl, |this| {
10921091
let e = this.lower_expr_mut(body);
10931092
coroutine_kind = this.coroutine_kind;
10941093
e
10951094
});
10961095
let coroutine_option =
1097-
this.coroutine_movability_for_fn(decl, fn_decl_span, coroutine_kind, movability);
1096+
this.closure_movability_for_fn(decl, fn_decl_span, coroutine_kind, movability);
10981097
(body_id, coroutine_option)
10991098
});
11001099

@@ -1111,26 +1110,26 @@ impl<'hir> LoweringContext<'_, 'hir> {
11111110
body: body_id,
11121111
fn_decl_span: self.lower_span(fn_decl_span),
11131112
fn_arg_span: Some(self.lower_span(fn_arg_span)),
1114-
movability: coroutine_option,
1113+
kind: closure_kind,
11151114
constness: self.lower_constness(constness),
11161115
});
11171116

11181117
hir::ExprKind::Closure(c)
11191118
}
11201119

1121-
fn coroutine_movability_for_fn(
1120+
fn closure_movability_for_fn(
11221121
&mut self,
11231122
decl: &FnDecl,
11241123
fn_decl_span: Span,
11251124
coroutine_kind: Option<hir::CoroutineKind>,
11261125
movability: Movability,
1127-
) -> Option<hir::Movability> {
1126+
) -> hir::ClosureKind {
11281127
match coroutine_kind {
1129-
Some(hir::CoroutineKind::Coroutine) => {
1128+
Some(hir::CoroutineKind::Coroutine(_)) => {
11301129
if decl.inputs.len() > 1 {
11311130
self.dcx().emit_err(CoroutineTooManyParameters { fn_decl_span });
11321131
}
1133-
Some(movability)
1132+
hir::ClosureKind::Coroutine(hir::CoroutineKind::Coroutine(movability))
11341133
}
11351134
Some(
11361135
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)
@@ -1143,7 +1142,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
11431142
if movability == Movability::Static {
11441143
self.dcx().emit_err(ClosureCannotBeStatic { fn_decl_span });
11451144
}
1146-
None
1145+
hir::ClosureKind::Closure
11471146
}
11481147
}
11491148
}
@@ -1235,7 +1234,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
12351234
body,
12361235
fn_decl_span: self.lower_span(fn_decl_span),
12371236
fn_arg_span: Some(self.lower_span(fn_arg_span)),
1238-
movability: None,
1237+
kind: hir::ClosureKind::Closure,
12391238
constness: hir::Constness::NotConst,
12401239
});
12411240
hir::ExprKind::Closure(c)
@@ -1655,7 +1654,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
16551654
self.dcx().emit_err(AsyncCoroutinesNotSupported { span }),
16561655
);
16571656
}
1658-
Some(hir::CoroutineKind::Coroutine) | None => {
1657+
Some(hir::CoroutineKind::Coroutine(_)) => {
1658+
if !self.tcx.features().coroutines {
1659+
rustc_session::parse::feature_err(
1660+
&self.tcx.sess.parse_sess,
1661+
sym::coroutines,
1662+
span,
1663+
"yield syntax is experimental",
1664+
)
1665+
.emit();
1666+
}
1667+
false
1668+
}
1669+
None => {
16591670
if !self.tcx.features().coroutines {
16601671
rustc_session::parse::feature_err(
16611672
&self.tcx.sess.parse_sess,
@@ -1665,7 +1676,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
16651676
)
16661677
.emit();
16671678
}
1668-
self.coroutine_kind = Some(hir::CoroutineKind::Coroutine);
1679+
self.coroutine_kind = Some(hir::CoroutineKind::Coroutine(Movability::Movable));
16691680
false
16701681
}
16711682
};

Diff for: ‎compiler/rustc_ast_lowering/src/item.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -952,11 +952,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
952952
params: &'hir [hir::Param<'hir>],
953953
value: hir::Expr<'hir>,
954954
) -> hir::BodyId {
955-
let body = hir::Body {
956-
coroutine_kind: self.coroutine_kind,
957-
params,
958-
value: self.arena.alloc(value),
959-
};
955+
let body = hir::Body { params, value: self.arena.alloc(value) };
960956
let id = body.id();
961957
debug_assert_eq!(id.hir_id.owner, self.current_hir_id_owner);
962958
self.bodies.push((id.hir_id.local_id, self.arena.alloc(body)));

0 commit comments

Comments
 (0)
Please sign in to comment.