Skip to content

Commit 2bc8f4f

Browse files
committed
Add interpolated_or_expr_span macro and pass lo to newly added parse_dot_suffix
1 parent 1bde18d commit 2bc8f4f

File tree

2 files changed

+39
-31
lines changed

2 files changed

+39
-31
lines changed

src/libsyntax/parse/parser.rs

+38-30
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,21 @@ macro_rules! maybe_whole {
233233
)
234234
}
235235

236+
/// Uses $parse_expr to parse an expression and returns the span of the interpolated
237+
/// token or the span of the parsed expression, if it was not interpolated
238+
macro_rules! interpolated_or_expr_span {
239+
($p:expr, $parse_expr:expr) => {
240+
{
241+
let is_interpolated = $p.token.is_interpolated();
242+
let e = $parse_expr;
243+
if is_interpolated {
244+
($p.last_span, e)
245+
} else {
246+
(e.span, e)
247+
}
248+
}
249+
}
250+
}
236251

237252
fn maybe_append(mut lhs: Vec<Attribute>, rhs: Option<Vec<Attribute>>)
238253
-> Vec<Attribute> {
@@ -2323,14 +2338,8 @@ impl<'a> Parser<'a> {
23232338
-> PResult<'a, P<Expr>> {
23242339
let attrs = try!(self.parse_or_use_outer_attributes(already_parsed_attrs));
23252340

2326-
let is_interpolated = self.token.is_interpolated();
2327-
let b = try!(self.parse_bottom_expr());
2328-
let lo = if is_interpolated {
2329-
self.last_span.lo
2330-
} else {
2331-
b.span.lo
2332-
};
2333-
self.parse_dot_or_call_expr_with(b, lo, attrs)
2341+
let (span, b) = interpolated_or_expr_span!(self, try!(self.parse_bottom_expr()));
2342+
self.parse_dot_or_call_expr_with(b, span.lo, attrs)
23342343
}
23352344

23362345
pub fn parse_dot_or_call_expr_with(&mut self,
@@ -2368,7 +2377,8 @@ impl<'a> Parser<'a> {
23682377
fn parse_dot_suffix(&mut self,
23692378
ident: Ident,
23702379
ident_span: Span,
2371-
self_value: P<Expr>)
2380+
self_value: P<Expr>,
2381+
lo: BytePos)
23722382
-> PResult<'a, P<Expr>> {
23732383
let (_, tys, bindings) = if self.eat(&token::ModSep) {
23742384
try!(self.expect_lt());
@@ -2382,8 +2392,6 @@ impl<'a> Parser<'a> {
23822392
self.span_err(last_span, "type bindings are only permitted on trait paths");
23832393
}
23842394

2385-
let lo = self_value.span.lo;
2386-
23872395
Ok(match self.token {
23882396
// expr.f() method call.
23892397
token::OpenDelim(token::Paren) => {
@@ -2428,7 +2436,7 @@ impl<'a> Parser<'a> {
24282436
hi = self.span.hi;
24292437
self.bump();
24302438

2431-
e = try!(self.parse_dot_suffix(i, mk_sp(dot_pos, hi), e));
2439+
e = try!(self.parse_dot_suffix(i, mk_sp(dot_pos, hi), e, lo));
24322440
}
24332441
token::Literal(token::Integer(n), suf) => {
24342442
let sp = self.span;
@@ -2481,7 +2489,7 @@ impl<'a> Parser<'a> {
24812489
let dot_pos = self.last_span.hi;
24822490
e = try!(self.parse_dot_suffix(special_idents::invalid,
24832491
mk_sp(dot_pos, dot_pos),
2484-
e));
2492+
e, lo));
24852493
}
24862494
}
24872495
continue;
@@ -2716,31 +2724,31 @@ impl<'a> Parser<'a> {
27162724
let ex = match self.token {
27172725
token::Not => {
27182726
self.bump();
2719-
let (interpolated, prev_span) = (self.token.is_interpolated(), self.span);
2720-
let e = try!(self.parse_prefix_expr(None));
2721-
hi = if interpolated { prev_span.hi } else { e.span.hi };
2727+
let (span, e) = interpolated_or_expr_span!(self,
2728+
try!(self.parse_prefix_expr(None)));
2729+
hi = span.hi;
27222730
self.mk_unary(UnNot, e)
27232731
}
27242732
token::BinOp(token::Minus) => {
27252733
self.bump();
2726-
let (interpolated, prev_span) = (self.token.is_interpolated(), self.span);
2727-
let e = try!(self.parse_prefix_expr(None));
2728-
hi = if interpolated { prev_span.hi } else { e.span.hi };
2734+
let (span, e) = interpolated_or_expr_span!(self,
2735+
try!(self.parse_prefix_expr(None)));
2736+
hi = span.hi;
27292737
self.mk_unary(UnNeg, e)
27302738
}
27312739
token::BinOp(token::Star) => {
27322740
self.bump();
2733-
let (interpolated, prev_span) = (self.token.is_interpolated(), self.span);
2734-
let e = try!(self.parse_prefix_expr(None));
2735-
hi = if interpolated { prev_span.hi } else { e.span.hi };
2741+
let (span, e) = interpolated_or_expr_span!(self,
2742+
try!(self.parse_prefix_expr(None)));
2743+
hi = span.hi;
27362744
self.mk_unary(UnDeref, e)
27372745
}
27382746
token::BinOp(token::And) | token::AndAnd => {
27392747
try!(self.expect_and());
27402748
let m = try!(self.parse_mutability());
2741-
let (interpolated, prev_span) = (self.token.is_interpolated(), self.span);
2742-
let e = try!(self.parse_prefix_expr(None));
2743-
hi = if interpolated { prev_span.hi } else { e.span.hi };
2749+
let (span, e) = interpolated_or_expr_span!(self,
2750+
try!(self.parse_prefix_expr(None)));
2751+
hi = span.hi;
27442752
ExprAddrOf(m, e)
27452753
}
27462754
token::Ident(..) if self.token.is_keyword(keywords::In) => {
@@ -2758,10 +2766,10 @@ impl<'a> Parser<'a> {
27582766
}
27592767
token::Ident(..) if self.token.is_keyword(keywords::Box) => {
27602768
self.bump();
2761-
let (interpolated, prev_span) = (self.token.is_interpolated(), self.span);
2762-
let subexpression = try!(self.parse_prefix_expr(None));
2763-
hi = if interpolated { prev_span.hi } else { subexpression.span.hi };
2764-
ExprBox(subexpression)
2769+
let (span, e) = interpolated_or_expr_span!(self,
2770+
try!(self.parse_prefix_expr(None)));
2771+
hi = span.hi;
2772+
ExprBox(e)
27652773
}
27662774
_ => return self.parse_dot_or_call_expr(Some(attrs))
27672775
};
@@ -2825,7 +2833,7 @@ impl<'a> Parser<'a> {
28252833
}
28262834
// Special cases:
28272835
if op == AssocOp::As {
2828-
let rhs = try!(self.parse_ty());
2836+
let rhs = try!(self.parse_ty());
28292837
lhs = self.mk_expr(lhs_span.lo, rhs.span.hi,
28302838
ExprCast(lhs, rhs), None);
28312839
continue

src/test/compile-fail/issue-31011.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
macro_rules! log {
1212
( $ctx:expr, $( $args:expr),* ) => {
1313
if $ctx.trace {
14-
//~^ attempted access of field `trace` on type `&T`, but no field with that name was found
14+
//~^ ERROR attempted access of field `trace` on type `&T`, but no field with that name
1515
println!( $( $args, )* );
1616
}
1717
}

0 commit comments

Comments
 (0)