diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index a66d6839ab0..d00406e07b7 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -382,6 +382,9 @@ fn initial_syntax_expander_table() -> SyntaxEnv { syntax_expanders.insert(intern("quote_pat"), builtin_normal_expander( ext::quote::expand_quote_pat)); + syntax_expanders.insert(intern("quote_arm"), + builtin_normal_expander( + ext::quote::expand_quote_arm)); syntax_expanders.insert(intern("quote_stmt"), builtin_normal_expander( ext::quote::expand_quote_stmt)); diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 8f236cebcf4..dcfb0198127 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -349,6 +349,14 @@ pub fn expand_quote_pat(cx: &mut ExtCtxt, base::MacExpr::new(expanded) } +pub fn expand_quote_arm(cx: &mut ExtCtxt, + sp: Span, + tts: &[ast::TokenTree]) + -> Box { + let expanded = expand_parse_call(cx, sp, "parse_arm", vec!(), tts); + base::MacExpr::new(expanded) +} + pub fn expand_quote_ty(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 878994369d0..945a643d2b4 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2727,37 +2727,41 @@ impl<'a> Parser<'a> { self.commit_expr_expecting(discriminant, token::LBRACE); let mut arms: Vec = Vec::new(); while self.token != token::RBRACE { - let attrs = self.parse_outer_attributes(); - let pats = self.parse_pats(); - let mut guard = None; - if self.eat_keyword(keywords::If) { - guard = Some(self.parse_expr()); - } - self.expect(&token::FAT_ARROW); - let expr = self.parse_expr_res(RESTRICT_STMT_EXPR); - - let require_comma = - !classify::expr_is_simple_block(expr) - && self.token != token::RBRACE; - - if require_comma { - self.commit_expr(expr, &[token::COMMA], &[token::RBRACE]); - } else { - self.eat(&token::COMMA); - } - - arms.push(ast::Arm { - attrs: attrs, - pats: pats, - guard: guard, - body: expr - }); + arms.push(self.parse_arm()); } let hi = self.span.hi; self.bump(); return self.mk_expr(lo, hi, ExprMatch(discriminant, arms)); } + pub fn parse_arm(&mut self) -> Arm { + let attrs = self.parse_outer_attributes(); + let pats = self.parse_pats(); + let mut guard = None; + if self.eat_keyword(keywords::If) { + guard = Some(self.parse_expr()); + } + self.expect(&token::FAT_ARROW); + let expr = self.parse_expr_res(RESTRICT_STMT_EXPR); + + let require_comma = + !classify::expr_is_simple_block(expr) + && self.token != token::RBRACE; + + if require_comma { + self.commit_expr(expr, &[token::COMMA], &[token::RBRACE]); + } else { + self.eat(&token::COMMA); + } + + ast::Arm { + attrs: attrs, + pats: pats, + guard: guard, + body: expr, + } + } + /// Parse an expression pub fn parse_expr(&mut self) -> Gc { return self.parse_expr_res(UNRESTRICTED); diff --git a/src/test/run-make/graphviz-flowgraph/f07.dot-expected.dot b/src/test/run-make/graphviz-flowgraph/f07.dot-expected.dot index f0907d8d708..2b7088fbc33 100644 --- a/src/test/run-make/graphviz-flowgraph/f07.dot-expected.dot +++ b/src/test/run-make/graphviz-flowgraph/f07.dot-expected.dot @@ -6,7 +6,7 @@ digraph block { N4[label="expr 777i"]; N5[label="expr 7777i"]; N6[label="expr [7i, 77i, 777i, 7777i]"]; - N7[label="expr match [7i, 77i, 777i, 7777i] { [x, y, ..] => x + y }"]; + N7[label="expr match [7i, 77i, 777i, 7777i] { [x, y, ..] => x + y, }"]; N8[label="(dummy_node)"]; N9[label="local x"]; N10[label="local y"]; @@ -15,7 +15,7 @@ digraph block { N13[label="expr x"]; N14[label="expr y"]; N15[label="expr x + y"]; - N16[label="block { match [7i, 77i, 777i, 7777i] { [x, y, ..] => x + y }; }"]; + N16[label="block { match [7i, 77i, 777i, 7777i] { [x, y, ..] => x + y, }; }"]; N0 -> N2; N2 -> N3; N3 -> N4; diff --git a/src/test/run-make/graphviz-flowgraph/f13.dot-expected.dot b/src/test/run-make/graphviz-flowgraph/f13.dot-expected.dot index dbfa4dd6fe9..5d1d1253b22 100644 --- a/src/test/run-make/graphviz-flowgraph/f13.dot-expected.dot +++ b/src/test/run-make/graphviz-flowgraph/f13.dot-expected.dot @@ -7,7 +7,7 @@ digraph block { N5[label="local x"]; N6[label="local _y"]; N7[label="expr x"]; - N8[label="expr match x { E13a => _y = 1, E13b(v) => _y = v + 1 }"]; + N8[label="expr match x { E13a => _y = 1, E13b(v) => _y = v + 1, }"]; N9[label="(dummy_node)"]; N10[label="local E13a"]; N11[label="expr 1"]; @@ -21,7 +21,7 @@ digraph block { N19[label="expr v + 1"]; N20[label="expr _y"]; N21[label="expr _y = v + 1"]; - N22[label="block {\l let x = E13b(13);\l let _y;\l match x { E13a => _y = 1, E13b(v) => _y = v + 1 }\l}\l"]; + N22[label="block {\l let x = E13b(13);\l let _y;\l match x { E13a => _y = 1, E13b(v) => _y = v + 1, }\l}\l"]; N0 -> N2; N2 -> N3; N3 -> N4; diff --git a/src/test/run-pass-fulldeps/qquote.rs b/src/test/run-pass-fulldeps/qquote.rs index 36b525c134b..a5cf8e46b7e 100644 --- a/src/test/run-pass-fulldeps/qquote.rs +++ b/src/test/run-pass-fulldeps/qquote.rs @@ -72,6 +72,8 @@ fn main() { let pat = quote_pat!(cx, Some(_)); check_pp(ext_cx, pat, pprust::print_pat, "Some(_)".to_string()); + let arm = quote_arm!(cx, (ref x, ref y) => (x, y)); + check_pp(ext_cx, arm, pprust::print_stmt, "(ref x, ref y) = (x, y)".to_string()); } fn check_pp(cx: fake_ext_ctxt, diff --git a/src/test/run-pass-fulldeps/quote-tokens.rs b/src/test/run-pass-fulldeps/quote-tokens.rs index 11c3dfb2241..60b8f09bb3d 100644 --- a/src/test/run-pass-fulldeps/quote-tokens.rs +++ b/src/test/run-pass-fulldeps/quote-tokens.rs @@ -26,6 +26,7 @@ fn syntax_extension(cx: &ExtCtxt) { let _b: Option> = quote_item!(cx, static foo : int = $e_toks; ); let _c: Gc = quote_pat!(cx, (x, 1 .. 4, *) ); let _d: Gc = quote_stmt!(cx, let x = $a; ); + let _d: syntax::ast::Arm = quote_arm!(cx, (ref x, ref y) = (x, y) ); let _e: Gc = quote_expr!(cx, match foo { $p_toks => 10 } ); let _f: Gc = quote_expr!(cx, ());