Skip to content

Commit 44911b7

Browse files
Make some matches exhaustive to avoid bugs, fix tools
1 parent a208bae commit 44911b7

File tree

8 files changed

+72
-46
lines changed

8 files changed

+72
-46
lines changed

compiler/rustc_ast_lowering/src/item.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10351035
let (Some(coroutine_kind), Some(body)) = (coroutine_kind, body) else {
10361036
return self.lower_fn_body_block(span, decl, body);
10371037
};
1038+
// FIXME(gen_blocks): Introduce `closure_id` method and remove ALL destructuring.
10381039
let (CoroutineKind::Async { closure_id, .. }
10391040
| CoroutineKind::Gen { closure_id, .. }
10401041
| CoroutineKind::AsyncGen { closure_id, .. }) = coroutine_kind;

compiler/rustc_ast_passes/src/ast_validation.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -1271,14 +1271,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
12711271
// Functions cannot both be `const async` or `const gen`
12721272
if let Some(&FnHeader {
12731273
constness: Const::Yes(cspan),
1274-
coroutine_kind:
1275-
Some(
1276-
CoroutineKind::Async { span: aspan, .. }
1277-
| CoroutineKind::Gen { span: aspan, .. },
1278-
),
1274+
coroutine_kind: Some(coro_kind),
12791275
..
12801276
}) = fk.header()
12811277
{
1278+
let aspan = match coro_kind {
1279+
CoroutineKind::Async { span: aspan, .. }
1280+
| CoroutineKind::Gen { span: aspan, .. }
1281+
| CoroutineKind::AsyncGen { span: aspan, .. } => aspan,
1282+
};
12821283
// FIXME(gen_blocks): Report a different error for `const gen`
12831284
self.err_handler().emit_err(errors::ConstAndAsync {
12841285
spans: vec![cspan, aspan],

compiler/rustc_builtin_macros/src/test.rs

+24-6
Original file line numberDiff line numberDiff line change
@@ -541,12 +541,30 @@ fn check_test_signature(
541541
return Err(sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "unsafe" }));
542542
}
543543

544-
if let Some(ast::CoroutineKind::Async { span, .. }) = f.sig.header.coroutine_kind {
545-
return Err(sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "async" }));
546-
}
547-
548-
if let Some(ast::CoroutineKind::Gen { span, .. }) = f.sig.header.coroutine_kind {
549-
return Err(sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "gen" }));
544+
if let Some(coro_kind) = f.sig.header.coroutine_kind {
545+
match coro_kind {
546+
ast::CoroutineKind::Async { span, .. } => {
547+
return Err(sd.emit_err(errors::TestBadFn {
548+
span: i.span,
549+
cause: span,
550+
kind: "async",
551+
}));
552+
}
553+
ast::CoroutineKind::Gen { span, .. } => {
554+
return Err(sd.emit_err(errors::TestBadFn {
555+
span: i.span,
556+
cause: span,
557+
kind: "gen",
558+
}));
559+
}
560+
ast::CoroutineKind::AsyncGen { span, .. } => {
561+
return Err(sd.emit_err(errors::TestBadFn {
562+
span: i.span,
563+
cause: span,
564+
kind: "async gen",
565+
}));
566+
}
567+
}
550568
}
551569

552570
// If the termination trait is active, the compiler will check that the output

compiler/rustc_lint/src/early.rs

+11-12
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,10 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
162162
// Explicitly check for lints associated with 'closure_id', since
163163
// it does not have a corresponding AST node
164164
if let ast_visit::FnKind::Fn(_, _, sig, _, _, _) = fk {
165-
if let Some(
166-
ast::CoroutineKind::Async { closure_id, .. }
167-
| ast::CoroutineKind::Gen { closure_id, .. },
168-
) = sig.header.coroutine_kind
169-
{
165+
if let Some(coro_kind) = sig.header.coroutine_kind {
166+
let (ast::CoroutineKind::Async { closure_id, .. }
167+
| ast::CoroutineKind::Gen { closure_id, .. }
168+
| ast::CoroutineKind::AsyncGen { closure_id, .. }) = coro_kind;
170169
self.check_id(closure_id);
171170
}
172171
}
@@ -227,13 +226,13 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
227226
// it does not have a corresponding AST node
228227
match e.kind {
229228
ast::ExprKind::Closure(box ast::Closure {
230-
coroutine_kind:
231-
Some(
232-
ast::CoroutineKind::Async { closure_id, .. }
233-
| ast::CoroutineKind::Gen { closure_id, .. },
234-
),
235-
..
236-
}) => self.check_id(closure_id),
229+
coroutine_kind: Some(coro_kind), ..
230+
}) => {
231+
let (ast::CoroutineKind::Async { closure_id, .. }
232+
| ast::CoroutineKind::Gen { closure_id, .. }
233+
| ast::CoroutineKind::AsyncGen { closure_id, .. }) = coro_kind;
234+
self.check_id(closure_id);
235+
}
237236
_ => {}
238237
}
239238
lint_callback!(self, check_expr_post, e);

