Skip to content

Commit 1bde18d

Browse files
committed
Use interpolated token span when building spans for bigger expressions
1 parent 20edb36 commit 1bde18d

File tree

6 files changed

+42
-39
lines changed

6 files changed

+42
-39
lines changed

src/libsyntax/ext/tt/transcribe.rs

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,12 @@
1010
use self::LockstepIterSize::*;
1111

1212
use ast;
13-
use ptr;
1413
use ast::{TokenTree, Ident, Name};
1514
use codemap::{Span, DUMMY_SP};
1615
use errors::Handler;
1716
use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
1817
use parse::token::{DocComment, MatchNt, SubstNt};
19-
use parse::token::{Token, NtIdent, NtExpr, SpecialMacroVar};
18+
use parse::token::{Token, NtIdent, SpecialMacroVar};
2019
use parse::token;
2120
use parse::lexer::TokenAndSpan;
2221

@@ -174,11 +173,6 @@ fn lockstep_iter_size(t: &TokenTree, r: &TtReader) -> LockstepIterSize {
174173
}
175174
}
176175

177-
fn update_span(base: Span, expr: &mut ast::Expr) {
178-
expr.span.lo = base.lo;
179-
expr.span.hi = base.hi;
180-
}
181-
182176
/// Return the next token from the TtReader.
183177
/// EFFECT: advances the reader's token field
184178
pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
@@ -285,7 +279,6 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
285279
}
286280
// FIXME #2887: think about span stuff here
287281
TokenTree::Token(sp, SubstNt(ident, namep)) => {
288-
//println!("SubstNt {:?} {:?}", ident, sp);
289282
r.stack.last_mut().unwrap().idx += 1;
290283
match lookup_cur_matched(r, ident) {
291284
None => {
@@ -304,14 +297,6 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
304297
r.cur_tok = token::Ident(sn.node, b);
305298
return ret_val;
306299
}
307-
MatchedNonterminal(NtExpr(ref expr)) => {
308-
let mut expr = (**expr).clone();
309-
//update_span(sp, &mut expr);
310-
// FIXME(pcwalton): Bad copy.
311-
r.cur_span = sp;
312-
r.cur_tok = token::Interpolated(NtExpr(ptr::P(expr)));
313-
return ret_val;
314-
}
315300
MatchedNonterminal(ref other_whole_nt) => {
316301
// FIXME(pcwalton): Bad copy.
317302
r.cur_span = sp;

src/libsyntax/parse/parser.rs

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,7 @@ impl<'a> Parser<'a> {
928928
// Stash token for error recovery (sometimes; clone is not necessarily cheap).
929929
self.last_token = if self.token.is_ident() ||
930930
self.token.is_path() ||
931+
self.token.is_interpolated() ||
931932
self.token == token::Comma {
932933
Some(Box::new(self.token.clone()))
933934
} else {
@@ -2322,13 +2323,9 @@ impl<'a> Parser<'a> {
23222323
-> PResult<'a, P<Expr>> {
23232324
let attrs = try!(self.parse_or_use_outer_attributes(already_parsed_attrs));
23242325

2325-
let interp = if let token::Interpolated(..) = self.token {
2326-
true
2327-
} else {
2328-
false
2329-
};
2326+
let is_interpolated = self.token.is_interpolated();
23302327
let b = try!(self.parse_bottom_expr());
2331-
let lo = if interp {
2328+
let lo = if is_interpolated {
23322329
self.last_span.lo
23332330
} else {
23342331
b.span.lo
@@ -2719,27 +2716,31 @@ impl<'a> Parser<'a> {
27192716
let ex = match self.token {
27202717
token::Not => {
27212718
self.bump();
2719+
let (interpolated, prev_span) = (self.token.is_interpolated(), self.span);
27222720
let e = try!(self.parse_prefix_expr(None));
2723-
hi = e.span.hi;
2721+
hi = if interpolated { prev_span.hi } else { e.span.hi };
27242722
self.mk_unary(UnNot, e)
27252723
}
27262724
token::BinOp(token::Minus) => {
27272725
self.bump();
2726+
let (interpolated, prev_span) = (self.token.is_interpolated(), self.span);
27282727
let e = try!(self.parse_prefix_expr(None));
2729-
hi = e.span.hi;
2728+
hi = if interpolated { prev_span.hi } else { e.span.hi };
27302729
self.mk_unary(UnNeg, e)
27312730
}
27322731
token::BinOp(token::Star) => {
27332732
self.bump();
2733+
let (interpolated, prev_span) = (self.token.is_interpolated(), self.span);
27342734
let e = try!(self.parse_prefix_expr(None));
2735-
hi = e.span.hi;
2735+
hi = if interpolated { prev_span.hi } else { e.span.hi };
27362736
self.mk_unary(UnDeref, e)
27372737
}
27382738
token::BinOp(token::And) | token::AndAnd => {
27392739
try!(self.expect_and());
27402740
let m = try!(self.parse_mutability());
2741+
let (interpolated, prev_span) = (self.token.is_interpolated(), self.span);
27412742
let e = try!(self.parse_prefix_expr(None));
2742-
hi = e.span.hi;
2743+
hi = if interpolated { prev_span.hi } else { e.span.hi };
27432744
ExprAddrOf(m, e)
27442745
}
27452746
token::Ident(..) if self.token.is_keyword(keywords::In) => {
@@ -2757,8 +2758,9 @@ impl<'a> Parser<'a> {
27572758
}
27582759
token::Ident(..) if self.token.is_keyword(keywords::Box) => {
27592760
self.bump();
2761+
let (interpolated, prev_span) = (self.token.is_interpolated(), self.span);
27602762
let subexpression = try!(self.parse_prefix_expr(None));
2761-
hi = subexpression.span.hi;
2763+
hi = if interpolated { prev_span.hi } else { subexpression.span.hi };
27622764
ExprBox(subexpression)
27632765
}
27642766
_ => return self.parse_dot_or_call_expr(Some(attrs))
@@ -2794,12 +2796,20 @@ impl<'a> Parser<'a> {
27942796
try!(self.parse_prefix_expr(attrs))
27952797
}
27962798
};
2799+
2800+
27972801
if self.expr_is_complete(&*lhs) {
27982802
// Semi-statement forms are odd. See https://github.com/rust-lang/rust/issues/29071
27992803
return Ok(lhs);
28002804
}
28012805
self.expected_tokens.push(TokenType::Operator);
28022806
while let Some(op) = AssocOp::from_token(&self.token) {
2807+
2808+
let lhs_span = match self.last_token {
2809+
Some(ref lt) if lt.is_interpolated() => self.last_span,
2810+
_ => lhs.span
2811+
};
2812+
28032813
let cur_op_span = self.span;
28042814
let restrictions = if op.is_assign_like() {
28052815
self.restrictions & Restrictions::RESTRICTION_NO_STRUCT_LITERAL
@@ -2815,13 +2825,13 @@ impl<'a> Parser<'a> {
28152825
}
28162826
// Special cases:
28172827
if op == AssocOp::As {
2818-
let rhs = try!(self.parse_ty());
2819-
lhs = self.mk_expr(lhs.span.lo, rhs.span.hi,
2828+
let rhs = try!(self.parse_ty());
2829+
lhs = self.mk_expr(lhs_span.lo, rhs.span.hi,
28202830
ExprCast(lhs, rhs), None);
28212831
continue
28222832
} else if op == AssocOp::Colon {
28232833
let rhs = try!(self.parse_ty());
2824-
lhs = self.mk_expr(lhs.span.lo, rhs.span.hi,
2834+
lhs = self.mk_expr(lhs_span.lo, rhs.span.hi,
28252835
ExprType(lhs, rhs), None);
28262836
continue
28272837
} else if op == AssocOp::DotDot {
@@ -2843,7 +2853,7 @@ impl<'a> Parser<'a> {
28432853
} else {
28442854
None
28452855
};
2846-
let (lhs_span, rhs_span) = (lhs.span, if let Some(ref x) = rhs {
2856+
let (lhs_span, rhs_span) = (lhs_span, if let Some(ref x) = rhs {
28472857
x.span
28482858
} else {
28492859
cur_op_span
@@ -2883,14 +2893,14 @@ impl<'a> Parser<'a> {
28832893
AssocOp::Equal | AssocOp::Less | AssocOp::LessEqual | AssocOp::NotEqual |
28842894
AssocOp::Greater | AssocOp::GreaterEqual => {
28852895
let ast_op = op.to_ast_binop().unwrap();
2886-
let (lhs_span, rhs_span) = (lhs.span, rhs.span);
2896+
let (lhs_span, rhs_span) = (lhs_span, rhs.span);
28872897
let binary = self.mk_binary(codemap::respan(cur_op_span, ast_op), lhs, rhs);
28882898
self.mk_expr(lhs_span.lo, rhs_span.hi, binary, None)
28892899
}
28902900
AssocOp::Assign =>
2891-
self.mk_expr(lhs.span.lo, rhs.span.hi, ExprAssign(lhs, rhs), None),
2901+
self.mk_expr(lhs_span.lo, rhs.span.hi, ExprAssign(lhs, rhs), None),
28922902
AssocOp::Inplace =>
2893-
self.mk_expr(lhs.span.lo, rhs.span.hi, ExprInPlace(lhs, rhs), None),
2903+
self.mk_expr(lhs_span.lo, rhs.span.hi, ExprInPlace(lhs, rhs), None),
28942904
AssocOp::AssignOp(k) => {
28952905
let aop = match k {
28962906
token::Plus => BiAdd,
@@ -2904,7 +2914,7 @@ impl<'a> Parser<'a> {
29042914
token::Shl => BiShl,
29052915
token::Shr => BiShr
29062916
};
2907-
let (lhs_span, rhs_span) = (lhs.span, rhs.span);
2917+
let (lhs_span, rhs_span) = (lhs_span, rhs.span);
29082918
let aopexpr = self.mk_assign_op(codemap::respan(cur_op_span, aop), lhs, rhs);
29092919
self.mk_expr(lhs_span.lo, rhs_span.hi, aopexpr, None)
29102920
}

src/libsyntax/parse/token.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,14 @@ impl Token {
223223
}
224224
}
225225

226+
/// Returns `true` if the token is interpolated.
227+
pub fn is_interpolated(&self) -> bool {
228+
match *self {
229+
Interpolated(..) => true,
230+
_ => false,
231+
}
232+
}
233+
226234
/// Returns `true` if the token is an interpolated path.
227235
pub fn is_path(&self) -> bool {
228236
match *self {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,5 @@ fn main() {
1919
foo!(a);
2020

2121
foo!(1i32.foo());
22-
//~^ ERROR attempted access of field `i32` on type `_`, but no field with that name was found
22+
//~^ ERROR no method named `foo` found for type `i32` in the current scope
2323
}

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,5 @@ macro_rules! not_an_lvalue {
1616
}
1717

1818
fn main() {
19-
20-
0 = 42;
2119
not_an_lvalue!(99);
2220
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
// this error is dispayed in `<std macros>`
12+
// error-pattern:cannot apply unary operator `!` to type `&'static str`
13+
1114
fn main() {
1215
assert!("foo");
13-
//~^ ERROR cannot apply unary operator `!` to type `&'static str`
1416
}

0 commit comments

Comments
 (0)