# Syntax of block-like expressions in match arms

**URL:** <https://internals.rust-lang.org/t/syntax-of-block-like-expressions-in-match-arms/5025>\
**Category:** language design\
**Created:** [March 31, 2017, 11:16am UTC](https://internals.rust-lang.org/t/syntax-of-block-like-expressions-in-match-arms/5025 "2017-03-31T11:16:41Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [March 31, 2017, 11:16am UTC](https://internals.rust-lang.org/t/syntax-of-block-like-expressions-in-match-arms/5025/1 "2017-03-31T11:16:41Z")

</div>

Hi! I’ve noticed that `rustc` treats block-like expressions differently for determining if the `;` or `,` is needed:

```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 semicolons. 
        3 => loop { },
        4 => while true {},
        _ => ()
    }
}

```

This seems just weird to me… Is there a reason you really need `,` after an `if` in match? Perhaps this is a bug that needs to be fixed?

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [March 31, 2017, 11:59am UTC](https://internals.rust-lang.org/t/syntax-of-block-like-expressions-in-match-arms/5025/2 "2017-03-31T11:59:22Z")

</div>

I wrangle with this too. In my case it’s:

```rust
match n {
    1 => foo() // not legal
    2 => foo(); // not legal either
};
{
    foo(); // fine
    foo() // fine too
}

```

---

<div class="post-metadata">

**Author:** ![Enamex](https://avatars.discourse-cdn.com/v4/letter/e/41988e/32.png) [@Enamex](https://internals.rust-lang.org/u/Enamex)\
**Post date:** [March 31, 2017, 6:11pm UTC](https://internals.rust-lang.org/t/syntax-of-block-like-expressions-in-match-arms/5025/3 "2017-03-31T18:11:25Z")

</div>

Seems like at one point all right hand blocks/statements of match arms were meant to end with a comma to separate them from the next arms.

I think that makes more sense than extending the ability to omit the comma to other block-like right hands.

---

<div class="post-metadata">

**Author:** ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)\
**Post date:** [March 31, 2017, 7:01pm UTC](https://internals.rust-lang.org/t/syntax-of-block-like-expressions-in-match-arms/5025/4 "2017-03-31T19:01:03Z")

</div>

I think it makes sense to make these consistent. I’ve definitely found the need for a comma after an inner `match` annoying (you missed this one but its the same).

---

<div class="post-metadata">

**Author:** ![harpocrates](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/harpocrates/32/3097_2.png) [@harpocrates](https://internals.rust-lang.org/u/harpocrates)\
**Post date:** [March 31, 2017, 9:42pm UTC](https://internals.rust-lang.org/t/syntax-of-block-like-expressions-in-match-arms/5025/5 "2017-03-31T21:42:11Z")

</div>

I came here to figure out what conflicts this would introduce from a parsing perspective and, armed with an [LALR grammar I recently wrote](https://github.com/harpocrates/language-rust/blob/master/src/Language/Rust/Parser/Internal.y), I tried loosening the need for a comma after block-like expressions (`if`, `loop`, `for`, `while`, `match`, macros with braces, and unsafe blocks) to see what conflicts that would introduce. To my surprise, it didn’t introduce any. Of course, it could be my grammar that is broken. 🙂

Naturally, we still _do_ need commas after struct literals even if they end in a block…

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [March 31, 2017, 9:56pm UTC](https://internals.rust-lang.org/t/syntax-of-block-like-expressions-in-match-arms/5025/6 "2017-03-31T21:56:00Z")

</div>

A problematic case might be

```rust
let x: &i32 = unimplemented!();
match x {
   &1 => if true { 1 } else { 2 } &3 // is &3 a pattern or a bitwise and?
}

```

But looks like this is already forbidden in match arms (in blocks, &3 is treated as a separate expression statement).

---

<div class="post-metadata">

**Author:** ![harpocrates](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/harpocrates/32/3097_2.png) [@harpocrates](https://internals.rust-lang.org/u/harpocrates)\
**Post date:** [April 1, 2017, 1:02am UTC](https://internals.rust-lang.org/t/syntax-of-block-like-expressions-in-match-arms/5025/7 "2017-04-01T01:02:01Z")

</div>

`if true { 1 } else { 2 } &3` _isn’t a block-like expression_, so it isn’t even in the running. `&3` cannot be anything but a pattern.

The problem you are describing is an ambiguity that one might see happening in expression statements. To deal with _that_ Rust expects the LHS of a binary expression to not be block-like for it to be turned into a statement.

In any case, this poses no problems in `match` blocks.

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [April 1, 2017, 6:46am UTC](https://internals.rust-lang.org/t/syntax-of-block-like-expressions-in-match-arms/5025/8 "2017-04-01T06:46:12Z")

</div>

@harpocrates are you aware of [https://github.com/rust-lang/rust/issues/30942](https://github.com/rust-lang/rust/issues/30942)? I think yours is the most complete LALR style Rust grammar so far, might be useful to advertise it on that issue 🙂

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [April 1, 2017, 8:16am UTC](https://internals.rust-lang.org/t/syntax-of-block-like-expressions-in-match-arms/5025/9 "2017-04-01T08:16:10Z")

</div>

PR: [https://github.com/rust-lang/rust/pull/40989](https://github.com/rust-lang/rust/pull/40989)

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [March 25, 2019, 8:28am UTC](https://internals.rust-lang.org/t/syntax-of-block-like-expressions-in-match-arms/5025/10 "2019-03-25T08:28:16Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
