Skip to content

Commit 9e1cf20

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 cbb8714 commit 9e1cf20

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: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,23 @@ use crate::{ast, token::Delimiter};
4242
/// _ => m! {} - 1, // binary subtraction operator
4343
/// }
4444
/// ```
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-
)
45+
pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool {
46+
use ast::ExprKind::*;
47+
48+
match &e.kind {
49+
If(..)
50+
| Match(..)
51+
| Block(..)
52+
| While(..)
53+
| Loop(..)
54+
| ForLoop { .. }
55+
| TryBlock(..)
56+
| ConstBlock(..) => false,
57+
58+
MacCall(mac_call) => mac_call.args.delim != Delimiter::Brace,
59+
60+
_ => true,
61+
}
5862
}
5963

6064
/// 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
@@ -1253,7 +1253,10 @@ impl<'a> State<'a> {
12531253
ast::StmtKind::Expr(expr) => {
12541254
self.space_if_not_bol();
12551255
self.print_expr_outer_attr_style(expr, false, FixupContext::new_stmt());
1256-
if classify::expr_requires_semi_to_be_stmt_FIXME(expr) {
1256+
if match expr.kind {
1257+
ast::ExprKind::MacCall(_) => true,
1258+
_ => classify::expr_requires_semi_to_be_stmt(expr),
1259+
} {
12571260
self.word(";");
12581261
}
12591262
}

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,11 @@ impl FixupContext {
128128
/// The documentation on `FixupContext::leftmost_subexpression_in_stmt` has
129129
/// examples.
130130
pub fn would_cause_statement_boundary(self, expr: &Expr) -> bool {
131-
self.leftmost_subexpression_in_stmt && !classify::expr_requires_semi_to_be_stmt_FIXME(expr)
131+
self.leftmost_subexpression_in_stmt
132+
&& match expr.kind {
133+
ExprKind::MacCall(_) => false,
134+
_ => !classify::expr_requires_semi_to_be_stmt(expr),
135+
}
132136
}
133137

134138
/// Determine whether parentheses are needed around the given `let`

compiler/rustc_lint/src/unused.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,10 @@ trait UnusedDelimLint {
688688
ExprKind::Index(base, _subscript, _) => base,
689689
_ => break,
690690
};
691-
if !classify::expr_requires_semi_to_be_stmt_FIXME(innermost) {
691+
if match innermost.kind {
692+
ExprKind::MacCall(_) => false,
693+
_ => !classify::expr_requires_semi_to_be_stmt(innermost),
694+
} {
692695
return true;
693696
}
694697
}

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,10 @@ impl<'a> Parser<'a> {
498498
/// Checks if this expression is a successfully parsed statement.
499499
fn expr_is_complete(&self, e: &Expr) -> bool {
500500
self.restrictions.contains(Restrictions::STMT_EXPR)
501-
&& !classify::expr_requires_semi_to_be_stmt_FIXME(e)
501+
&& match e.kind {
502+
ExprKind::MacCall(_) => false,
503+
_ => !classify::expr_requires_semi_to_be_stmt(e),
504+
}
502505
}
503506

504507
/// Parses `x..y`, `x..=y`, and `x..`/`x..=`.
@@ -2694,7 +2697,10 @@ impl<'a> Parser<'a> {
26942697
// If it's not a free-standing expression, and is followed by a block,
26952698
// then it's very likely the condition to an `else if`.
26962699
if self.check(&TokenKind::OpenDelim(Delimiter::Brace))
2697-
&& classify::expr_requires_semi_to_be_stmt_FIXME(&cond) =>
2700+
&& match cond.kind {
2701+
ExprKind::MacCall(_) => true,
2702+
_ => classify::expr_requires_semi_to_be_stmt(&cond),
2703+
} =>
26982704
{
26992705
self.dcx().emit_err(errors::ExpectedElseBlock {
27002706
first_tok_span,
@@ -3136,8 +3142,10 @@ impl<'a> Parser<'a> {
31363142
err
31373143
})?;
31383144

3139-
let require_comma = classify::expr_requires_semi_to_be_stmt_FIXME(&expr)
3140-
&& this.token != token::CloseDelim(Delimiter::Brace);
3145+
let require_comma = match expr.kind {
3146+
ExprKind::MacCall(_) => true,
3147+
_ => classify::expr_requires_semi_to_be_stmt(&expr),
3148+
} && this.token != token::CloseDelim(Delimiter::Brace);
31413149

31423150
if !require_comma {
31433151
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
@@ -648,8 +648,10 @@ impl<'a> Parser<'a> {
648648
match &mut stmt.kind {
649649
// Expression without semicolon.
650650
StmtKind::Expr(expr)
651-
if classify::expr_requires_semi_to_be_stmt_FIXME(expr)
652-
&& !expr.attrs.is_empty()
651+
if match expr.kind {
652+
ExprKind::MacCall(_) => true,
653+
_ => classify::expr_requires_semi_to_be_stmt(expr),
654+
} && !expr.attrs.is_empty()
653655
&& ![token::Eof, token::Semi, token::CloseDelim(Delimiter::Brace)]
654656
.contains(&self.token.kind) =>
655657
{
@@ -663,7 +665,10 @@ impl<'a> Parser<'a> {
663665
// Expression without semicolon.
664666
StmtKind::Expr(expr)
665667
if self.token != token::Eof
666-
&& classify::expr_requires_semi_to_be_stmt_FIXME(expr) =>
668+
&& match expr.kind {
669+
ExprKind::MacCall(_) => true,
670+
_ => classify::expr_requires_semi_to_be_stmt(expr),
671+
} =>
667672
{
668673
// Just check for errors and recover; do not eat semicolon yet.
669674

0 commit comments

Comments
 (0)