diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 5f46a693f18..a2ac336f605 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -588,13 +588,6 @@ fn view_path_id(p: @view_path) -> node_id { } } -fn lone_block_expr(blk: blk) -> option<@ast::expr> { - if blk.node.view_items.len() != 0 { ret none; } - if blk.node.stmts.len() != 0 { ret none; } - if blk.node.rules != default_blk { ret none; } - ret blk.node.expr; -} - // Local Variables: // mode: rust // fill-column: 78; diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 78768ea7f35..ada3810b45f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1477,9 +1477,10 @@ class parser { // For distingishing between record literals and blocks fn looking_at_record_literal() -> bool { let lookahead = self.look_ahead(1); - self.token_is_keyword(~"mut", lookahead) || - (is_plain_ident(lookahead) && - self.look_ahead(2) == token::COLON) + self.token == token::LBRACE && + (self.token_is_keyword(~"mut", lookahead) || + (is_plain_ident(lookahead) && + self.look_ahead(2) == token::COLON)) } fn parse_record_literal() -> expr_ { @@ -1518,26 +1519,30 @@ class parser { let pats = self.parse_pats(); let mut guard = none; if self.eat_keyword(~"if") { guard = some(self.parse_expr()); } - let blk = if self.token != token::FAT_ARROW { - self.parse_block() + let expr = if self.token != token::FAT_ARROW { + self.parse_block_expr(self.last_span.lo, default_blk) } else { self.bump(); - if self.token == token::LBRACE - && !self.looking_at_record_literal() { - self.parse_block() - } else { - let expr = self.parse_expr(); - if self.token != token::RBRACE { - self.expect(token::COMMA); - } - {node: {view_items: ~[], - stmts: ~[], - expr: some(expr), - id: self.get_id(), - rules: default_blk}, - span: expr.span} - } + self.parse_expr_res(RESTRICT_STMT_EXPR) }; + + let require_comma = + classify::expr_requires_semi_to_be_stmt(expr) + && self.token != token::RBRACE; + + if require_comma { + self.expect(token::COMMA); + } else { + self.eat(token::COMMA); + } + + let blk = {node: {view_items: ~[], + stmts: ~[], + expr: some(expr), + id: self.get_id(), + rules: default_blk}, + span: expr.span}; + vec::push(arms, {pats: pats, guard: guard, body: blk}); } let mut hi = self.span.hi; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index b0ef87a8cca..b02bebf58b7 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -6,7 +6,7 @@ import pp::{break_offset, word, printer, inconsistent, eof}; import diagnostic; import ast::{required, provided}; -import ast_util::{operator_prec, lone_block_expr}; +import ast_util::{operator_prec}; import dvec::{dvec, extensions}; import parse::classify::*; import util::interner; @@ -1052,17 +1052,21 @@ fn print_expr(s: ps, &&expr: @ast::expr) { none { } } word_space(s, ~"=>"); - alt lone_block_expr(arm.body) { + // Extract the expression from the extra block the parser adds + assert arm.body.node.view_items.is_empty(); + assert arm.body.node.stmts.is_empty(); + assert arm.body.node.rules == ast::default_blk; + alt arm.body.node.expr { some(expr) => { end(s); // close the ibox for the pattern print_expr(s, expr); - if i < len - 1 { word(s.s, ~","); } + if expr_requires_semi_to_be_stmt(expr) + && i < len - 1 { + word(s.s, ~","); + } end(s); // close enclosing cbox } - none => { - print_possibly_embedded_block(s, arm.body, block_normal, - alt_indent_unit); - } + none => fail } } bclose_(s, expr.span, alt_indent_unit); diff --git a/src/test/compile-fail/alt-arrows-block-then-binop.rs b/src/test/compile-fail/alt-arrows-block-then-binop.rs new file mode 100644 index 00000000000..037e0c8b517 --- /dev/null +++ b/src/test/compile-fail/alt-arrows-block-then-binop.rs @@ -0,0 +1,7 @@ +fn main() { + + alt 0 { + 0 => { + } + 5 //~ ERROR unexpected token: `+` + } +} \ No newline at end of file diff --git a/src/test/run-pass/alt-arrows-blocky-commas.rs b/src/test/run-pass/alt-arrows-blocky-commas.rs new file mode 100644 index 00000000000..100ec11cd96 --- /dev/null +++ b/src/test/run-pass/alt-arrows-blocky-commas.rs @@ -0,0 +1,56 @@ +// no-reformat +// Testing the presense or absense of commas separating block-structure +// alt arm expressions + +fn fun(_f: fn()) { +} + +fn it(_f: fn() -> bool) { +} + +fn main() { + + alt 0 { + 00 => { + } + 01 => if true { + } else { + } + 03 => alt 0 { + _ => () + } + 04 => do fun { + } + 05 => for it { + } + 06 => while false { + } + 07 => loop { + } + 08 => unsafe { + } + 09 => unchecked { + } + 10 => { + }, + 11 => if true { + } else { + }, + 13 => alt 0 { + _ => () + }, + 14 => do fun { + }, + 15 => for it { + }, + 16 => while false { + }, + 17 => loop { + }, + 18 => unsafe { + }, + 19 => unchecked { + }, + _ => () + } +} \ No newline at end of file