compiler/rustc_resolve/src/def_collector.rs

+26-22
Original file line numberDiff line numberDiff line change
@@ -156,29 +156,33 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
156156

157157
fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) {
158158
if let FnKind::Fn(_, _, sig, _, generics, body) = fn_kind {
159-
if let Some(
160-
CoroutineKind::Async { closure_id, .. } | CoroutineKind::Gen { closure_id, .. },
161-
) = sig.header.coroutine_kind
162-
{
163-
self.visit_generics(generics);
164-
165-
// For async functions, we need to create their inner defs inside of a
166-
// closure to match their desugared representation. Besides that,
167-
// we must mirror everything that `visit::walk_fn` below does.
168-
self.visit_fn_header(&sig.header);
169-
for param in &sig.decl.inputs {
170-
self.visit_param(param);
171-
}
172-
self.visit_fn_ret_ty(&sig.decl.output);
173-
// If this async fn has no body (i.e. it's an async fn signature in a trait)
174-
// then the closure_def will never be used, and we should avoid generating a
175-
// def-id for it.
176-
if let Some(body) = body {
177-
let closure_def =
178-
self.create_def(closure_id, kw::Empty, DefKind::Closure, span);
179-
self.with_parent(closure_def, |this| this.visit_block(body));
159+
match sig.header.coroutine_kind {
160+
Some(
161+
CoroutineKind::Async { closure_id, .. }
162+
| CoroutineKind::Gen { closure_id, .. }
163+
| CoroutineKind::AsyncGen { closure_id, .. },
164+
) => {
165+
self.visit_generics(generics);
166+
167+
// For async functions, we need to create their inner defs inside of a
168+
// closure to match their desugared representation. Besides that,
169+
// we must mirror everything that `visit::walk_fn` below does.
170+
self.visit_fn_header(&sig.header);
171+
for param in &sig.decl.inputs {
172+
self.visit_param(param);
173+
}
174+
self.visit_fn_ret_ty(&sig.decl.output);
175+
// If this async fn has no body (i.e. it's an async fn signature in a trait)
176+
// then the closure_def will never be used, and we should avoid generating a
177+
// def-id for it.
178+
if let Some(body) = body {
179+
let closure_def =
180+
self.create_def(closure_id, kw::Empty, DefKind::Closure, span);
181+
self.with_parent(closure_def, |this| this.visit_block(body));
182+
}
183+
return;
180184
}
181-
return;
185+
None => {}
182186
}
183187
}
184188

src/tools/clippy/clippy_utils/src/ast_utils.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,8 @@ pub fn eq_fn_sig(l: &FnSig, r: &FnSig) -> bool {
566566
fn eq_opt_coroutine_kind(l: Option<CoroutineKind>, r: Option<CoroutineKind>) -> bool {
567567
match (l, r) {
568568
(Some(CoroutineKind::Async { .. }), Some(CoroutineKind::Async { .. }))
569-
| (Some(CoroutineKind::Gen { .. }), Some(CoroutineKind::Gen { .. })) => true,
569+
| (Some(CoroutineKind::Gen { .. }), Some(CoroutineKind::Gen { .. }))
570+
| (Some(CoroutineKind::AsyncGen { .. }), Some(CoroutineKind::AsyncGen { .. })) => true,
570571
(None, None) => true,
571572
_ => false,
572573
}

src/tools/rustfmt/src/closures.rs

+1
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ fn rewrite_closure_fn_decl(
275275
let coro = match coroutine_kind {
276276
Some(ast::CoroutineKind::Async { .. }) => "async ",
277277
Some(ast::CoroutineKind::Gen { .. }) => "gen ",
278+
Some(ast::CoroutineKind::AsyncGen { .. }) => "async gen ",
278279
None => "",
279280
};
280281
let mover = if matches!(capture, ast::CaptureBy::Value { .. }) {

src/tools/rustfmt/src/utils.rs

+1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ pub(crate) fn format_coro(coroutine_kind: &ast::CoroutineKind) -> &'static str {
7979
match coroutine_kind {
8080
ast::CoroutineKind::Async { .. } => "async ",
8181
ast::CoroutineKind::Gen { .. } => "gen ",
82+
ast::CoroutineKind::AsyncGen { .. } => "async gen ",
8283
}
8384
}
8485

0 commit comments

Comments
 (0)