]> git.lizzy.rs Git - rust.git/commitdiff
Parser: Fix spans of explicit self arg idents
authorPhil Dawes <pdawes@drw.com>
Wed, 15 Oct 2014 17:04:29 +0000 (18:04 +0100)
committerPhil Dawes <pdawes@drw.com>
Sat, 18 Oct 2014 15:05:26 +0000 (16:05 +0100)
src/libsyntax/parse/mod.rs
src/libsyntax/parse/parser.rs

index c4a8775a0128278f99ee064a0615f05e38729277..f4ed367b3e40a3f326aabd212d47de2b86177ffe 100644 (file)
@@ -721,7 +721,7 @@ pub fn integer_lit(s: &str, sd: &SpanHandler, sp: Span) -> ast::Lit_ {
 mod test {
     use super::*;
     use serialize::json;
-    use codemap::{Span, BytePos, Spanned, NO_EXPANSION};
+    use codemap::{Span, BytePos, Pos, Spanned, NO_EXPANSION};
     use owned_slice::OwnedSlice;
     use ast;
     use abi;
@@ -1121,6 +1121,46 @@ fn parser_done(p: Parser){
                             span: sp(0,21)})));
     }
 
+    fn get_spans_of_pat_idents(src: &str) -> Vec<Span> {
+        let item = string_to_item(src.to_string()).unwrap();
+
+        struct PatIdentVisitor {
+            spans: Vec<Span>
+        }
+        impl<'v> ::visit::Visitor<'v> for PatIdentVisitor {
+            fn visit_pat(&mut self, p: &'v ast::Pat) {
+                match p.node {
+                    ast::PatIdent(_ , ref spannedident, _) => {
+                        self.spans.push(spannedident.span.clone());
+                    }
+                    _ => {
+                        ::visit::walk_pat(self, p);
+                    }
+                }
+            }
+        }
+        let mut v = PatIdentVisitor { spans: Vec::new() };
+        ::visit::walk_item(&mut v, &*item);
+        return v.spans;
+    }
+
+    #[test] fn span_of_self_arg_pat_idents_are_correct() {
+
+        let srcs = ["impl z { fn a (&self, &myarg: int) {} }",
+                    "impl z { fn a (&mut self, &myarg: int) {} }",
+                    "impl z { fn a (&'a self, &myarg: int) {} }",
+                    "impl z { fn a (self, &myarg: int) {} }",
+                    "impl z { fn a (self: Foo, &myarg: int) {} }",
+                    ];
+
+        for &src in srcs.iter() {
+            let spans = get_spans_of_pat_idents(src);
+            let Span{lo:lo,hi:hi,..} = spans[0];
+            assert!("self" == src.slice(lo.to_uint(), hi.to_uint()),
+                    "\"{}\" != \"self\". src=\"{}\"",
+                    src.slice(lo.to_uint(), hi.to_uint()), src)
+        }
+    }
 
     #[test] fn parse_exprs () {
         // just make sure that they parse....
index 17f52bc21c539580cac2b709e1968a553f7b748f..635311bb885eb07f5f7b259d45a90f606c760a6e 100644 (file)
@@ -4164,10 +4164,16 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
         // A bit of complexity and lookahead is needed here in order to be
         // backwards compatible.
         let lo = self.span.lo;
+        let mut self_ident_lo = self.span.lo;
+        let mut self_ident_hi = self.span.hi;
+
         let mut mutbl_self = MutImmutable;
         let explicit_self = match self.token {
             token::BINOP(token::AND) => {
-                maybe_parse_borrowed_explicit_self(self)
+                let eself = maybe_parse_borrowed_explicit_self(self);
+                self_ident_lo = self.last_span.lo;
+                self_ident_hi = self.last_span.hi;
+                eself
             }
             token::TILDE => {
                 // We need to make sure it isn't a type
@@ -4239,7 +4245,7 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
             _ => SelfStatic,
         };
 
-        let explicit_self_sp = mk_sp(lo, self.span.hi);
+        let explicit_self_sp = mk_sp(self_ident_lo, self_ident_hi);
 
         // shared fall-through for the three cases below. borrowing prevents simply
         // writing this as a closure