about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-07-19 00:35:33 +0000
committerbors <bors@rust-lang.org>2017-07-19 00:35:33 +0000
commit83c36219102616939c4172184b01176f19033464 (patch)
treed549285d8c122f654bb321211a431ca0527c972e /src/libsyntax/parse
parentaf049cd08b58520af2dd202f15d00f67f9748322 (diff)
parente3d052f30af80e58289065bb3d7520e0e7be1ee8 (diff)
downloadrust-83c36219102616939c4172184b01176f19033464.tar.gz
rust-83c36219102616939c4172184b01176f19033464.zip
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.
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/classify.rs12
-rw-r--r--src/libsyntax/parse/parser.rs3
2 files changed, 4 insertions, 11 deletions
diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/parse/classify.rs
index 0c6f09ba766..b8e02556625 100644
--- a/src/libsyntax/parse/classify.rs
+++ b/src/libsyntax/parse/classify.rs
@@ -12,7 +12,7 @@
 
 // Predicates on exprs and stmts that the pretty-printer and parser use
 
-use ast::{self, BlockCheckMode};
+use ast;
 
 /// Does this expression require a semicolon to be treated
 /// 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 {
         ast::ExprKind::While(..) |
         ast::ExprKind::WhileLet(..) |
         ast::ExprKind::Loop(..) |
-        ast::ExprKind::ForLoop(..) => false,
+        ast::ExprKind::ForLoop(..) |
+        ast::ExprKind::Catch(..) => false,
         _ => true,
     }
 }
 
-pub fn expr_is_simple_block(e: &ast::Expr) -> bool {
-    match e.node {
-        ast::ExprKind::Block(ref block) => block.rules == BlockCheckMode::Default,
-        _ => false,
-    }
-}
-
 /// this statement requires a semicolon after it.
 /// note that in one case (`stmt_semi`), we've already
 /// seen the semicolon, and thus don't need another.
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 90d9ae383a4..ae3edfcbf32 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -3209,8 +3209,7 @@ impl<'a> Parser<'a> {
         self.expect(&token::FatArrow)?;
         let expr = self.parse_expr_res(RESTRICTION_STMT_EXPR, None)?;
 
-        let require_comma =
-            !classify::expr_is_simple_block(&expr)
+        let require_comma = classify::expr_requires_semi_to_be_stmt(&expr)
             && self.token != token::CloseDelim(token::Brace);
 
         if require_comma {