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.
This commit is contained in:
parent
2c7bc5e33c
commit
bd4c9676c7
3 changed files with 43 additions and 6 deletions
|
@ -1386,14 +1386,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
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue