From 20edb366e7d16da946c2484a8542dffb07b79837 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Sun, 24 Jan 2016 00:52:43 +0100 Subject: Set span for interpolated tokens correctly --- src/libsyntax/parse/parser.rs | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index acce6ed87d0..f5ebe842577 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2322,18 +2322,29 @@ impl<'a> Parser<'a> { -> PResult<'a, P> { let attrs = try!(self.parse_or_use_outer_attributes(already_parsed_attrs)); + let interp = if let token::Interpolated(..) = self.token { + true + } else { + false + }; let b = try!(self.parse_bottom_expr()); - self.parse_dot_or_call_expr_with(b, attrs) + let lo = if interp { + self.last_span.lo + } else { + b.span.lo + }; + self.parse_dot_or_call_expr_with(b, lo, attrs) } pub fn parse_dot_or_call_expr_with(&mut self, e0: P, + lo: BytePos, attrs: ThinAttributes) -> PResult<'a, P> { // Stitch the list of outer attributes onto the return value. // A little bit ugly, but the best way given the current code // structure - self.parse_dot_or_call_expr_with_(e0) + self.parse_dot_or_call_expr_with_(e0, lo) .map(|expr| expr.map(|mut expr| { expr.attrs.update(|a| a.prepend(attrs)); @@ -2408,9 +2419,8 @@ impl<'a> Parser<'a> { }) } - fn parse_dot_or_call_expr_with_(&mut self, e0: P) -> PResult<'a, P> { + fn parse_dot_or_call_expr_with_(&mut self, e0: P, lo: BytePos) -> PResult<'a, P> { let mut e = e0; - let lo = e.span.lo; let mut hi; loop { // expr.f @@ -3828,7 +3838,8 @@ impl<'a> Parser<'a> { let e = self.mk_mac_expr(span.lo, span.hi, mac.and_then(|m| m.node), None); - let e = try!(self.parse_dot_or_call_expr_with(e, attrs)); + let lo = e.span.lo; + let e = try!(self.parse_dot_or_call_expr_with(e, lo, attrs)); let e = try!(self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))); try!(self.handle_expression_like_statement( e, -- cgit 1.4.1-3-g733a5 From 1bde18d60c2e2a4fec149312bae6e20609b6599b Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Sun, 24 Jan 2016 22:46:39 +0100 Subject: Use interpolated token span when building spans for bigger expressions --- src/libsyntax/ext/tt/transcribe.rs | 17 +------------ src/libsyntax/parse/parser.rs | 48 ++++++++++++++++++++++-------------- src/libsyntax/parse/token.rs | 8 ++++++ src/test/compile-fail/issue-25385.rs | 2 +- src/test/compile-fail/issue-26093.rs | 2 -- src/test/compile-fail/issue-28308.rs | 4 ++- 6 files changed, 42 insertions(+), 39 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 6cf05558adb..8878c606d6a 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -10,13 +10,12 @@ use self::LockstepIterSize::*; use ast; -use ptr; use ast::{TokenTree, Ident, Name}; use codemap::{Span, DUMMY_SP}; use errors::Handler; use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal}; use parse::token::{DocComment, MatchNt, SubstNt}; -use parse::token::{Token, NtIdent, NtExpr, SpecialMacroVar}; +use parse::token::{Token, NtIdent, SpecialMacroVar}; use parse::token; use parse::lexer::TokenAndSpan; @@ -174,11 +173,6 @@ fn lockstep_iter_size(t: &TokenTree, r: &TtReader) -> LockstepIterSize { } } -fn update_span(base: Span, expr: &mut ast::Expr) { - expr.span.lo = base.lo; - expr.span.hi = base.hi; -} - /// Return the next token from the TtReader. /// EFFECT: advances the reader's token field pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan { @@ -285,7 +279,6 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan { } // FIXME #2887: think about span stuff here TokenTree::Token(sp, SubstNt(ident, namep)) => { - //println!("SubstNt {:?} {:?}", ident, sp); r.stack.last_mut().unwrap().idx += 1; match lookup_cur_matched(r, ident) { None => { @@ -304,14 +297,6 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan { r.cur_tok = token::Ident(sn.node, b); return ret_val; } - MatchedNonterminal(NtExpr(ref expr)) => { - let mut expr = (**expr).clone(); - //update_span(sp, &mut expr); - // FIXME(pcwalton): Bad copy. - r.cur_span = sp; - r.cur_tok = token::Interpolated(NtExpr(ptr::P(expr))); - return ret_val; - } MatchedNonterminal(ref other_whole_nt) => { // FIXME(pcwalton): Bad copy. r.cur_span = sp; diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index f5ebe842577..6b419002828 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -928,6 +928,7 @@ impl<'a> Parser<'a> { // Stash token for error recovery (sometimes; clone is not necessarily cheap). self.last_token = if self.token.is_ident() || self.token.is_path() || + self.token.is_interpolated() || self.token == token::Comma { Some(Box::new(self.token.clone())) } else { @@ -2322,13 +2323,9 @@ impl<'a> Parser<'a> { -> PResult<'a, P> { let attrs = try!(self.parse_or_use_outer_attributes(already_parsed_attrs)); - let interp = if let token::Interpolated(..) = self.token { - true - } else { - false - }; + let is_interpolated = self.token.is_interpolated(); let b = try!(self.parse_bottom_expr()); - let lo = if interp { + let lo = if is_interpolated { self.last_span.lo } else { b.span.lo @@ -2719,27 +2716,31 @@ impl<'a> Parser<'a> { let ex = match self.token { token::Not => { self.bump(); + let (interpolated, prev_span) = (self.token.is_interpolated(), self.span); let e = try!(self.parse_prefix_expr(None)); - hi = e.span.hi; + hi = if interpolated { prev_span.hi } else { e.span.hi }; self.mk_unary(UnNot, e) } token::BinOp(token::Minus) => { self.bump(); + let (interpolated, prev_span) = (self.token.is_interpolated(), self.span); let e = try!(self.parse_prefix_expr(None)); - hi = e.span.hi; + hi = if interpolated { prev_span.hi } else { e.span.hi }; self.mk_unary(UnNeg, e) } token::BinOp(token::Star) => { self.bump(); + let (interpolated, prev_span) = (self.token.is_interpolated(), self.span); let e = try!(self.parse_prefix_expr(None)); - hi = e.span.hi; + hi = if interpolated { prev_span.hi } else { e.span.hi }; self.mk_unary(UnDeref, e) } token::BinOp(token::And) | token::AndAnd => { try!(self.expect_and()); let m = try!(self.parse_mutability()); + let (interpolated, prev_span) = (self.token.is_interpolated(), self.span); let e = try!(self.parse_prefix_expr(None)); - hi = e.span.hi; + hi = if interpolated { prev_span.hi } else { e.span.hi }; ExprAddrOf(m, e) } token::Ident(..) if self.token.is_keyword(keywords::In) => { @@ -2757,8 +2758,9 @@ impl<'a> Parser<'a> { } token::Ident(..) if self.token.is_keyword(keywords::Box) => { self.bump(); + let (interpolated, prev_span) = (self.token.is_interpolated(), self.span); let subexpression = try!(self.parse_prefix_expr(None)); - hi = subexpression.span.hi; + hi = if interpolated { prev_span.hi } else { subexpression.span.hi }; ExprBox(subexpression) } _ => return self.parse_dot_or_call_expr(Some(attrs)) @@ -2794,12 +2796,20 @@ impl<'a> Parser<'a> { try!(self.parse_prefix_expr(attrs)) } }; + + if self.expr_is_complete(&*lhs) { // Semi-statement forms are odd. See https://github.com/rust-lang/rust/issues/29071 return Ok(lhs); } self.expected_tokens.push(TokenType::Operator); while let Some(op) = AssocOp::from_token(&self.token) { + + let lhs_span = match self.last_token { + Some(ref lt) if lt.is_interpolated() => self.last_span, + _ => lhs.span + }; + let cur_op_span = self.span; let restrictions = if op.is_assign_like() { self.restrictions & Restrictions::RESTRICTION_NO_STRUCT_LITERAL @@ -2815,13 +2825,13 @@ impl<'a> Parser<'a> { } // Special cases: if op == AssocOp::As { - let rhs = try!(self.parse_ty()); - lhs = self.mk_expr(lhs.span.lo, rhs.span.hi, + let rhs = try!(self.parse_ty()); + lhs = self.mk_expr(lhs_span.lo, rhs.span.hi, ExprCast(lhs, rhs), None); continue } else if op == AssocOp::Colon { let rhs = try!(self.parse_ty()); - lhs = self.mk_expr(lhs.span.lo, rhs.span.hi, + lhs = self.mk_expr(lhs_span.lo, rhs.span.hi, ExprType(lhs, rhs), None); continue } else if op == AssocOp::DotDot { @@ -2843,7 +2853,7 @@ impl<'a> Parser<'a> { } else { None }; - let (lhs_span, rhs_span) = (lhs.span, if let Some(ref x) = rhs { + let (lhs_span, rhs_span) = (lhs_span, if let Some(ref x) = rhs { x.span } else { cur_op_span @@ -2883,14 +2893,14 @@ impl<'a> Parser<'a> { AssocOp::Equal | AssocOp::Less | AssocOp::LessEqual | AssocOp::NotEqual | AssocOp::Greater | AssocOp::GreaterEqual => { let ast_op = op.to_ast_binop().unwrap(); - let (lhs_span, rhs_span) = (lhs.span, rhs.span); + let (lhs_span, rhs_span) = (lhs_span, rhs.span); let binary = self.mk_binary(codemap::respan(cur_op_span, ast_op), lhs, rhs); self.mk_expr(lhs_span.lo, rhs_span.hi, binary, None) } AssocOp::Assign => - self.mk_expr(lhs.span.lo, rhs.span.hi, ExprAssign(lhs, rhs), None), + self.mk_expr(lhs_span.lo, rhs.span.hi, ExprAssign(lhs, rhs), None), AssocOp::Inplace => - self.mk_expr(lhs.span.lo, rhs.span.hi, ExprInPlace(lhs, rhs), None), + self.mk_expr(lhs_span.lo, rhs.span.hi, ExprInPlace(lhs, rhs), None), AssocOp::AssignOp(k) => { let aop = match k { token::Plus => BiAdd, @@ -2904,7 +2914,7 @@ impl<'a> Parser<'a> { token::Shl => BiShl, token::Shr => BiShr }; - let (lhs_span, rhs_span) = (lhs.span, rhs.span); + let (lhs_span, rhs_span) = (lhs_span, rhs.span); let aopexpr = self.mk_assign_op(codemap::respan(cur_op_span, aop), lhs, rhs); self.mk_expr(lhs_span.lo, rhs_span.hi, aopexpr, None) } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 242626154fc..220d0aff2e3 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -223,6 +223,14 @@ impl Token { } } + /// Returns `true` if the token is interpolated. + pub fn is_interpolated(&self) -> bool { + match *self { + Interpolated(..) => true, + _ => false, + } + } + /// Returns `true` if the token is an interpolated path. pub fn is_path(&self) -> bool { match *self { diff --git a/src/test/compile-fail/issue-25385.rs b/src/test/compile-fail/issue-25385.rs index 3ee6cdedf0c..aa941bc5691 100644 --- a/src/test/compile-fail/issue-25385.rs +++ b/src/test/compile-fail/issue-25385.rs @@ -19,5 +19,5 @@ fn main() { foo!(a); foo!(1i32.foo()); - //~^ ERROR attempted access of field `i32` on type `_`, but no field with that name was found + //~^ ERROR no method named `foo` found for type `i32` in the current scope } diff --git a/src/test/compile-fail/issue-26093.rs b/src/test/compile-fail/issue-26093.rs index 6ac36707505..3489a2ca9be 100644 --- a/src/test/compile-fail/issue-26093.rs +++ b/src/test/compile-fail/issue-26093.rs @@ -16,7 +16,5 @@ macro_rules! not_an_lvalue { } fn main() { - - 0 = 42; not_an_lvalue!(99); } diff --git a/src/test/compile-fail/issue-28308.rs b/src/test/compile-fail/issue-28308.rs index 43261a97f7b..642bb0c4a10 100644 --- a/src/test/compile-fail/issue-28308.rs +++ b/src/test/compile-fail/issue-28308.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// this error is dispayed in `` +// error-pattern:cannot apply unary operator `!` to type `&'static str` + fn main() { assert!("foo"); - //~^ ERROR cannot apply unary operator `!` to type `&'static str` } -- cgit 1.4.1-3-g733a5 From 2bc8f4ff80a4343bacfcab9629eb681e576dee48 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Tue, 26 Jan 2016 11:34:32 +0100 Subject: Add interpolated_or_expr_span macro and pass lo to newly added parse_dot_suffix --- src/libsyntax/parse/parser.rs | 68 ++++++++++++++++++++---------------- src/test/compile-fail/issue-31011.rs | 2 +- 2 files changed, 39 insertions(+), 31 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 6b419002828..e00e72a72e9 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -233,6 +233,21 @@ macro_rules! maybe_whole { ) } +/// Uses $parse_expr to parse an expression and returns the span of the interpolated +/// token or the span of the parsed expression, if it was not interpolated +macro_rules! interpolated_or_expr_span { + ($p:expr, $parse_expr:expr) => { + { + let is_interpolated = $p.token.is_interpolated(); + let e = $parse_expr; + if is_interpolated { + ($p.last_span, e) + } else { + (e.span, e) + } + } + } +} fn maybe_append(mut lhs: Vec, rhs: Option>) -> Vec { @@ -2323,14 +2338,8 @@ impl<'a> Parser<'a> { -> PResult<'a, P> { let attrs = try!(self.parse_or_use_outer_attributes(already_parsed_attrs)); - let is_interpolated = self.token.is_interpolated(); - let b = try!(self.parse_bottom_expr()); - let lo = if is_interpolated { - self.last_span.lo - } else { - b.span.lo - }; - self.parse_dot_or_call_expr_with(b, lo, attrs) + let (span, b) = interpolated_or_expr_span!(self, try!(self.parse_bottom_expr())); + self.parse_dot_or_call_expr_with(b, span.lo, attrs) } pub fn parse_dot_or_call_expr_with(&mut self, @@ -2368,7 +2377,8 @@ impl<'a> Parser<'a> { fn parse_dot_suffix(&mut self, ident: Ident, ident_span: Span, - self_value: P) + self_value: P, + lo: BytePos) -> PResult<'a, P> { let (_, tys, bindings) = if self.eat(&token::ModSep) { try!(self.expect_lt()); @@ -2382,8 +2392,6 @@ impl<'a> Parser<'a> { self.span_err(last_span, "type bindings are only permitted on trait paths"); } - let lo = self_value.span.lo; - Ok(match self.token { // expr.f() method call. token::OpenDelim(token::Paren) => { @@ -2428,7 +2436,7 @@ impl<'a> Parser<'a> { hi = self.span.hi; self.bump(); - e = try!(self.parse_dot_suffix(i, mk_sp(dot_pos, hi), e)); + e = try!(self.parse_dot_suffix(i, mk_sp(dot_pos, hi), e, lo)); } token::Literal(token::Integer(n), suf) => { let sp = self.span; @@ -2481,7 +2489,7 @@ impl<'a> Parser<'a> { let dot_pos = self.last_span.hi; e = try!(self.parse_dot_suffix(special_idents::invalid, mk_sp(dot_pos, dot_pos), - e)); + e, lo)); } } continue; @@ -2716,31 +2724,31 @@ impl<'a> Parser<'a> { let ex = match self.token { token::Not => { self.bump(); - let (interpolated, prev_span) = (self.token.is_interpolated(), self.span); - let e = try!(self.parse_prefix_expr(None)); - hi = if interpolated { prev_span.hi } else { e.span.hi }; + let (span, e) = interpolated_or_expr_span!(self, + try!(self.parse_prefix_expr(None))); + hi = span.hi; self.mk_unary(UnNot, e) } token::BinOp(token::Minus) => { self.bump(); - let (interpolated, prev_span) = (self.token.is_interpolated(), self.span); - let e = try!(self.parse_prefix_expr(None)); - hi = if interpolated { prev_span.hi } else { e.span.hi }; + let (span, e) = interpolated_or_expr_span!(self, + try!(self.parse_prefix_expr(None))); + hi = span.hi; self.mk_unary(UnNeg, e) } token::BinOp(token::Star) => { self.bump(); - let (interpolated, prev_span) = (self.token.is_interpolated(), self.span); - let e = try!(self.parse_prefix_expr(None)); - hi = if interpolated { prev_span.hi } else { e.span.hi }; + let (span, e) = interpolated_or_expr_span!(self, + try!(self.parse_prefix_expr(None))); + hi = span.hi; self.mk_unary(UnDeref, e) } token::BinOp(token::And) | token::AndAnd => { try!(self.expect_and()); let m = try!(self.parse_mutability()); - let (interpolated, prev_span) = (self.token.is_interpolated(), self.span); - let e = try!(self.parse_prefix_expr(None)); - hi = if interpolated { prev_span.hi } else { e.span.hi }; + let (span, e) = interpolated_or_expr_span!(self, + try!(self.parse_prefix_expr(None))); + hi = span.hi; ExprAddrOf(m, e) } token::Ident(..) if self.token.is_keyword(keywords::In) => { @@ -2758,10 +2766,10 @@ impl<'a> Parser<'a> { } token::Ident(..) if self.token.is_keyword(keywords::Box) => { self.bump(); - let (interpolated, prev_span) = (self.token.is_interpolated(), self.span); - let subexpression = try!(self.parse_prefix_expr(None)); - hi = if interpolated { prev_span.hi } else { subexpression.span.hi }; - ExprBox(subexpression) + let (span, e) = interpolated_or_expr_span!(self, + try!(self.parse_prefix_expr(None))); + hi = span.hi; + ExprBox(e) } _ => return self.parse_dot_or_call_expr(Some(attrs)) }; @@ -2825,7 +2833,7 @@ impl<'a> Parser<'a> { } // Special cases: if op == AssocOp::As { - let rhs = try!(self.parse_ty()); + let rhs = try!(self.parse_ty()); lhs = self.mk_expr(lhs_span.lo, rhs.span.hi, ExprCast(lhs, rhs), None); continue diff --git a/src/test/compile-fail/issue-31011.rs b/src/test/compile-fail/issue-31011.rs index 87c1732b897..a55b6f13872 100644 --- a/src/test/compile-fail/issue-31011.rs +++ b/src/test/compile-fail/issue-31011.rs @@ -11,7 +11,7 @@ macro_rules! log { ( $ctx:expr, $( $args:expr),* ) => { if $ctx.trace { - //~^ attempted access of field `trace` on type `&T`, but no field with that name was found + //~^ ERROR attempted access of field `trace` on type `&T`, but no field with that name println!( $( $args, )* ); } } -- cgit 1.4.1-3-g733a5 From 9d8c64b9966a2e6fe6b022491eb3fb7bb81ec292 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Tue, 26 Jan 2016 12:49:22 +0100 Subject: Push try! to call site of interpolated_or_expr_span! --- src/libsyntax/parse/parser.rs | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index e00e72a72e9..4c818da6336 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -239,12 +239,13 @@ macro_rules! interpolated_or_expr_span { ($p:expr, $parse_expr:expr) => { { let is_interpolated = $p.token.is_interpolated(); - let e = $parse_expr; - if is_interpolated { - ($p.last_span, e) - } else { - (e.span, e) - } + $parse_expr.map(|e| { + if is_interpolated { + ($p.last_span, e) + } else { + (e.span, e) + } + }) } } } @@ -2338,7 +2339,7 @@ impl<'a> Parser<'a> { -> PResult<'a, P> { let attrs = try!(self.parse_or_use_outer_attributes(already_parsed_attrs)); - let (span, b) = interpolated_or_expr_span!(self, try!(self.parse_bottom_expr())); + let (span, b) = try!(interpolated_or_expr_span!(self, self.parse_bottom_expr())); self.parse_dot_or_call_expr_with(b, span.lo, attrs) } @@ -2724,30 +2725,30 @@ impl<'a> Parser<'a> { let ex = match self.token { token::Not => { self.bump(); - let (span, e) = interpolated_or_expr_span!(self, - try!(self.parse_prefix_expr(None))); + let (span, e) = try!(interpolated_or_expr_span!(self, + self.parse_prefix_expr(None))); hi = span.hi; self.mk_unary(UnNot, e) } token::BinOp(token::Minus) => { self.bump(); - let (span, e) = interpolated_or_expr_span!(self, - try!(self.parse_prefix_expr(None))); + let (span, e) = try!(interpolated_or_expr_span!(self, + self.parse_prefix_expr(None))); hi = span.hi; self.mk_unary(UnNeg, e) } token::BinOp(token::Star) => { self.bump(); - let (span, e) = interpolated_or_expr_span!(self, - try!(self.parse_prefix_expr(None))); + let (span, e) = try!(interpolated_or_expr_span!(self, + self.parse_prefix_expr(None))); hi = span.hi; self.mk_unary(UnDeref, e) } token::BinOp(token::And) | token::AndAnd => { try!(self.expect_and()); let m = try!(self.parse_mutability()); - let (span, e) = interpolated_or_expr_span!(self, - try!(self.parse_prefix_expr(None))); + let (span, e) = try!(interpolated_or_expr_span!(self, + self.parse_prefix_expr(None))); hi = span.hi; ExprAddrOf(m, e) } @@ -2766,8 +2767,8 @@ impl<'a> Parser<'a> { } token::Ident(..) if self.token.is_keyword(keywords::Box) => { self.bump(); - let (span, e) = interpolated_or_expr_span!(self, - try!(self.parse_prefix_expr(None))); + let (span, e) = try!(interpolated_or_expr_span!(self, + self.parse_prefix_expr(None))); hi = span.hi; ExprBox(e) } -- cgit 1.4.1-3-g733a5 From 47bfd8c93c71730628af48818dd04ed62cffee74 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Wed, 27 Jan 2016 10:47:33 +0100 Subject: Turn interpolated_or_expr_span into a function --- src/libsyntax/parse/parser.rs | 52 ++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 28 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 4c818da6336..24a71e019f0 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -233,23 +233,6 @@ macro_rules! maybe_whole { ) } -/// Uses $parse_expr to parse an expression and returns the span of the interpolated -/// token or the span of the parsed expression, if it was not interpolated -macro_rules! interpolated_or_expr_span { - ($p:expr, $parse_expr:expr) => { - { - let is_interpolated = $p.token.is_interpolated(); - $parse_expr.map(|e| { - if is_interpolated { - ($p.last_span, e) - } else { - (e.span, e) - } - }) - } - } -} - fn maybe_append(mut lhs: Vec, rhs: Option>) -> Vec { if let Some(ref attrs) = rhs { @@ -558,6 +541,18 @@ impl<'a> Parser<'a> { self.commit_stmt(&[edible], &[]) } + /// returns the span of expr, if it was not interpolated or the span of the interpolated token + fn interpolated_or_expr_span(&self, expr: PResult<'a, P>) -> PResult<'a, (Span, P)> { + let is_interpolated = self.token.is_interpolated(); + expr.map(|e| { + if is_interpolated { + (self.last_span, e) + } else { + (e.span, e) + } + }) + } + pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> { self.check_strict_keywords(); self.check_reserved_keywords(); @@ -2339,7 +2334,8 @@ impl<'a> Parser<'a> { -> PResult<'a, P> { let attrs = try!(self.parse_or_use_outer_attributes(already_parsed_attrs)); - let (span, b) = try!(interpolated_or_expr_span!(self, self.parse_bottom_expr())); + let b = self.parse_bottom_expr(); + let (span, b) = try!(self.interpolated_or_expr_span(b)); self.parse_dot_or_call_expr_with(b, span.lo, attrs) } @@ -2725,30 +2721,30 @@ impl<'a> Parser<'a> { let ex = match self.token { token::Not => { self.bump(); - let (span, e) = try!(interpolated_or_expr_span!(self, - self.parse_prefix_expr(None))); + let e = self.parse_prefix_expr(None); + let (span, e) = try!(self.interpolated_or_expr_span(e)); hi = span.hi; self.mk_unary(UnNot, e) } token::BinOp(token::Minus) => { self.bump(); - let (span, e) = try!(interpolated_or_expr_span!(self, - self.parse_prefix_expr(None))); + let e = self.parse_prefix_expr(None); + let (span, e) = try!(self.interpolated_or_expr_span(e)); hi = span.hi; self.mk_unary(UnNeg, e) } token::BinOp(token::Star) => { self.bump(); - let (span, e) = try!(interpolated_or_expr_span!(self, - self.parse_prefix_expr(None))); + let e = self.parse_prefix_expr(None); + let (span, e) = try!(self.interpolated_or_expr_span(e)); hi = span.hi; self.mk_unary(UnDeref, e) } token::BinOp(token::And) | token::AndAnd => { try!(self.expect_and()); let m = try!(self.parse_mutability()); - let (span, e) = try!(interpolated_or_expr_span!(self, - self.parse_prefix_expr(None))); + let e = self.parse_prefix_expr(None); + let (span, e) = try!(self.interpolated_or_expr_span(e)); hi = span.hi; ExprAddrOf(m, e) } @@ -2767,8 +2763,8 @@ impl<'a> Parser<'a> { } token::Ident(..) if self.token.is_keyword(keywords::Box) => { self.bump(); - let (span, e) = try!(interpolated_or_expr_span!(self, - self.parse_prefix_expr(None))); + let e = self.parse_prefix_expr(None); + let (span, e) = try!(self.interpolated_or_expr_span(e)); hi = span.hi; ExprBox(e) } -- cgit 1.4.1-3-g733a5 From e533ed91be4c39d718ad4bfa78165f77db842e49 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Wed, 27 Jan 2016 11:26:38 +0100 Subject: Avoid storing interolated token in Parser.last_token --- src/libsyntax/parse/parser.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 24a71e019f0..883a54079d8 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -254,6 +254,7 @@ pub struct Parser<'a> { pub cfg: CrateConfig, /// the previous token or None (only stashed sometimes). pub last_token: Option>, + last_token_interpolated: bool, pub buffer: [TokenAndSpan; 4], pub buffer_start: isize, pub buffer_end: isize, @@ -361,6 +362,7 @@ impl<'a> Parser<'a> { span: span, last_span: span, last_token: None, + last_token_interpolated: false, buffer: [ placeholder.clone(), placeholder.clone(), @@ -542,10 +544,11 @@ impl<'a> Parser<'a> { } /// returns the span of expr, if it was not interpolated or the span of the interpolated token - fn interpolated_or_expr_span(&self, expr: PResult<'a, P>) -> PResult<'a, (Span, P)> { - let is_interpolated = self.token.is_interpolated(); + fn interpolated_or_expr_span(&self, + expr: PResult<'a, P>) + -> PResult<'a, (Span, P)> { expr.map(|e| { - if is_interpolated { + if self.last_token_interpolated { (self.last_span, e) } else { (e.span, e) @@ -939,12 +942,12 @@ impl<'a> Parser<'a> { // Stash token for error recovery (sometimes; clone is not necessarily cheap). self.last_token = if self.token.is_ident() || self.token.is_path() || - self.token.is_interpolated() || self.token == token::Comma { Some(Box::new(self.token.clone())) } else { None }; + self.last_token_interpolated = self.token.is_interpolated(); let next = if self.buffer_start == self.buffer_end { self.reader.real_token() } else { @@ -2810,9 +2813,10 @@ impl<'a> Parser<'a> { self.expected_tokens.push(TokenType::Operator); while let Some(op) = AssocOp::from_token(&self.token) { - let lhs_span = match self.last_token { - Some(ref lt) if lt.is_interpolated() => self.last_span, - _ => lhs.span + let lhs_span = if self.last_token_interpolated { + self.last_span + } else { + lhs.span }; let cur_op_span = self.span; -- cgit 1.4.1-3-g733a5