Skip to content

Commit

Permalink
Rollup merge of rust-lang#88996 - Aaron1011:trailing-macro-semi, r=pe…
Browse files Browse the repository at this point in the history
…trochenkov

Fix linting when trailing macro expands to a trailing semi

When a macro is used in the trailing expression position of a block
(e.g. `fn foo() { my_macro!() }`), we currently parse it as an
expression, rather than a statement. As a result, we ended up
using the `NodeId` of the containing statement as our `lint_node_id`,
even though we don't normally do this for macro calls.

If such a macro expands to an expression with a `#[cfg]` attribute,
then the trailing statement can get removed entirely. This lead to
an ICE, since we were usng the `NodeId` of the expression to emit
a lint.

Ths commit makes us skip updating `lint_node_id` when handling
a macro in trailing expression position. This will cause us to
lint at the closest parent of the macro call.
  • Loading branch information
JohnTitor authored and ehuss committed Oct 4, 2021
1 parent b893d56 commit c981a57
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 6 deletions.
15 changes: 9 additions & 6 deletions compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1373,14 +1373,17 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
// `SEMICOLON_IN_EXPRESSIONS_FROM_MACROS` lint if needed.
// See #78991 for an investigation of treating macros in this position
// as statements, rather than expressions, during parsing.
if let StmtKind::Expr(expr) = &stmt.kind {
if matches!(**expr, ast::Expr { kind: ast::ExprKind::MacCall(..), .. }) {
let res = match &stmt.kind {
StmtKind::Expr(expr)
if matches!(**expr, ast::Expr { kind: ast::ExprKind::MacCall(..), .. }) =>
{
self.cx.current_expansion.is_trailing_mac = true;
// Don't use `assign_id` for this statement - it may get removed
// entirely due to a `#[cfg]` on the contained expression
noop_flat_map_stmt(stmt, self)
}
}

let res = assign_id!(self, &mut stmt.id, || noop_flat_map_stmt(stmt, self));

_ => assign_id!(self, &mut stmt.id, || noop_flat_map_stmt(stmt, self)),
};
self.cx.current_expansion.is_trailing_mac = false;
res
}
Expand Down
16 changes: 16 additions & 0 deletions src/test/ui/macros/lint-trailing-macro-call.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// check-pass
//
// Ensures that we properly lint
// a removed 'expression' resulting from a macro
// in trailing expression position

macro_rules! expand_it {
() => {
#[cfg(FALSE)] 25; //~ WARN trailing semicolon in macro
//~| WARN this was previously
}
}

fn main() {
expand_it!()
}
18 changes: 18 additions & 0 deletions src/test/ui/macros/lint-trailing-macro-call.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
warning: trailing semicolon in macro used in expression position
--> $DIR/lint-trailing-macro-call.rs:9:25
|
LL | #[cfg(FALSE)] 25;
| ^
...
LL | expand_it!()
| ------------ 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 <https://github.com/rust-lang/rust/issues/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 `expand_it`
= note: this warning originates in the macro `expand_it` (in Nightly builds, run with -Z macro-backtrace for more info)

warning: 1 warning emitted

0 comments on commit c981a57

Please sign in to comment.