about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorErick Tryzelaar <erick.tryzelaar@gmail.com>2013-02-27 11:03:21 -0800
committerErick Tryzelaar <erick.tryzelaar@gmail.com>2013-02-27 11:03:21 -0800
commit7d0ec86c4a382f3d937c4bf5f12ab69468d991c1 (patch)
tree8a793aa83482c45a0aaae05f1bfac087ecee0b59 /src/libsyntax/parse
parentea36a0dee1630e24ba2889ca13550026b1af4f9d (diff)
parenta6d9689399d091c3265f00434a69c551a61c28dc (diff)
downloadrust-7d0ec86c4a382f3d937c4bf5f12ab69468d991c1.tar.gz
rust-7d0ec86c4a382f3d937c4bf5f12ab69468d991c1.zip
Merge remote-tracking branch 'remotes/origin/incoming' into incoming
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/lexer.rs50
-rw-r--r--src/libsyntax/parse/mod.rs36
-rw-r--r--src/libsyntax/parse/obsolete.rs23
-rw-r--r--src/libsyntax/parse/parser.rs92
-rw-r--r--src/libsyntax/parse/token.rs4
5 files changed, 139 insertions, 66 deletions
diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs
index 54fdcc647ea..2a40b700c11 100644
--- a/src/libsyntax/parse/lexer.rs
+++ b/src/libsyntax/parse/lexer.rs
@@ -133,7 +133,7 @@ impl reader for StringReader {
     fn dup(@mut self) -> reader { dup_string_reader(self) as reader }
 }
 
