Skip to content

Commit 507fba5

Browse files
committed
syntax: Allow any block-like expr to be used as alt arm w/o comma separator
1 parent fd17d34 commit 507fba5

File tree

5 files changed

+99
-34
lines changed

5 files changed

+99
-34
lines changed

src/libsyntax/ast_util.rs

-7
Original file line numberDiff line numberDiff line change
@@ -588,13 +588,6 @@ fn view_path_id(p: @view_path) -> node_id {
588588
}
589589
}
590590

591-
fn lone_block_expr(blk: blk) -> option<@ast::expr> {
592-
if blk.node.view_items.len() != 0 { ret none; }
593-
if blk.node.stmts.len() != 0 { ret none; }
594-
if blk.node.rules != default_blk { ret none; }
595-
ret blk.node.expr;
596-
}
597-
598591
// Local Variables:
599592
// mode: rust
600593
// fill-column: 78;

src/libsyntax/parse/parser.rs

+25-20
Original file line numberDiff line numberDiff line change
@@ -1477,9 +1477,10 @@ class parser {
14771477
// For distingishing between record literals and blocks
14781478
fn looking_at_record_literal() -> bool {
14791479
let lookahead = self.look_ahead(1);
1480-
self.token_is_keyword(~"mut", lookahead) ||
1481-
(is_plain_ident(lookahead) &&
1482-
self.look_ahead(2) == token::COLON)
1480+
self.token == token::LBRACE &&
1481+
(self.token_is_keyword(~"mut", lookahead) ||
1482+
(is_plain_ident(lookahead) &&
1483+
self.look_ahead(2) == token::COLON))
14831484
}
14841485
14851486
fn parse_record_literal() -> expr_ {
@@ -1518,26 +1519,30 @@ class parser {
15181519
let pats = self.parse_pats();
15191520
let mut guard = none;
15201521
if self.eat_keyword(~"if") { guard = some(self.parse_expr()); }
1521-
let blk = if self.token != token::FAT_ARROW {
1522-
self.parse_block()
1522+
let expr = if self.token != token::FAT_ARROW {
1523+
self.parse_block_expr(self.last_span.lo, default_blk)
15231524
} else {
15241525
self.bump();
1525-
if self.token == token::LBRACE
1526-
&& !self.looking_at_record_literal() {
1527-
self.parse_block()
1528-
} else {
1529-
let expr = self.parse_expr();
1530-
if self.token != token::RBRACE {
1531-
self.expect(token::COMMA);
1532-
}
1533-
{node: {view_items: ~[],
1534-
stmts: ~[],
1535-
expr: some(expr),
1536-
id: self.get_id(),
1537-
rules: default_blk},
1538-
span: expr.span}
1539-
}
1526+
self.parse_expr_res(RESTRICT_STMT_EXPR)
15401527
};
1528+
1529+
let require_comma =
1530+
classify::expr_requires_semi_to_be_stmt(expr)
1531+
&& self.token != token::RBRACE;
1532+
1533+
if require_comma {
1534+
self.expect(token::COMMA);
1535+
} else {
1536+
self.eat(token::COMMA);
1537+
}
1538+
1539+
let blk = {node: {view_items: ~[],
1540+
stmts: ~[],
1541+
expr: some(expr),
1542+
id: self.get_id(),
1543+
rules: default_blk},
1544+
span: expr.span};
1545+
15411546
vec::push(arms, {pats: pats, guard: guard, body: blk});
15421547
}
15431548
let mut hi = self.span.hi;

src/libsyntax/print/pprust.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import pp::{break_offset, word, printer,
66
inconsistent, eof};
77
import diagnostic;
88
import ast::{required, provided};
9-
import ast_util::{operator_prec, lone_block_expr};
9+
import ast_util::{operator_prec};
1010
import dvec::{dvec, extensions};
1111
import parse::classify::*;
1212
import util::interner;
@@ -1052,17 +1052,21 @@ fn print_expr(s: ps, &&expr: @ast::expr) {
10521052
none { }
10531053
}
10541054
word_space(s, ~"=>");
1055-
alt lone_block_expr(arm.body) {
1055+
// Extract the expression from the extra block the parser adds
1056+
assert arm.body.node.view_items.is_empty();
1057+
assert arm.body.node.stmts.is_empty();
1058+
assert arm.body.node.rules == ast::default_blk;
1059+
alt arm.body.node.expr {
10561060
some(expr) => {
10571061
end(s); // close the ibox for the pattern
10581062
print_expr(s, expr);
1059-
if i < len - 1 { word(s.s, ~","); }
1063+
if expr_requires_semi_to_be_stmt(expr)
1064+
&& i < len - 1 {
1065+
word(s.s, ~",");
1066+
}
10601067
end(s); // close enclosing cbox
10611068
}
1062-
none => {
1063-
print_possibly_embedded_block(s, arm.body, block_normal,
1064-
alt_indent_unit);
1065-
}
1069+
none => fail
10661070
}
10671071
}
10681072
bclose_(s, expr.span, alt_indent_unit);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
fn main() {
2+
3+
alt 0 {
4+
0 => {
5+
} + 5 //~ ERROR unexpected token: `+`
6+
}
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// no-reformat
2+
// Testing the presense or absense of commas separating block-structure
3+
// alt arm expressions
4+
5+
fn fun(_f: fn()) {
6+
}
7+
8+
fn it(_f: fn() -> bool) {
9+
}
10+
11+
fn main() {
12+
13+
alt 0 {
14+
00 => {
15+
}
16+
01 => if true {
17+
} else {
18+
}
19+
03 => alt 0 {
20+
_ => ()
21+
}
22+
04 => do fun {
23+
}
24+
05 => for it {
25+
}
26+
06 => while false {
27+
}
28+
07 => loop {
29+
}
30+
08 => unsafe {
31+
}
32+
09 => unchecked {
33+
}
34+
10 => {
35+
},
36+
11 => if true {
37+
} else {
38+
},
39+
13 => alt 0 {
40+
_ => ()
41+
},
42+
14 => do fun {
43+
},
44+
15 => for it {
45+
},
46+
16 => while false {
47+
},
48+
17 => loop {
49+
},
50+
18 => unsafe {
51+
},
52+
19 => unchecked {
53+
},
54+
_ => ()
55+
}
56+
}

0 commit comments

Comments
 (0)