Rollup merge of #78376 - Aaron1011:feature/consistent-empty-expr, r=petrochenkov
Treat trailing semicolon as a statement in macro call See #61733 (comment) We now preserve the trailing semicolon in a macro invocation, even if the macro expands to nothing. As a result, the following code no longer compiles: ```rust macro_rules! empty { () => { } } fn foo() -> bool { //~ ERROR mismatched { true } //~ ERROR mismatched empty!(); } ``` Previously, `{ true }` would be considered the trailing expression, even though there's a semicolon in `empty!();` This makes macro expansion more token-based.
This commit is contained in:
commit
0716724a0b
6 changed files with 77 additions and 2 deletions
|
@ -310,8 +310,44 @@ impl<'a, 'b> MutVisitor for PlaceholderExpander<'a, 'b> {
|
|||
};
|
||||
|
||||
if style == ast::MacStmtStyle::Semicolon {
|
||||
// Implement the proposal described in
|
||||
// https://github.com/rust-lang/rust/issues/61733#issuecomment-509626449
|
||||
//
|
||||
// The macro invocation expands to the list of statements.
|
||||
// If the list of statements is empty, then 'parse'
|
||||
// the trailing semicolon on the original invocation
|
||||
// as an empty statement. That is:
|
||||
//
|
||||
// `empty();` is parsed as a single `StmtKind::Empty`
|
||||
//
|
||||
// If the list of statements is non-empty, see if the
|
||||
// final statement alreayd has a trailing semicolon.
|
||||
//
|
||||
// If it doesn't have a semicolon, then 'parse' the trailing semicolon
|
||||
// from the invocation as part of the final statement,
|
||||
// using `stmt.add_trailing_semicolon()`
|
||||
//
|
||||
// If it does have a semicolon, then 'parse' the trailing semicolon
|
||||
// from the invocation as a new StmtKind::Empty
|
||||
|
||||
// FIXME: We will need to preserve the original
|
||||
// semicolon token and span as part of #15701
|
||||
let empty_stmt = ast::Stmt {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
kind: ast::StmtKind::Empty,
|
||||
span: DUMMY_SP,
|
||||
tokens: None,
|
||||
};
|
||||
|
||||
if let Some(stmt) = stmts.pop() {
|
||||
stmts.push(stmt.add_trailing_semicolon());
|
||||
if stmt.has_trailing_semicolon() {
|
||||
stmts.push(stmt);
|
||||
stmts.push(empty_stmt);
|
||||
} else {
|
||||
stmts.push(stmt.add_trailing_semicolon());
|
||||
}
|
||||
} else {
|
||||
stmts.push(empty_stmt);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue