Skip to content

Commit

Permalink
Make some matches exhaustive to avoid bugs, fix tools
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Dec 5, 2023
1 parent 7cc2ec8 commit b45e065
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 46 deletions.
11 changes: 6 additions & 5 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1271,14 +1271,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
// Functions cannot both be `const async` or `const gen`
if let Some(&FnHeader {
constness: Const::Yes(cspan),
coroutine_kind:
Some(
CoroutineKind::Async { span: aspan, .. }
| CoroutineKind::Gen { span: aspan, .. },
),
coroutine_kind: Some(coro_kind),
..
}) = fk.header()
{
let aspan = match coro_kind {
CoroutineKind::Async { span: aspan, .. }
| CoroutineKind::Gen { span: aspan, .. }
| CoroutineKind::AsyncGen { span: aspan, .. } => aspan,
};
// FIXME(gen_blocks): Report a different error for `const gen`
self.err_handler().emit_err(errors::ConstAndAsync {
spans: vec![cspan, aspan],
Expand Down
30 changes: 24 additions & 6 deletions compiler/rustc_builtin_macros/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -541,12 +541,30 @@ fn check_test_signature(
return Err(sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "unsafe" }));
}

if let Some(ast::CoroutineKind::Async { span, .. }) = f.sig.header.coroutine_kind {
return Err(sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "async" }));
}

if let Some(ast::CoroutineKind::Gen { span, .. }) = f.sig.header.coroutine_kind {
return Err(sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "gen" }));
if let Some(coro_kind) = f.sig.header.coroutine_kind {
match coro_kind {
ast::CoroutineKind::Async { span, .. } => {
return Err(sd.emit_err(errors::TestBadFn {
span: i.span,
cause: span,
kind: "async",
}));
}
ast::CoroutineKind::Gen { span, .. } => {
return Err(sd.emit_err(errors::TestBadFn {
span: i.span,
cause: span,
kind: "gen",
}));
}
ast::CoroutineKind::AsyncGen { span, .. } => {
return Err(sd.emit_err(errors::TestBadFn {
span: i.span,
cause: span,
kind: "async gen",
}));
}
}
}

// If the termination trait is active, the compiler will check that the output
Expand Down
23 changes: 11 additions & 12 deletions compiler/rustc_lint/src/early.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,10 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
// Explicitly check for lints associated with 'closure_id', since
// it does not have a corresponding AST node
if let ast_visit::FnKind::Fn(_, _, sig, _, _, _) = fk {
if let Some(
ast::CoroutineKind::Async { closure_id, .. }
| ast::CoroutineKind::Gen { closure_id, .. },
) = sig.header.coroutine_kind
{
if let Some(coro_kind) = sig.header.coroutine_kind {
let (ast::CoroutineKind::Async { closure_id, .. }
| ast::CoroutineKind::Gen { closure_id, .. }
| ast::CoroutineKind::AsyncGen { closure_id, .. }) = coro_kind;
self.check_id(closure_id);
}
}
Expand Down Expand Up @@ -227,13 +226,13 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
// it does not have a corresponding AST node
match e.kind {
ast::ExprKind::Closure(box ast::Closure {
coroutine_kind:
Some(
ast::CoroutineKind::Async { closure_id, .. }
| ast::CoroutineKind::Gen { closure_id, .. },
),
..
}) => self.check_id(closure_id),
coroutine_kind: Some(coro_kind), ..
}) => {
let (ast::CoroutineKind::Async { closure_id, .. }
| ast::CoroutineKind::Gen { closure_id, .. }
| ast::CoroutineKind::AsyncGen { closure_id, .. }) = coro_kind;
self.check_id(closure_id);
}
_ => {}
}
lint_callback!(self, check_expr_post, e);
Expand Down
48 changes: 26 additions & 22 deletions compiler/rustc_resolve/src/def_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,29 +156,33 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {

fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) {
if let FnKind::Fn(_, _, sig, _, generics, body) = fn_kind {
if let Some(
CoroutineKind::Async { closure_id, .. } | CoroutineKind::Gen { closure_id, .. },
) = sig.header.coroutine_kind
{
self.visit_generics(generics);

// For async functions, we need to create their inner defs inside of a
// closure to match their desugared representation. Besides that,
// we must mirror everything that `visit::walk_fn` below does.
self.visit_fn_header(&sig.header);
for param in &sig.decl.inputs {
self.visit_param(param);
}
self.visit_fn_ret_ty(&sig.decl.output);
// If this async fn has no body (i.e. it's an async fn signature in a trait)
// then the closure_def will never be used, and we should avoid generating a
// def-id for it.
if let Some(body) = body {
let closure_def =
self.create_def(closure_id, kw::Empty, DefKind::Closure, span);
self.with_parent(closure_def, |this| this.visit_block(body));
match sig.header.coroutine_kind {
Some(
CoroutineKind::Async { closure_id, .. }
| CoroutineKind::Gen { closure_id, .. }
| CoroutineKind::AsyncGen { closure_id, .. },
) => {
self.visit_generics(generics);

// For async functions, we need to create their inner defs inside of a
// closure to match their desugared representation. Besides that,
// we must mirror everything that `visit::walk_fn` below does.
self.visit_fn_header(&sig.header);
for param in &sig.decl.inputs {
self.visit_param(param);
}
self.visit_fn_ret_ty(&sig.decl.output);
// If this async fn has no body (i.e. it's an async fn signature in a trait)
// then the closure_def will never be used, and we should avoid generating a
// def-id for it.
if let Some(body) = body {
let closure_def =
self.create_def(closure_id, kw::Empty, DefKind::Closure, span);
self.with_parent(closure_def, |this| this.visit_block(body));
}
return;
}
return;
None => {}
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/tools/clippy/clippy_utils/src/ast_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,8 @@ pub fn eq_fn_sig(l: &FnSig, r: &FnSig) -> bool {
fn eq_opt_coroutine_kind(l: Option<CoroutineKind>, r: Option<CoroutineKind>) -> bool {
match (l, r) {
(Some(CoroutineKind::Async { .. }), Some(CoroutineKind::Async { .. }))
| (Some(CoroutineKind::Gen { .. }), Some(CoroutineKind::Gen { .. })) => true,
| (Some(CoroutineKind::Gen { .. }), Some(CoroutineKind::Gen { .. }))
| (Some(CoroutineKind::AsyncGen { .. }), Some(CoroutineKind::AsyncGen { .. })) => true,
(None, None) => true,
_ => false,
}
Expand Down
1 change: 1 addition & 0 deletions src/tools/rustfmt/src/closures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ fn rewrite_closure_fn_decl(
let coro = match coroutine_kind {
Some(ast::CoroutineKind::Async { .. }) => "async ",
Some(ast::CoroutineKind::Gen { .. }) => "gen ",
Some(ast::CoroutineKind::AsyncGen { .. }) => "async gen ",
None => "",
};
let mover = if matches!(capture, ast::CaptureBy::Value { .. }) {
Expand Down
1 change: 1 addition & 0 deletions src/tools/rustfmt/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ pub(crate) fn format_coro(coroutine_kind: &ast::CoroutineKind) -> &'static str {
match coroutine_kind {
ast::CoroutineKind::Async { .. } => "async ",
ast::CoroutineKind::Gen { .. } => "gen ",
ast::CoroutineKind::AsyncGen { .. } => "async gen ",
}
}

Expand Down

0 comments on commit b45e065

Please sign in to comment.