Skip to content

Commit 83c3621

Browse files
committed
Auto merge of #40989 - matklad:comma-arms, r=petrochenkov
Unify rules about commas in match arms and semicolons in expressions Original discussion: https://internals.rust-lang.org/t/syntax-of-block-like-expressions-in-match-arms/5025/7. Currently, rust uses different rules to determine if `,` is needed after an expression in a match arm and if `;` is needed in an expression statement: ```Rust fn stmt() { # no need for semicolons { () } if true { () } else { () } loop {} while true {} } fn match_arm(n: i32) { match n { 1 => { () } # can omit comma here 2 => if true { () } else { () }, # but all other cases do need commas. 3 => loop { }, 4 => while true {}, _ => () } } ``` This seems weird: why would you want to require `,` after and `if`? This PR unifies the rules. It is backwards compatible because it allows strictly more programs.
2 parents af049cd + e3d052f commit 83c3621

File tree

4 files changed

+57
-11
lines changed

4 files changed

+57
-11
lines changed

src/libsyntax/parse/classify.rs

+3-9
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
1313
// Predicates on exprs and stmts that the pretty-printer and parser use
1414

15-
use ast::{self, BlockCheckMode};
15+
use ast;
1616

1717
/// Does this expression require a semicolon to be treated
1818
/// as a statement? The negation of this: 'can this expression
@@ -30,18 +30,12 @@ pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool {
3030
ast::ExprKind::While(..) |
3131
ast::ExprKind::WhileLet(..) |
3232
ast::ExprKind::Loop(..) |
33-
ast::ExprKind::ForLoop(..) => false,
33+
ast::ExprKind::ForLoop(..) |
34+
ast::ExprKind::Catch(..) => false,
3435
_ => true,
3536
}
3637
}
3738

38-
pub fn expr_is_simple_block(e: &ast::Expr) -> bool {
39-
match e.node {
40-
ast::ExprKind::Block(ref block) => block.rules == BlockCheckMode::Default,
41-
_ => false,
42-
}
43-
}
44-
4539
/// this statement requires a semicolon after it.
4640
/// note that in one case (`stmt_semi`), we've already
4741
/// seen the semicolon, and thus don't need another.

src/libsyntax/parse/parser.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -3209,8 +3209,7 @@ impl<'a> Parser<'a> {
32093209
self.expect(&token::FatArrow)?;
32103210
let expr = self.parse_expr_res(RESTRICTION_STMT_EXPR, None)?;
32113211

3212-
let require_comma =
3213-
!classify::expr_is_simple_block(&expr)
3212+
let require_comma = classify::expr_requires_semi_to_be_stmt(&expr)
32143213
&& self.token != token::CloseDelim(token::Brace);
32153214

32163215
if require_comma {

src/test/run-pass/catch-expr.rs

+6
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,10 @@ pub fn main() {
7171
Ok(&my_string)
7272
};
7373
assert_eq!(res, Ok("test"));
74+
75+
do catch {
76+
()
77+
}
78+
79+
();
7480
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// ignore-pretty issue #37199
12+
13+
fn main() {
14+
let x = 1;
15+
16+
match x {
17+
1 => loop { break; },
18+
2 => while true { break; },
19+
3 => if true { () },
20+
4 => if true { () } else { () },
21+
5 => match () { () => () },
22+
6 => { () },
23+
7 => unsafe { () },
24+
_ => (),
25+
}
26+
27+
match x {
28+
1 => loop { break; }
29+
2 => while true { break; }
30+
3 => if true { () }
31+
4 => if true { () } else { () }
32+
5 => match () { () => () }
33+
6 => { () }
34+
7 => unsafe { () }
35+
_ => ()
36+
}
37+
38+
let r: &i32 = &x;
39+
40+
match r {
41+
// Absence of comma should not cause confusion between a pattern
42+
// and a bitwise and.
43+
&1 => if true { () } else { () }
44+
&2 => (),
45+
_ =>()
46+
}
47+
}

0 commit comments

Comments
 (0)