diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index b97593b92b355..9aee86c9e57dd 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -45,6 +45,8 @@ crate struct ParserAnyMacro<'a> { lint_node_id: NodeId, is_trailing_mac: bool, arm_span: Span, + /// Whether or not this macro is defined in the current crate + is_local: bool, } crate fn annotate_err_with_kind( @@ -124,6 +126,7 @@ impl<'a> ParserAnyMacro<'a> { lint_node_id, arm_span, is_trailing_mac, + is_local, } = *self; let snapshot = &mut parser.clone(); let fragment = match parse_ast_fragment(parser, kind) { @@ -138,13 +141,15 @@ impl<'a> ParserAnyMacro<'a> { // `macro_rules! m { () => { panic!(); } }` isn't parsed by `.parse_expr()`, // but `m!()` is allowed in expression positions (cf. issue #34706). if kind == AstFragmentKind::Expr && parser.token == token::Semi { - parser.sess.buffer_lint_with_diagnostic( - SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, - parser.token.span, - lint_node_id, - "trailing semicolon in macro used in expression position", - BuiltinLintDiagnostics::TrailingMacro(is_trailing_mac, macro_ident), - ); + if is_local { + parser.sess.buffer_lint_with_diagnostic( + SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, + parser.token.span, + lint_node_id, + "trailing semicolon in macro used in expression position", + BuiltinLintDiagnostics::TrailingMacro(is_trailing_mac, macro_ident), + ); + } parser.bump(); } @@ -162,6 +167,7 @@ struct MacroRulesMacroExpander { lhses: Vec, rhses: Vec, valid: bool, + is_local: bool, } impl TTMacroExpander for MacroRulesMacroExpander { @@ -183,6 +189,7 @@ impl TTMacroExpander for MacroRulesMacroExpander { input, &self.lhses, &self.rhses, + self.is_local, ) } } @@ -210,6 +217,7 @@ fn generic_extension<'cx>( arg: TokenStream, lhses: &[mbe::TokenTree], rhses: &[mbe::TokenTree], + is_local: bool, ) -> Box { let sess = &cx.sess.parse_sess; @@ -311,6 +319,7 @@ fn generic_extension<'cx>( lint_node_id: cx.current_expansion.lint_node_id, is_trailing_mac: cx.current_expansion.is_trailing_mac, arm_span, + is_local, }); } Failure(token, msg) => match best_failure { @@ -544,6 +553,9 @@ pub fn compile_declarative_macro( lhses, rhses, valid, + // Macros defined in the current crate have a real node id, + // whereas macros from an external crate have a dummy id. + is_local: def.id != DUMMY_NODE_ID, })) } diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 5b1cd0bcb3ffe..7195c41eae92e 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -2799,7 +2799,7 @@ declare_lint! { /// [issue #79813]: https://github.com/rust-lang/rust/issues/79813 /// [future-incompatible]: ../index.md#future-incompatible-lints pub SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, - Allow, + Warn, "trailing semicolon in macro body used as expression", @future_incompatible = FutureIncompatibleInfo { reference: "issue #79813 ", diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs index 7afe52a3fd693..676695795badc 100644 --- a/library/std/src/macros.rs +++ b/library/std/src/macros.rs @@ -290,7 +290,7 @@ macro_rules! dbg { // `$val` expression could be a block (`{ .. }`), in which case the `eprintln!` // will be malformed. () => { - $crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!()); + $crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!()) }; ($val:expr $(,)?) => { // Use of `match` here is intentional because it affects the lifetimes diff --git a/src/test/ui/hygiene/auxiliary/intercrate.rs b/src/test/ui/hygiene/auxiliary/intercrate.rs index 10d399ba54e71..0685358851edd 100644 --- a/src/test/ui/hygiene/auxiliary/intercrate.rs +++ b/src/test/ui/hygiene/auxiliary/intercrate.rs @@ -5,7 +5,7 @@ pub mod foo { mod bar { fn f() -> u32 { 1 } pub macro m() { - f(); + f() } } } diff --git a/src/test/ui/hygiene/hygienic-label-1.rs b/src/test/ui/hygiene/hygienic-label-1.rs index 66361eec21a52..a06d9255ab5b0 100644 --- a/src/test/ui/hygiene/hygienic-label-1.rs +++ b/src/test/ui/hygiene/hygienic-label-1.rs @@ -3,5 +3,5 @@ macro_rules! foo { } pub fn main() { - 'x: loop { foo!() } + 'x: loop { foo!(); } } diff --git a/src/test/ui/hygiene/hygienic-label-1.stderr b/src/test/ui/hygiene/hygienic-label-1.stderr index 97a7240b9069b..c1ed861836c1c 100644 --- a/src/test/ui/hygiene/hygienic-label-1.stderr +++ b/src/test/ui/hygiene/hygienic-label-1.stderr @@ -4,8 +4,8 @@ error[E0426]: use of undeclared label `'x` LL | () => { break 'x; } | ^^ undeclared label `'x` ... -LL | 'x: loop { foo!() } - | ------ in this macro invocation +LL | 'x: loop { foo!(); } + | ------- in this macro invocation | = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/hygiene/hygienic-label-3.rs b/src/test/ui/hygiene/hygienic-label-3.rs index a81eb84225970..ab0559e1b6a83 100644 --- a/src/test/ui/hygiene/hygienic-label-3.rs +++ b/src/test/ui/hygiene/hygienic-label-3.rs @@ -4,6 +4,6 @@ macro_rules! foo { pub fn main() { 'x: for _ in 0..1 { - foo!() + foo!(); }; } diff --git a/src/test/ui/hygiene/hygienic-label-3.stderr b/src/test/ui/hygiene/hygienic-label-3.stderr index 52840049f825a..29d1b67e09f9b 100644 --- a/src/test/ui/hygiene/hygienic-label-3.stderr +++ b/src/test/ui/hygiene/hygienic-label-3.stderr @@ -4,8 +4,8 @@ error[E0426]: use of undeclared label `'x` LL | () => { break 'x; } | ^^ undeclared label `'x` ... -LL | foo!() - | ------ in this macro invocation +LL | foo!(); + | ------- in this macro invocation | = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/allow-semicolon-in-expressions-from-macros.rs b/src/test/ui/lint/semicolon-in-expressions-from-macros/allow-semicolon-in-expressions-from-macros.rs deleted file mode 100644 index 6f9e6ec0a57ff..0000000000000 --- a/src/test/ui/lint/semicolon-in-expressions-from-macros/allow-semicolon-in-expressions-from-macros.rs +++ /dev/null @@ -1,15 +0,0 @@ -// check-pass -// Ensure that trailing semicolons are allowed by default - -macro_rules! foo { - () => { - true; - } -} - -fn main() { - let val = match true { - true => false, - _ => foo!() - }; -} diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/auxiliary/foreign-crate.rs b/src/test/ui/lint/semicolon-in-expressions-from-macros/auxiliary/foreign-crate.rs new file mode 100644 index 0000000000000..781391cc574a9 --- /dev/null +++ b/src/test/ui/lint/semicolon-in-expressions-from-macros/auxiliary/foreign-crate.rs @@ -0,0 +1,4 @@ +#[macro_export] +macro_rules! my_macro { + () => { true; } +} diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/foreign-crate.rs b/src/test/ui/lint/semicolon-in-expressions-from-macros/foreign-crate.rs new file mode 100644 index 0000000000000..374506366f802 --- /dev/null +++ b/src/test/ui/lint/semicolon-in-expressions-from-macros/foreign-crate.rs @@ -0,0 +1,9 @@ +// aux-build:foreign-crate.rs +// check-pass + +extern crate foreign_crate; + +// Test that we do not lint for a macro in a foreign crate +fn main() { + let _ = foreign_crate::my_macro!(); +} diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.rs b/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.rs new file mode 100644 index 0000000000000..2c63311e65978 --- /dev/null +++ b/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.rs @@ -0,0 +1,16 @@ +// check-pass +// Ensure that trailing semicolons cause warnings by default + +macro_rules! foo { + () => { + true; //~ WARN trailing semicolon in macro + //~| WARN this was previously + } +} + +fn main() { + let _val = match true { + true => false, + _ => foo!() + }; +} diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr b/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr new file mode 100644 index 0000000000000..d770a8c8f36e6 --- /dev/null +++ b/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr @@ -0,0 +1,16 @@ +warning: trailing semicolon in macro used in expression position + --> $DIR/warn-semicolon-in-expressions-from-macros.rs:6:13 + | +LL | true; + | ^ +... +LL | _ => foo!() + | ------ in this macro invocation + | + = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default + = 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 + = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: 1 warning emitted + diff --git a/src/test/ui/macros/macro-context.rs b/src/test/ui/macros/macro-context.rs index 13e179578ad01..d09fdf118e6f4 100644 --- a/src/test/ui/macros/macro-context.rs +++ b/src/test/ui/macros/macro-context.rs @@ -6,6 +6,8 @@ macro_rules! m { //~| ERROR macro expansion ignores token `;` //~| ERROR cannot find type `i` in this scope //~| ERROR cannot find value `i` in this scope + //~| WARN trailing semicolon in macro + //~| WARN this was previously } fn main() { diff --git a/src/test/ui/macros/macro-context.stderr b/src/test/ui/macros/macro-context.stderr index 5ed73b7fb93a3..3b8a6f1749158 100644 --- a/src/test/ui/macros/macro-context.stderr +++ b/src/test/ui/macros/macro-context.stderr @@ -64,7 +64,21 @@ LL | let i = m!(); | = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 6 previous errors +warning: trailing semicolon in macro used in expression position + --> $DIR/macro-context.rs:3:15 + | +LL | () => ( i ; typeof ); + | ^ +... +LL | let i = m!(); + | ---- in this macro invocation + | + = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default + = 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 + = note: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 6 previous errors; 1 warning emitted Some errors have detailed explanations: E0412, E0425. For more information about an error, try `rustc --explain E0412`. diff --git a/src/test/ui/macros/macro-in-expression-context.fixed b/src/test/ui/macros/macro-in-expression-context.fixed index df36db0f49e72..f22caf2793fd5 100644 --- a/src/test/ui/macros/macro-in-expression-context.fixed +++ b/src/test/ui/macros/macro-in-expression-context.fixed @@ -3,6 +3,12 @@ macro_rules! foo { () => { assert_eq!("A", "A"); + //~^ WARN trailing semicolon in macro + //~| WARN this was previously + //~| NOTE macro invocations at the end of a block + //~| NOTE to ignore the value produced by the macro + //~| NOTE for more information + //~| NOTE `#[warn(semicolon_in_expressions_from_macros)]` on by default assert_eq!("B", "B"); } //~^^ ERROR macro expansion ignores token `assert_eq` and any following @@ -12,4 +18,10 @@ macro_rules! foo { fn main() { foo!(); //~^ NOTE caused by the macro expansion here + //~| NOTE in this expansion + //~| NOTE in this expansion + //~| NOTE in this expansion + //~| NOTE in this expansion + //~| NOTE in this expansion + //~| NOTE in this expansion } diff --git a/src/test/ui/macros/macro-in-expression-context.rs b/src/test/ui/macros/macro-in-expression-context.rs index b3f5e568967e8..1a056e582ff47 100644 --- a/src/test/ui/macros/macro-in-expression-context.rs +++ b/src/test/ui/macros/macro-in-expression-context.rs @@ -3,6 +3,12 @@ macro_rules! foo { () => { assert_eq!("A", "A"); + //~^ WARN trailing semicolon in macro + //~| WARN this was previously + //~| NOTE macro invocations at the end of a block + //~| NOTE to ignore the value produced by the macro + //~| NOTE for more information + //~| NOTE `#[warn(semicolon_in_expressions_from_macros)]` on by default assert_eq!("B", "B"); } //~^^ ERROR macro expansion ignores token `assert_eq` and any following @@ -12,4 +18,10 @@ macro_rules! foo { fn main() { foo!() //~^ NOTE caused by the macro expansion here + //~| NOTE in this expansion + //~| NOTE in this expansion + //~| NOTE in this expansion + //~| NOTE in this expansion + //~| NOTE in this expansion + //~| NOTE in this expansion } diff --git a/src/test/ui/macros/macro-in-expression-context.stderr b/src/test/ui/macros/macro-in-expression-context.stderr index d27d6fbaef7a6..1840babd61dc2 100644 --- a/src/test/ui/macros/macro-in-expression-context.stderr +++ b/src/test/ui/macros/macro-in-expression-context.stderr @@ -1,5 +1,5 @@ error: macro expansion ignores token `assert_eq` and any following - --> $DIR/macro-in-expression-context.rs:6:9 + --> $DIR/macro-in-expression-context.rs:12:9 | LL | assert_eq!("B", "B"); | ^^^^^^^^^ @@ -11,5 +11,21 @@ LL | foo!() | = note: the usage of `foo!` is likely invalid in expression context -error: aborting due to previous error +warning: trailing semicolon in macro used in expression position + --> $DIR/macro-in-expression-context.rs:5:29 + | +LL | assert_eq!("A", "A"); + | ^ +... +LL | foo!() + | ------ in this macro invocation + | + = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default + = 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 + = note: macro invocations at the end of a block are treated as expressions + = note: to ignore the value produced by the macro, add a semicolon after the invocation of `foo` + = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/proc-macro/nested-nonterminal-tokens.rs b/src/test/ui/proc-macro/nested-nonterminal-tokens.rs index 2f5af10a40ac2..04d34e21cdc74 100644 --- a/src/test/ui/proc-macro/nested-nonterminal-tokens.rs +++ b/src/test/ui/proc-macro/nested-nonterminal-tokens.rs @@ -17,7 +17,7 @@ macro_rules! wrap { (first, $e:expr) => { wrap!(second, $e + 1) }; (second, $e:expr) => { wrap!(third, $e + 2) }; (third, $e:expr) => { - print_bang!($e + 3); + print_bang!($e + 3) }; } diff --git a/src/tools/clippy/tests/ui/needless_borrow_pat.rs b/src/tools/clippy/tests/ui/needless_borrow_pat.rs index f0926220755a2..7a8137778b446 100644 --- a/src/tools/clippy/tests/ui/needless_borrow_pat.rs +++ b/src/tools/clippy/tests/ui/needless_borrow_pat.rs @@ -7,7 +7,7 @@ fn f1(_: &str) {} macro_rules! m1 { ($e:expr) => { - f1($e); + f1($e) }; } macro_rules! m3 { diff --git a/src/tools/clippy/tests/ui/ref_binding_to_reference.rs b/src/tools/clippy/tests/ui/ref_binding_to_reference.rs index c7235e1c22105..cd6db8ddc8864 100644 --- a/src/tools/clippy/tests/ui/ref_binding_to_reference.rs +++ b/src/tools/clippy/tests/ui/ref_binding_to_reference.rs @@ -7,7 +7,7 @@ fn f1(_: &str) {} macro_rules! m2 { ($e:expr) => { - f1(*$e); + f1(*$e) }; } macro_rules! m3 {