diff options
| author | P1start <rewi-github@whanau.org> | 2014-12-21 19:03:31 +1300 |
|---|---|---|
| committer | P1start <rewi-github@whanau.org> | 2014-12-30 16:06:48 +1300 |
| commit | 5cf72ff8988243814aed3f384ea272e2c3d85ee2 (patch) | |
| tree | 952cc1f83efe8ee05e5e1c57cb0fa059172d08a3 /src | |
| parent | fea5aa656ff4349f4d3e1fea1447d26986762ae1 (diff) | |
| download | rust-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.rs | 15 | ||||
| -rw-r--r-- | src/test/run-pass/parse-complex-macro-invoc-op.rs | 43 |
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; + + id!(true) && true; + id![true] || true; +} + +fn main() {} |
