Compute a better lint_node_id during expansion

When we need to emit a lint at a macro invocation, we currently use the
`NodeId` of its parent definition (e.g. the enclosing function). This
means that any `#[allow]` / `#[deny]` attributes placed 'closer' to the
macro (e.g. on an enclosing block or statement) will have no effect.

This commit computes a better `lint_node_id` in `InvocationCollector`.
When we visit/flat_map an AST node, we assign it a `NodeId` (earlier
than we normally would), and store than `NodeId` in current
`ExpansionData`. When we collect a macro invocation, the current
`lint_node_id` gets cloned along with our `ExpansionData`, allowing it
to be used if we need to emit a lint later on.

This improves the handling of `#[allow]` / `#[deny]` for
`SEMICOLON_IN_EXPRESSIONS_FROM_MACROS` and some `asm!`-related lints.
The 'legacy derive helpers' lint retains its current behavior
(I've inlined the now-removed `lint_node_id` function), since
there isn't an `ExpansionData` readily available.
This commit is contained in:
Aaron Hill 2021-07-14 18:24:12 -05:00
parent eb0b95b55a
commit ddd544856e
No known key found for this signature in database
GPG key ID: B4087E510E98B164
10 changed files with 139 additions and 65 deletions

View file

@ -1,16 +1,10 @@
warning: avoid using `.intel_syntax`, Intel syntax is the default
--> $DIR/inline-syntax.rs:57:14
|
LL | global_asm!(".intel_syntax noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(bad_asm_style)]` on by default
warning: avoid using `.intel_syntax`, Intel syntax is the default
--> $DIR/inline-syntax.rs:31:15
|
LL | asm!(".intel_syntax noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(bad_asm_style)]` on by default
warning: avoid using `.intel_syntax`, Intel syntax is the default
--> $DIR/inline-syntax.rs:34:15
@ -42,5 +36,11 @@ warning: avoid using `.intel_syntax`, Intel syntax is the default
LL | .intel_syntax noprefix
| ^^^^^^^^^^^^^^^^^^^^^^
warning: avoid using `.intel_syntax`, Intel syntax is the default
--> $DIR/inline-syntax.rs:57:14
|
LL | global_asm!(".intel_syntax noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^^^
warning: 7 warnings emitted

View file

@ -1,14 +1,17 @@
// check-pass
// edition:2018
#![feature(stmt_expr_attributes)]
#![warn(semicolon_in_expressions_from_macros)]
#[allow(dead_code)]
macro_rules! foo {
($val:ident) => {
true; //~ WARN trailing
//~| WARN this was previously
//~| WARN trailing
//~| WARN this was previously
true; //~ WARN trailing semicolon in macro
//~| WARN this was previously accepted
//~| WARN trailing semicolon in macro
//~| WARN this was previously accepted
//~| WARN trailing semicolon in macro
//~| WARN this was previously accepted
}
}
@ -18,17 +21,14 @@ async fn bar() {
}
fn main() {
// This `allow` doesn't work
#[allow(semicolon_in_expressions_from_macros)]
let _ = {
foo!(first)
};
// This 'allow' doesn't work either
#[allow(semicolon_in_expressions_from_macros)]
let _ = foo!(second);
// But this 'allow' does
#[allow(semicolon_in_expressions_from_macros)]
fn inner() {
let _ = foo!(third);
@ -38,4 +38,14 @@ fn main() {
async {
let _ = foo!(fourth);
};
let _ = {
foo!(warn_in_block)
};
let _ = foo!(warn_in_expr);
// This `#[allow]` does not work, since the attribute gets dropped
// when we expand the macro
let _ = #[allow(semicolon_in_expressions_from_macros)] foo!(allow_does_not_work);
}

View file

@ -1,14 +1,14 @@
warning: trailing semicolon in macro used in expression position
--> $DIR/semicolon-in-expressions-from-macros.rs:8:13
--> $DIR/semicolon-in-expressions-from-macros.rs:9:13
|
LL | true;
| ^
...
LL | foo!(first)
| ----------- in this macro invocation
LL | foo!(warn_in_block)
| ------------------- in this macro invocation
|
note: the lint level is defined here
--> $DIR/semicolon-in-expressions-from-macros.rs:3:9
--> $DIR/semicolon-in-expressions-from-macros.rs:4:9
|
LL | #![warn(semicolon_in_expressions_from_macros)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -17,17 +17,30 @@ LL | #![warn(semicolon_in_expressions_from_macros)]
= note: this warning originates in the macro `foo` (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:8:13
--> $DIR/semicolon-in-expressions-from-macros.rs:9:13
|
LL | true;
| ^
...
LL | let _ = foo!(second);
| ------------ in this macro invocation
LL | let _ = foo!(warn_in_expr);
| ------------------ in this macro invocation
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
= note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
warning: 2 warnings emitted
warning: trailing semicolon in macro used in expression position
--> $DIR/semicolon-in-expressions-from-macros.rs:9:13
|
LL | true;
| ^
...
LL | let _ = #[allow(semicolon_in_expressions_from_macros)] foo!(allow_does_not_work);
| ------------------------- in this macro invocation
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
= note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
warning: 3 warnings emitted