Fix early lints inside an async desugaring

Fixes #81531

When we buffer an early lint for a macro invocation,
we need to determine which NodeId to take the lint level from.
Currently, we use the `NodeId` of the closest def parent. However, if
the macro invocation is inside the desugared closure from an `async fn`
or async closure, that `NodeId` does not actually exist in the AST.

This commit explicitly calls `check_lint` for the `NodeId`s of closures
desugared from async expressions, ensuring that we do not miss any
buffered lints.
This commit is contained in:
Aaron Hill 2021-01-29 19:03:20 -05:00
parent b81f5811f9
commit a74b2fb946
No known key found for this signature in database
GPG Key ID: B4087E510E98B164
3 changed files with 25 additions and 3 deletions

View File

@ -143,6 +143,14 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
run_early_pass!(self, check_fn, fk, span, id);
self.check_id(id);
ast_visit::walk_fn(self, fk, span);
// 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 ast::Async::Yes { closure_id, .. } = sig.header.asyncness {
self.check_id(closure_id);
}
}
run_early_pass!(self, check_fn_post, fk, span, id);
}
@ -208,6 +216,14 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
fn visit_expr_post(&mut self, e: &'a ast::Expr) {
run_early_pass!(self, check_expr_post, e);
// Explicitly check for lints associated with 'closure_id', since
// it does not have a corresponding AST node
if let ast::ExprKind::Closure(_, asyncness, ..) = e.kind {
if let ast::Async::Yes { closure_id, .. } = asyncness {
self.check_id(closure_id);
}
}
}
fn visit_generic_arg(&mut self, arg: &'a ast::GenericArg) {

View File

@ -1,4 +1,5 @@
// check-pass
// edition:2018
#![warn(semicolon_in_expressions_from_macros)]
#[allow(dead_code)]
@ -11,6 +12,11 @@ macro_rules! foo {
}
}
#[allow(semicolon_in_expressions_from_macros)]
async fn bar() {
foo!(first);
}
fn main() {
// This `allow` doesn't work
#[allow(semicolon_in_expressions_from_macros)]

View File

@ -1,5 +1,5 @@
warning: trailing semicolon in macro used in expression position
--> $DIR/semicolon-in-expressions-from-macros.rs:7:13
--> $DIR/semicolon-in-expressions-from-macros.rs:8:13
|
LL | true;
| ^
@ -8,7 +8,7 @@ LL | foo!(first)
| ----------- in this macro invocation
|
note: the lint level is defined here
--> $DIR/semicolon-in-expressions-from-macros.rs:2:9
--> $DIR/semicolon-in-expressions-from-macros.rs:3:9
|
LL | #![warn(semicolon_in_expressions_from_macros)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -17,7 +17,7 @@ LL | #![warn(semicolon_in_expressions_from_macros)]
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
warning: trailing semicolon in macro used in expression position
--> $DIR/semicolon-in-expressions-from-macros.rs:7:13
--> $DIR/semicolon-in-expressions-from-macros.rs:8:13
|
LL | true;
| ^