about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlorian Hahn <flo@fhahn.com>2016-01-24 22:46:39 +0100
committerFlorian Hahn <flo@fhahn.com>2016-01-26 10:32:58 +0100
commit1bde18d60c2e2a4fec149312bae6e20609b6599b (patch)
treec09697d0cb233d611e3914df8c3107bb1384a648
parent20edb366e7d16da946c2484a8542dffb07b79837 (diff)
downloadrust-1bde18d60c2e2a4fec149312bae6e20609b6599b.tar.gz
rust-1bde18d60c2e2a4fec149312bae6e20609b6599b.zip
Use interpolated token span when building spans for bigger expressions
-rw-r--r--src/libsyntax/ext/tt/transcribe.rs17
-rw-r--r--src/libsyntax/parse/parser.rs48
-rw-r--r--src/libsyntax/parse/token.rs8
-rw-r--r--src/test/compile-fail/issue-25385.rs2
-rw-r--r--src/test/compile-fail/issue-26093.rs2
-rw-r--r--src/test/compile-fail/issue-28308.rs4
6 files changed, 42 insertions, 39 deletions
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<Expr>> {
         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 `<std macros>`
+// error-pattern:cannot apply unary operator `!` to type `&'static str`
+
 fn main() {
     assert!("foo");
-    //~^ ERROR cannot apply unary operator `!` to type `&'static str`
 }