-pub impl reader for TtReader {
+impl reader for TtReader {
     fn is_eof(@mut self) -> bool { self.cur_tok == token::EOF }
     fn next_token(@mut self) -> TokenAndSpan { tt_next_token(self) }
     fn fatal(@mut self, m: ~str) -> ! {
@@ -779,11 +779,13 @@ pub mod test {
     use diagnostic;
     use util::testing::{check_equal, check_equal_ptr};
 
+    // represents a testing reader (incl. both reader and interner)
     struct Env {
         interner: @token::ident_interner,
         string_reader: @mut StringReader
     }
 
+    // open a string reader for the given string
     fn setup(teststr: ~str) -> Env {
         let cm = CodeMap::new();
         let fm = cm.new_filemap(~"zebra.rs", @teststr);
@@ -818,6 +820,52 @@ pub mod test {
         check_equal (string_reader.last_pos,BytePos(29))
     }
 
+    // check that the given reader produces the desired stream
+    // of tokens (stop checking after exhausting the expected vec)
+    fn check_tokenization (env: Env, expected: ~[token::Token]) {
+        for expected.each |expected_tok| {
+            let TokenAndSpan {tok:actual_tok, sp: _} =
+                env.string_reader.next_token();
+            check_equal(&actual_tok,expected_tok);
+        }
+    }
+
+    // make the identifier by looking up the string in the interner
+    fn mk_ident (env: Env, id: ~str, is_mod_name: bool) -> token::Token {
+        token::IDENT (env.interner.intern(@id),is_mod_name)
+    }
+
+    #[test] fn doublecolonparsing () {
+        let env = setup (~"a b");
+        check_tokenization (env,
+                           ~[mk_ident (env,~"a",false),
+                             mk_ident (env,~"b",false)]);
+    }
+
+    #[test] fn dcparsing_2 () {
+        let env = setup (~"a::b");
+        check_tokenization (env,
+                           ~[mk_ident (env,~"a",true),
+                             token::MOD_SEP,
+                             mk_ident (env,~"b",false)]);
+    }
+
+    #[test] fn dcparsing_3 () {
+        let env = setup (~"a ::b");
+        check_tokenization (env,
+                           ~[mk_ident (env,~"a",false),
+                             token::MOD_SEP,
+                             mk_ident (env,~"b",false)]);
+    }
+
+    #[test] fn dcparsing_4 () {
+        let env = setup (~"a:: b");
+        check_tokenization (env,
+                           ~[mk_ident (env,~"a",true),
+                             token::MOD_SEP,
+                             mk_ident (env,~"b",false)]);
+    }
+
     #[test] fn character_a() {
         let env = setup(~"'a'");
         let TokenAndSpan {tok, sp: _} =
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index d8c3ca06d76..816e4137126 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -104,9 +104,7 @@ pub fn parse_crate_from_source_str(
         codemap::FssNone,
         source
     );
-    let r = p.parse_crate_mod(/*bad*/ copy cfg);
-    p.abort_if_errors();
-    r
+    maybe_aborted(p.parse_crate_mod(/*bad*/ copy cfg),p)
 }
 
 pub fn parse_expr_from_source_str(
@@ -122,9 +120,7 @@ pub fn parse_expr_from_source_str(
         codemap::FssNone,
         source
     );
-    let r = p.parse_expr();
-    p.abort_if_errors();
-    r
+    maybe_aborted(p.parse_expr(), p)
 }
 
 pub fn parse_item_from_source_str(
@@ -141,9 +137,7 @@ pub fn parse_item_from_source_str(
         codemap::FssNone,
         source
     );
-    let r = p.parse_item(attrs);
-    p.abort_if_errors();
-    r
+    maybe_aborted(p.parse_item(attrs),p)
 }
 
 pub fn parse_stmt_from_source_str(
@@ -160,9 +154,7 @@ pub fn parse_stmt_from_source_str(
         codemap::FssNone,
         source
     );
-    let r = p.parse_stmt(attrs);
-    p.abort_if_errors();
-    r
+    maybe_aborted(p.parse_stmt(attrs),p)
 }
 
 pub fn parse_tts_from_source_str(
@@ -179,9 +171,7 @@ pub fn parse_tts_from_source_str(
         source
     );
     *p.quote_depth += 1u;
-    let r = p.parse_all_token_trees();
-    p.abort_if_errors();
-    r
+    maybe_aborted(p.parse_all_token_trees(),p)
 }
 
 pub fn parse_from_source_str<T>(
@@ -202,8 +192,7 @@ pub fn parse_from_source_str<T>(
     if !p.reader.is_eof() {
         p.reader.fatal(~"expected end-of-string");
     }
-    p.abort_if_errors();
-    r
+    maybe_aborted(r,p)
 }
 
 pub fn next_node_id(sess: @mut ParseSess) -> node_id {
@@ -230,8 +219,8 @@ pub fn new_parser_from_source_str(
     Parser(sess, cfg, srdr as reader)
 }
 
-// Read the entire source file, return a parser
-// that draws from that string
+/// Read the entire source file, return a parser
+/// that draws from that string
 pub fn new_parser_result_from_file(
     sess: @mut ParseSess,
     +cfg: ast::crate_cfg,
@@ -252,7 +241,7 @@ pub fn new_parser_result_from_file(
     }
 }
 
-/// Create a new parser for an entire crate, handling errors as appropriate
+/// Create a new parser, handling errors as appropriate
 /// if the file doesn't exist
 pub fn new_parser_from_file(
     sess: @mut ParseSess,
@@ -297,6 +286,13 @@ pub fn new_parser_from_tts(
     Parser(sess, cfg, trdr as reader)
 }
 
+// abort if necessary
+pub fn maybe_aborted<T>(+result : T, p: Parser) -> T {
+    p.abort_if_errors();
+    result
+}
+
+
 
 #[cfg(test)]
 mod test {
diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
index 96ed81e476e..2b2f1f48034 100644
--- a/src/libsyntax/parse/obsolete.rs
+++ b/src/libsyntax/parse/obsolete.rs
@@ -48,9 +48,12 @@ pub enum ObsoleteSyntax {
     ObsoleteUnenforcedBound,
     ObsoleteImplSyntax,
     ObsoleteTraitBoundSeparator,
+    ObsoleteMutOwnedPointer,
+    ObsoleteMutVector,
+    ObsoleteTraitImplVisibility,
 }
 
-pub impl to_bytes::IterBytes for ObsoleteSyntax {
+impl to_bytes::IterBytes for ObsoleteSyntax {
     #[inline(always)]
     pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
         (*self as uint).iter_bytes(lsb0, f);
@@ -126,6 +129,24 @@ pub impl Parser {
                 "space-separated trait bounds",
                 "write `+` between trait bounds"
             ),
+            ObsoleteMutOwnedPointer => (
+                "const or mutable owned pointer",
+                "mutability inherits through `~` pointers; place the `~` box
+                 in a mutable location, like a mutable local variable or an \
+                 `@mut` box"
+            ),
+            ObsoleteMutVector => (
+                "const or mutable vector",
+                "mutability inherits through `~` pointers; place the vector \
+                 in a mutable location, like a mutable local variable or an \
+                 `@mut` box"
+            ),
+            ObsoleteTraitImplVisibility => (
+                "visibility-qualified trait implementation",
+                "`pub` or `priv` is meaningless for trait implementations, \
+                 because the `impl...for...` form defines overloads for \
+                 methods that already exist; remove the `pub` or `priv`"
+            ),
         };
 
         self.report(sp, kind, kind_str, desc);
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index dffa04ac1ca..3d4e0f9020b 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -75,7 +75,8 @@ use parse::obsolete::{ObsoleteMoveInit, ObsoleteBinaryMove};
 use parse::obsolete::{ObsoleteStructCtor, ObsoleteWith};
 use parse::obsolete::{ObsoleteSyntax, ObsoleteLowerCaseKindBounds};
 use parse::obsolete::{ObsoleteUnsafeBlock, ObsoleteImplSyntax};
-use parse::obsolete::{ObsoleteTraitBoundSeparator};
+use parse::obsolete::{ObsoleteTraitBoundSeparator, ObsoleteMutOwnedPointer};
+use parse::obsolete::{ObsoleteMutVector, ObsoleteTraitImplVisibility};
 use parse::prec::{as_prec, token_to_binop};
 use parse::token::{can_begin_expr, is_ident, is_ident_or_path};
 use parse::token::{is_plain_ident, INTERPOLATED, special_idents};
@@ -653,6 +654,9 @@ pub impl Parser {
         } else if *self.token == token::LBRACKET {
             self.expect(&token::LBRACKET);
             let mt = self.parse_mt();
+            if mt.mutbl == m_mutbl {    // `m_const` too after snapshot
+                self.obsolete(*self.last_span, ObsoleteMutVector);
+            }
 
             // Parse the `* 3` in `[ int * 3 ]`
             let t = match self.maybe_parse_fixed_vstore_with_star() {
@@ -710,6 +714,11 @@ pub impl Parser {
         // rather than boxed ptrs.  But the special casing of str/vec is not
         // reflected in the AST type.
         let mt = self.parse_mt();
+
+        if mt.mutbl != m_imm && sigil == OwnedSigil {
+            self.obsolete(*self.last_span, ObsoleteMutOwnedPointer);
+        }
+
         ctor(mt)
     }
 
@@ -781,18 +790,6 @@ pub impl Parser {
         }
     }
 
-    fn parse_capture_item_or(parse_arg_fn: fn(&Parser) -> arg_or_capture_item)
-        -> arg_or_capture_item
-    {
-        if self.eat_keyword(&~"copy") {
-            // XXX outdated syntax now that moves-based-on-type has gone in
-            self.parse_ident();
-            either::Right(())
-        } else {
-            parse_arg_fn(&self)
-        }
-    }
-
     // This version of parse arg doesn't necessarily require
     // identifier names.
     fn parse_arg_general(require_name: bool) -> arg {
@@ -821,32 +818,26 @@ pub impl Parser {
         either::Left(self.parse_arg_general(true))
     }
 
-    fn parse_arg_or_capture_item() -> arg_or_capture_item {
-        self.parse_capture_item_or(|p| p.parse_arg())
-    }
-
     fn parse_fn_block_arg() -> arg_or_capture_item {
-        do self.parse_capture_item_or |p| {
-            let m = p.parse_arg_mode();
-            let is_mutbl = self.eat_keyword(&~"mut");
-            let pat = p.parse_pat(false);
-            let t = if p.eat(&token::COLON) {
-                p.parse_ty(false)
-            } else {
-                @Ty {
-                    id: p.get_id(),
-                    node: ty_infer,
-                    span: mk_sp(p.span.lo, p.span.hi),
-                }
-            };
-            either::Left(ast::arg {
-                mode: m,
-                is_mutbl: is_mutbl,
-                ty: t,
-                pat: pat,
-                id: p.get_id()
-            })
-        }
+        let m = self.parse_arg_mode();
+        let is_mutbl = self.eat_keyword(&~"mut");
+        let pat = self.parse_pat(false);
+        let t = if self.eat(&token::COLON) {
+            self.parse_ty(false)
+        } else {
+            @Ty {
+                id: self.get_id(),
+                node: ty_infer,
+                span: mk_sp(self.span.lo, self.span.hi),
+            }
+        };
+        either::Left(ast::arg {
+            mode: m,
+            is_mutbl: is_mutbl,
+            ty: t,
+            pat: pat,
+            id: self.get_id()
+        })
     }
 
     fn maybe_parse_fixed_vstore_with_star() -> Option<uint> {
@@ -1184,6 +1175,10 @@ pub impl Parser {
         } else if *self.token == token::LBRACKET {
             self.bump();
             let mutbl = self.parse_mutability();
+            if mutbl == m_mutbl {   // `m_const` too after snapshot
+                self.obsolete(*self.last_span, ObsoleteMutVector);
+            }
+
             if *self.token == token::RBRACKET {
                 // Empty vector.
                 self.bump();
@@ -1659,6 +1654,10 @@ pub impl Parser {
           token::TILDE => {
             self.bump();
             let m = self.parse_mutability();
+            if m != m_imm {
+                self.obsolete(*self.last_span, ObsoleteMutOwnedPointer);
+            }
+
             let e = self.parse_prefix_expr();
             hi = e.span.hi;
             // HACK: turn ~[...] into a ~-evec
@@ -1794,7 +1793,7 @@ pub impl Parser {
 
         // if we want to allow fn expression argument types to be inferred in
         // the future, just have to change parse_arg to parse_fn_block_arg.
-        let decl = self.parse_fn_decl(|p| p.parse_arg_or_capture_item());
+        let decl = self.parse_fn_decl(|p| p.parse_arg());
 
         let body = self.parse_block();
 
@@ -3044,9 +3043,9 @@ pub impl Parser {
     }
 
     // Parses two variants (with the region/type params always optional):
-    //    impl<T> ~[T] : to_str { ... }
-    //    impl<T> to_str for ~[T] { ... }
-    fn parse_item_impl() -> item_info {
+    //    impl<T> Foo { ... }
+    //    impl<T> ToStr for ~[T] { ... }
+    fn parse_item_impl(visibility: ast::visibility) -> item_info {
         fn wrap_path(p: &Parser, pt: @path) -> @Ty {
             @Ty {
                 id: p.get_id(),
@@ -3095,6 +3094,12 @@ pub impl Parser {
             None
         };
 
+        // Do not allow visibility to be specified in `impl...for...`. It is
+        // meaningless.
+        if opt_trait.is_some() && visibility != ast::inherited {
+            self.obsolete(*self.span, ObsoleteTraitImplVisibility);
+        }
+
         let mut meths = ~[];
         if !self.eat(&token::SEMI) {
             self.expect(&token::LBRACE);
@@ -3993,7 +3998,8 @@ pub impl Parser {
                                           maybe_append(attrs, extra_attrs)));
         } else if items_allowed && self.eat_keyword(&~"impl") {
             // IMPL ITEM
-            let (ident, item_, extra_attrs) = self.parse_item_impl();
+            let (ident, item_, extra_attrs) =
+                self.parse_item_impl(visibility);
             return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
                                           visibility,
                                           maybe_append(attrs, extra_attrs)));
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 8b063314c9b..6d0ca2c6657 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -87,7 +87,9 @@ pub enum Token {
     LIT_STR(ast::ident),
 
     /* Name components */
-    // an identifier contains an "is_mod_name" boolean.
+    // an identifier contains an "is_mod_name" boolean,
+    // indicating whether :: follows this token with no
+    // whitespace in between.
     IDENT(ast::ident, bool),
     UNDERSCORE,
     LIFETIME(ast::ident),