Skip to content

Commit 6757053

Browse files
huonwalexcrichton
authored andcommitted
syntax: allow stmt/expr macro invocations to be delimited by {}.
This makes using control-flow-y macros like `spawn! { ... }` more fluent and natural. cc #11892.
1 parent 0309104 commit 6757053

5 files changed

+94
-3
lines changed

src/libsyntax/parse/parser.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3185,15 +3185,35 @@ impl Parser {
31853185
let pth = self.parse_path(NoTypesAllowed).path;
31863186
self.bump();
31873187

3188-
let id = if self.token == token::LPAREN {
3188+
let id = if self.token == token::LPAREN || self.token == token::LBRACE {
31893189
token::special_idents::invalid // no special identifier
31903190
} else {
31913191
self.parse_ident()
31923192
};
31933193

3194+
// check that we're pointing at delimiters (need to check
3195+
// again after the `if`, because of `parse_ident`
3196+
// consuming more tokens).
3197+
let (bra, ket) = match self.token {
3198+
token::LPAREN => (token::LPAREN, token::RPAREN),
3199+
token::LBRACE => (token::LBRACE, token::RBRACE),
3200+
_ => {
3201+
// we only expect an ident if we didn't parse one
3202+
// above.
3203+
let ident_str = if id == token::special_idents::invalid {
3204+
"identifier, "
3205+
} else {
3206+
""
3207+
};
3208+
let tok_str = self.this_token_to_str();
3209+
self.fatal(format!("expected {}`(` or `\\{`, but found `{}`",
3210+
ident_str, tok_str))
3211+
}
3212+
};
3213+
31943214
let tts = self.parse_unspanned_seq(
3195-
&token::LPAREN,
3196-
&token::RPAREN,
3215+
&bra,
3216+
&ket,
31973217
seq_sep_none(),
31983218
|p| p.parse_token_tree()
31993219
);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2014 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+
fn main() {
12+
foo! bar < //~ ERROR expected `(` or `{`, but found `<`
13+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2014 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+
fn main() {
12+
foo! {
13+
bar, "baz", 1, 2.0
14+
) //~ ERROR incorrect close delimiter
15+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2014 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+
fn main() {
12+
foo! (
13+
bar, "baz", 1, 2.0
14+
} //~ ERROR incorrect close delimiter
15+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2014 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+
#[feature(macro_rules)];
12+
13+
macro_rules! expr (($e: expr) => { $e })
14+
15+
macro_rules! spawn {
16+
($($code: tt)*) => {
17+
expr!(spawn(proc() {$($code)*}))
18+
}
19+
}
20+
21+
pub fn main() {
22+
spawn! {
23+
info!("stmt");
24+
};
25+
let _ = spawn! {
26+
info!("expr");
27+
};
28+
}

0 commit comments

Comments
 (0)