about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorP1start <rewi-github@whanau.org>2014-12-21 19:03:31 +1300
committerP1start <rewi-github@whanau.org>2014-12-30 16:06:48 +1300
commit5cf72ff8988243814aed3f384ea272e2c3d85ee2 (patch)
tree952cc1f83efe8ee05e5e1c57cb0fa059172d08a3 /src
parentfea5aa656ff4349f4d3e1fea1447d26986762ae1 (diff)
downloadrust-5cf72ff8988243814aed3f384ea272e2c3d85ee2.tar.gz
rust-5cf72ff8988243814aed3f384ea272e2c3d85ee2.zip
Parse arbitrary operators after expr-like macro invocations in statement position
Closes #20093.
Diffstat (limited to 'src')
-rw-r--r--src/libsyntax/parse/parser.rs15
-rw-r--r--src/test/run-pass/parse-complex-macro-invoc-op.rs43
2 files changed, 53 insertions, 5 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 2f43661eebe..3acb74485f5 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2995,14 +2995,17 @@ impl<'a> Parser<'a> {
     /// actually, this seems to be the main entry point for
     /// parsing an arbitrary expression.
     pub fn parse_assign_expr(&mut self) -> P<Expr> {
-        let lo = self.span.lo;
         let lhs = self.parse_binops();
+        self.parse_assign_expr_with(lhs)
+    }
+
+    pub fn parse_assign_expr_with(&mut self, lhs: P<Expr>) -> P<Expr> {
         let restrictions = self.restrictions & RESTRICTION_NO_STRUCT_LITERAL;
         match self.token {
           token::Eq => {
               self.bump();
               let rhs = self.parse_expr_res(restrictions);
-              self.mk_expr(lo, rhs.span.hi, ExprAssign(lhs, rhs))
+              self.mk_expr(lhs.span.lo, rhs.span.hi, ExprAssign(lhs, rhs))
           }
           token::BinOpEq(op) => {
               self.bump();
@@ -3020,8 +3023,9 @@ impl<'a> Parser<'a> {
                   token::Shr =>     BiShr
               };
               let rhs_span = rhs.span;
+              let span = lhs.span;
               let assign_op = self.mk_assign_op(aop, lhs, rhs);
-              self.mk_expr(lo, rhs_span.hi, assign_op)
+              self.mk_expr(span.lo, rhs_span.hi, assign_op)
           }
           _ => {
               lhs
@@ -3919,8 +3923,9 @@ impl<'a> Parser<'a> {
                                     let e = self.mk_mac_expr(span.lo,
                                                              span.hi,
                                                              macro.and_then(|m| m.node));
-                                    let e =
-                                        self.parse_dot_or_call_expr_with(e);
+                                    let e = self.parse_dot_or_call_expr_with(e);
+                                    let e = self.parse_more_binops(e, 0);
+                                    let e = self.parse_assign_expr_with(e);
                                     self.handle_expression_like_statement(
                                         e,
                                         ast::DUMMY_NODE_ID,
diff --git a/src/test/run-pass/parse-complex-macro-invoc-op.rs b/src/test/run-pass/parse-complex-macro-invoc-op.rs
new file mode 100644
index 00000000000..e9ec624c13e
--- /dev/null
+++ b/src/test/run-pass/parse-complex-macro-invoc-op.rs
@@ -0,0 +1,43 @@
+// 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.
+
+// Test parsing binary operators after macro invocations.
+
+#![feature(macro_rules)]
+
+macro_rules! id {
+    ($e: expr) => { $e }
+}
+
+fn foo() {
+    id!(1i) + 1;
+    id![1i] - 1;
+    id!(1i) * 1;
+    id![1i] / 1;
+    id!(1i) % 1;
+
+    id!(1i) & 1;
+    id![1i] | 1;
+    id!(1i) ^ 1;
+
+    let mut x = 1i;
+    id![x] = 2;
+    id!(x) += 1;
+
+    id!(1f64).clone();
+
+    id!([1i, 2, 3])[1];
+    id![drop](1i);
+
+    id!(true) && true;
+    id![true] || true;
+}
+
+fn main() {}