about summary refs log tree commit diff
diff options
context:
space:
mode:
authorKevin Ballard <kevin@sb.org>2014-05-25 18:33:52 -0700
committerKevin Ballard <kevin@sb.org>2014-05-25 22:33:12 -0700
commitff0f9b62f64cea6474e93667f93b91c05e3be57f (patch)
treef8849c1b7a40ca8d0782395207004b2cddfa88ee
parent759517c180857e1b494486d810c882755a1e2e26 (diff)
downloadrust-ff0f9b62f64cea6474e93667f93b91c05e3be57f.tar.gz
rust-ff0f9b62f64cea6474e93667f93b91c05e3be57f.zip
Allow $foo:block nonterminals in expression position
Fixes #13678.
-rw-r--r--src/libsyntax/parse/parser.rs18
-rw-r--r--src/test/run-pass/macro-block-nonterminal.rs21
2 files changed, 32 insertions, 7 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index bfdf0361f05..ae5f16c2580 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -135,17 +135,21 @@ at INTERPOLATED tokens */
 macro_rules! maybe_whole_expr (
     ($p:expr) => (
         {
-            let mut maybe_path = match ($p).token {
-                INTERPOLATED(token::NtPath(ref pt)) => Some((**pt).clone()),
-                _ => None,
-            };
-            let found = match ($p).token {
+            let found = match $p.token {
                 INTERPOLATED(token::NtExpr(e)) => {
                     Some(e)
                 }
                 INTERPOLATED(token::NtPath(_)) => {
-                    let pt = maybe_path.take_unwrap();
-                    Some($p.mk_expr(($p).span.lo, ($p).span.hi, ExprPath(pt)))
+                    // FIXME: The following avoids an issue with lexical borrowck scopes,
+                    // but the clone is unfortunate.
+                    let pt = match $p.token {
+                        INTERPOLATED(token::NtPath(ref pt)) => (**pt).clone(),
+                        _ => unreachable!()
+                    };
+                    Some($p.mk_expr($p.span.lo, $p.span.hi, ExprPath(pt)))
+                }
+                INTERPOLATED(token::NtBlock(b)) => {
+                    Some($p.mk_expr($p.span.lo, $p.span.hi, ExprBlock(b)))
                 }
                 _ => None
             };
diff --git a/src/test/run-pass/macro-block-nonterminal.rs b/src/test/run-pass/macro-block-nonterminal.rs
new file mode 100644
index 00000000000..8a9fbbe2848
--- /dev/null
+++ b/src/test/run-pass/macro-block-nonterminal.rs
@@ -0,0 +1,21 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(macro_rules)]
+
+macro_rules! do_block{
+    ($val:block) => {$val}
+}
+
+fn main() {
+    let s;
+    do_block!({ s = "it works!"; });
+    assert_eq!(s, "it works!");
+}