Skip to content

Commit 0860cb1

Browse files
committed
Macro call with braces does not require semicolon to be statement
This commit by itself is supposed to have no effect on behavior. All of the call sites are updated to preserve their previous behavior. The behavior changes are in the commits that follow.
1 parent a2845cf commit 0860cb1

File tree

6 files changed

+50
-23
lines changed

6 files changed

+50
-23
lines changed

compiler/rustc_ast/src/util/classify.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Routines the parser and pretty-printer use to classify AST nodes.
22
33
use crate::ast;
4+
use crate::token::Delimiter;
45

56
/// Does this expression require a semicolon to be treated as a statement?
67
///
@@ -42,19 +43,23 @@ use crate::ast;
4243
/// _ => m! {} - 1, // binary subtraction operator
4344
/// }
4445
/// ```
45-
#[allow(non_snake_case)]
46-
pub fn expr_requires_semi_to_be_stmt_FIXME(e: &ast::Expr) -> bool {
47-
!matches!(
48-
e.kind,
49-
ast::ExprKind::If(..)
50-
| ast::ExprKind::Match(..)
51-
| ast::ExprKind::Block(..)
52-
| ast::ExprKind::While(..)
53-
| ast::ExprKind::Loop(..)
54-
| ast::ExprKind::ForLoop { .. }
55-
| ast::ExprKind::TryBlock(..)
56-
| ast::ExprKind::ConstBlock(..)
57-
)
46+
pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool {
47+
use ast::ExprKind::*;
48+
49+
match &e.kind {
50+
If(..)
51+
| Match(..)
52+
| Block(..)
53+
| While(..)
54+
| Loop(..)
55+
| ForLoop { .. }
56+
| TryBlock(..)
57+
| ConstBlock(..) => false,
58+
59+
MacCall(mac_call) => mac_call.args.delim != Delimiter::Brace,
60+
61+
_ => true,
62+
}
5863
}
5964

6065
/// If an expression ends with `}`, returns the innermost expression ending in the `}`

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1101,7 +1101,10 @@ impl<'a> State<'a> {
11011101
false,
11021102
FixupContext { stmt: true, ..FixupContext::default() },
11031103
);
1104-
if classify::expr_requires_semi_to_be_stmt_FIXME(expr) {
1104+
if match expr.kind {
1105+
ast::ExprKind::MacCall(_) => true,
1106+
_ => classify::expr_requires_semi_to_be_stmt(expr),
1107+
} {
11051108
self.word(";");
11061109
}
11071110
}

compiler/rustc_ast_pretty/src/pprust/state/expr.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,10 @@ impl<'a> State<'a> {
471471
// Same applies to a small set of other expression kinds which eagerly
472472
// terminate a statement which opens with them.
473473
let needs_par = fixup.leftmost_subexpression_in_stmt
474-
&& !classify::expr_requires_semi_to_be_stmt_FIXME(expr);
474+
&& match expr.kind {
475+
ast::ExprKind::MacCall(_) => false,
476+
_ => !classify::expr_requires_semi_to_be_stmt(expr),
477+
};
475478
if needs_par {
476479
self.popen();
477480
fixup = FixupContext::default();

compiler/rustc_lint/src/unused.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,10 @@ trait UnusedDelimLint {
674674
ExprKind::Index(base, _subscript, _) => base,
675675
_ => break,
676676
};
677-
if !classify::expr_requires_semi_to_be_stmt_FIXME(innermost) {
677+
if match innermost.kind {
678+
ExprKind::MacCall(_) => false,
679+
_ => !classify::expr_requires_semi_to_be_stmt(innermost),
680+
} {
678681
return true;
679682
}
680683
}

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,10 @@ impl<'a> Parser<'a> {
470470
/// Checks if this expression is a successfully parsed statement.
471471
fn expr_is_complete(&self, e: &Expr) -> bool {
472472
self.restrictions.contains(Restrictions::STMT_EXPR)
473-
&& !classify::expr_requires_semi_to_be_stmt_FIXME(e)
473+
&& match e.kind {
474+
ExprKind::MacCall(_) => false,
475+
_ => !classify::expr_requires_semi_to_be_stmt(e),
476+
}
474477
}
475478

476479
/// Parses `x..y`, `x..=y`, and `x..`/`x..=`.
@@ -2567,7 +2570,10 @@ impl<'a> Parser<'a> {
25672570
// If it's not a free-standing expression, and is followed by a block,
25682571
// then it's very likely the condition to an `else if`.
25692572
if self.check(&TokenKind::OpenDelim(Delimiter::Brace))
2570-
&& classify::expr_requires_semi_to_be_stmt_FIXME(&cond) =>
2573+
&& match cond.kind {
2574+
ExprKind::MacCall(_) => true,
2575+
_ => classify::expr_requires_semi_to_be_stmt(&cond),
2576+
} =>
25712577
{
25722578
self.dcx().emit_err(errors::ExpectedElseBlock {
25732579
first_tok_span,
@@ -2989,8 +2995,10 @@ impl<'a> Parser<'a> {
29892995
err
29902996
})?;
29912997

2992-
let require_comma = classify::expr_requires_semi_to_be_stmt_FIXME(&expr)
2993-
&& this.token != token::CloseDelim(Delimiter::Brace);
2998+
let require_comma = match expr.kind {
2999+
ExprKind::MacCall(_) => true,
3000+
_ => classify::expr_requires_semi_to_be_stmt(&expr),
3001+
} && this.token != token::CloseDelim(Delimiter::Brace);
29943002

29953003
if !require_comma {
29963004
arm_body = Some(expr);

compiler/rustc_parse/src/parser/stmt.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -637,8 +637,10 @@ impl<'a> Parser<'a> {
637637
match &mut stmt.kind {
638638
// Expression without semicolon.
639639
StmtKind::Expr(expr)
640-
if classify::expr_requires_semi_to_be_stmt_FIXME(expr)
641-
&& !expr.attrs.is_empty()
640+
if match expr.kind {
641+
ExprKind::MacCall(_) => true,
642+
_ => classify::expr_requires_semi_to_be_stmt(expr),
643+
} && !expr.attrs.is_empty()
642644
&& ![token::Eof, token::Semi, token::CloseDelim(Delimiter::Brace)]
643645
.contains(&self.token.kind) =>
644646
{
@@ -652,7 +654,10 @@ impl<'a> Parser<'a> {
652654
// Expression without semicolon.
653655
StmtKind::Expr(expr)
654656
if self.token != token::Eof
655-
&& classify::expr_requires_semi_to_be_stmt_FIXME(expr) =>
657+
&& match expr.kind {
658+
ExprKind::MacCall(_) => true,
659+
_ => classify::expr_requires_semi_to_be_stmt(expr),
660+
} =>
656661
{
657662
// Just check for errors and recover; do not eat semicolon yet.
658663
// `expect_one_of` returns PResult<'a, bool /* recovered */>

0 commit comments

Comments
 (0)