From 2bc8f4ff80a4343bacfcab9629eb681e576dee48 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Tue, 26 Jan 2016 11:34:32 +0100 Subject: [PATCH] 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(-) 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 @@ pub fn parse_dot_or_call_expr(&mut self, -> 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 @@ pub fn parse_dot_or_call_expr_with(&mut self, 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 @@ fn parse_dot_suffix(&mut self, 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 @@ fn parse_dot_or_call_expr_with_(&mut self, e0: P, lo: BytePos) -> PResult< 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 @@ fn parse_dot_or_call_expr_with_(&mut self, e0: P, lo: BytePos) -> PResult< 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 @@ pub fn parse_prefix_expr(&mut self, 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 @@ pub fn parse_prefix_expr(&mut self, } 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 @@ pub fn parse_assoc_expr_with(&mut self, } // 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, )* ); } } -- 2.44.0