about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/comments.rs15
-rw-r--r--src/libsyntax/parse/common.rs4
-rw-r--r--src/libsyntax/parse/eval.rs6
-rw-r--r--src/libsyntax/parse/lexer.rs12
-rw-r--r--src/libsyntax/parse/obsolete.rs2
-rw-r--r--src/libsyntax/parse/parser.rs230
-rw-r--r--src/libsyntax/parse/token.rs118
7 files changed, 209 insertions, 178 deletions
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs
index 9c705cff7bb..cb8416501b3 100644
--- a/src/libsyntax/parse/comments.rs
+++ b/src/libsyntax/parse/comments.rs
@@ -1,4 +1,5 @@
 use io::println;//XXXXXXXXxxx
+use io::ReaderUtil;
 use util::interner;
 use lexer::{string_reader, bump, is_eof, nextch,
                is_whitespace, get_str_from, reader};
@@ -129,7 +130,7 @@ fn consume_non_eol_whitespace(rdr: string_reader) {
 fn push_blank_line_comment(rdr: string_reader, &comments: ~[cmnt]) {
     debug!(">>> blank-line comment");
     let v: ~[~str] = ~[];
-    vec::push(comments, {style: blank_line, lines: v, pos: rdr.chpos});
+    comments.push({style: blank_line, lines: v, pos: rdr.chpos});
 }
 
 fn consume_whitespace_counting_blank_lines(rdr: string_reader,
@@ -148,7 +149,7 @@ fn read_shebang_comment(rdr: string_reader, code_to_the_left: bool,
     debug!(">>> shebang comment");
     let p = rdr.chpos;
     debug!("<<< shebang comment");
-    vec::push(comments, {
+    comments.push({
         style: if code_to_the_left { trailing } else { isolated },
         lines: ~[read_one_line_comment(rdr)],
         pos: p
@@ -166,12 +167,12 @@ fn read_line_comments(rdr: string_reader, code_to_the_left: bool,
         if is_doc_comment(line) { // doc-comments are not put in comments
             break;
         }
-        vec::push(lines, line);
+        lines.push(line);
         consume_non_eol_whitespace(rdr);
     }
     debug!("<<< line comments");
     if !lines.is_empty() {
-        vec::push(comments, {
+        comments.push({
             style: if code_to_the_left { trailing } else { isolated },
             lines: lines,
             pos: p
@@ -197,7 +198,7 @@ fn trim_whitespace_prefix_and_push_line(&lines: ~[~str],
         } else { s1 = ~""; }
     } else { s1 = s; }
     log(debug, ~"pushing line: " + s1);
-    vec::push(lines, s1);
+    lines.push(s1);
 }
 
 fn read_block_comment(rdr: string_reader, code_to_the_left: bool,
@@ -256,7 +257,7 @@ fn read_block_comment(rdr: string_reader, code_to_the_left: bool,
         style = mixed;
     }
     debug!("<<< block comment");
-    vec::push(comments, {style: style, lines: lines, pos: p});
+    comments.push({style: style, lines: lines, pos: p});
 }
 
 fn peeking_at_comment(rdr: string_reader) -> bool {
@@ -314,7 +315,7 @@ fn gather_comments_and_literals(span_diagnostic: diagnostic::span_handler,
         let {tok: tok, sp: sp} = rdr.peek();
         if token::is_lit(tok) {
             let s = get_str_from(rdr, bstart);
-            vec::push(literals, {lit: s, pos: sp.lo});
+            literals.push({lit: s, pos: sp.lo});
             log(debug, ~"tok lit: " + s);
         } else {
             log(debug, ~"tok: " + token::to_str(rdr.interner, tok));
diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs
index 4b8bfcda848..c8c30ee7fa9 100644
--- a/src/libsyntax/parse/common.rs
+++ b/src/libsyntax/parse/common.rs
@@ -229,7 +229,7 @@ impl parser: parser_common {
               }
               _ => ()
             }
-            vec::push(v, f(self));
+            v.push(f(self));
         }
 
         return v;
@@ -274,7 +274,7 @@ impl parser: parser_common {
               _ => ()
             }
             if sep.trailing_sep_allowed && self.token == ket { break; }
-            vec::push(v, f(self));
+            v.push(f(self));
         }
         return v;
     }
diff --git a/src/libsyntax/parse/eval.rs b/src/libsyntax/parse/eval.rs
index 7127e2747eb..14dc490346e 100644
--- a/src/libsyntax/parse/eval.rs
+++ b/src/libsyntax/parse/eval.rs
@@ -107,7 +107,7 @@ fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: &Path,
         // Thread defids, chpos and byte_pos through the parsers
         cx.sess.chpos = r0.chpos;
         cx.sess.byte_pos = cx.sess.byte_pos + r0.pos;
-        vec::push(items, i);
+        items.push(i);
       }
       ast::cdir_dir_mod(vis, id, cdirs, attrs) => {
         let path = Path(cdir_path_opt(*cx.sess.interner.get(id), attrs));
@@ -126,9 +126,9 @@ fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: &Path,
               vis: vis,
               span: cdir.span};
         cx.sess.next_id += 1;
-        vec::push(items, i);
+        items.push(i);
       }
-      ast::cdir_view_item(vi) => vec::push(view_items, vi),
+      ast::cdir_view_item(vi) => view_items.push(vi),
       ast::cdir_syntax(*) => ()
     }
 }
diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs
index c9b10c7b754..06fcc1cf958 100644
--- a/src/libsyntax/parse/lexer.rs
+++ b/src/libsyntax/parse/lexer.rs
@@ -13,7 +13,7 @@ trait reader {
     fn next_token() -> {tok: token::token, sp: span};
     fn fatal(~str) -> !;
     fn span_diag() -> span_handler;
-    pure fn interner() -> token::ident_interner;
+    pure fn interner() -> @token::ident_interner;
     fn peek() -> {tok: token::token, sp: span};
     fn dup() -> reader;
 }
@@ -26,7 +26,7 @@ type string_reader = @{
     mut curr: char,
     mut chpos: uint,
     filemap: codemap::filemap,
-    interner: token::ident_interner,
+    interner: @token::ident_interner,
     /* cached: */
     mut peek_tok: token::token,
     mut peek_span: span
@@ -34,7 +34,7 @@ type string_reader = @{
 
 fn new_string_reader(span_diagnostic: span_handler,
                      filemap: codemap::filemap,
-                     itr: token::ident_interner) -> string_reader {
+                     itr: @token::ident_interner) -> string_reader {
     let r = new_low_level_string_reader(span_diagnostic, filemap, itr);
     string_advance_token(r); /* fill in peek_* */
     return r;
@@ -43,7 +43,7 @@ fn new_string_reader(span_diagnostic: span_handler,
 /* For comments.rs, which hackily pokes into 'pos' and 'curr' */
 fn new_low_level_string_reader(span_diagnostic: span_handler,
                                filemap: codemap::filemap,
-                               itr: token::ident_interner)
+                               itr: @token::ident_interner)
     -> string_reader {
     let r = @{span_diagnostic: span_diagnostic, src: filemap.src,
               mut col: 0u, mut pos: 0u, mut curr: -1 as char,
@@ -78,7 +78,7 @@ impl string_reader: reader {
         self.span_diagnostic.span_fatal(copy self.peek_span, m)
     }
     fn span_diag() -> span_handler { self.span_diagnostic }
-    pure fn interner() -> token::ident_interner { self.interner }
+    pure fn interner() -> @token::ident_interner { self.interner }
     fn peek() -> {tok: token::token, sp: span} {
         {tok: self.peek_tok, sp: self.peek_span}
     }
@@ -100,7 +100,7 @@ impl tt_reader: reader {
         self.sp_diag.span_fatal(copy self.cur_span, m);
     }
     fn span_diag() -> span_handler { self.sp_diag }
-    pure fn interner() -> token::ident_interner { self.interner }
+    pure fn interner() -> @token::ident_interner { self.interner }
     fn peek() -> {tok: token::token, sp: span} {
         { tok: self.cur_tok, sp: self.cur_span }
     }
diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
index 9cfa84ad9e0..782535f5c2b 100644
--- a/src/libsyntax/parse/obsolete.rs
+++ b/src/libsyntax/parse/obsolete.rs
@@ -36,7 +36,7 @@ impl ObsoleteSyntax : cmp::Eq {
 
 impl ObsoleteSyntax: to_bytes::IterBytes {
     #[inline(always)]
-    pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
+    pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) {
         (self as uint).iter_bytes(lsb0, f);
     }
 }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 681d6296d4e..8860d1b5cea 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -237,7 +237,7 @@ struct parser {
     mut restriction: restriction,
     mut quote_depth: uint, // not (yet) related to the quasiquoter
     reader: reader,
-    interner: interner<@~str>,
+    interner: @token::ident_interner,
     keywords: HashMap<~str, ()>,
     strict_keywords: HashMap<~str, ()>,
     reserved_keywords: HashMap<~str, ()>,
@@ -496,7 +496,7 @@ impl parser {
                 let mut ts = ~[self.parse_ty(false)];
                 while self.token == token::COMMA {
                     self.bump();
-                    vec::push(ts, self.parse_ty(false));
+                    ts.push(self.parse_ty(false));
                 }
                 let t = if vec::len(ts) == 1u { ts[0].node }
                 else { ty_tup(ts) };
@@ -584,6 +584,29 @@ impl parser {
         } else { infer(self.get_id()) }
     }
 
+    fn is_named_argument() -> bool {
+        let offset = if self.token == token::BINOP(token::AND) {
+            1
+        } else if self.token == token::BINOP(token::MINUS) {
+            1
+        } else if self.token == token::ANDAND {
+            1
+        } else if self.token == token::BINOP(token::PLUS) {
+            if self.look_ahead(1) == token::BINOP(token::PLUS) {
+                2
+            } else {
+                1
+            }
+        } else { 0 };
+        if offset == 0 {
+            is_plain_ident(self.token)
+                && self.look_ahead(1) == token::COLON
+        } else {
+            is_plain_ident(self.look_ahead(offset))
+                && self.look_ahead(offset + 1) == token::COLON
+        }
+    }
+
     fn parse_capture_item_or(parse_arg_fn: fn(parser) -> arg_or_capture_item)
         -> arg_or_capture_item {
 
@@ -605,29 +628,17 @@ impl parser {
     // This version of parse arg doesn't necessarily require
     // identifier names.
     fn parse_arg_general(require_name: bool) -> arg {
-        let m = self.parse_arg_mode();
-        let i = if require_name {
+        let mut m;
+        let i = if require_name || self.is_named_argument() {
+            m = self.parse_arg_mode();
             let name = self.parse_value_ident();
             self.expect(token::COLON);
             name
         } else {
-            if is_plain_ident(self.token)
-                && self.look_ahead(1u) == token::COLON {
-                let name = self.parse_value_ident();
-                self.bump();
-                name
-            } else { special_idents::invalid }
+            m = infer(self.get_id());
+            special_idents::invalid
         };
 
-        match m {
-            expl(_) => {
-                if i == special_idents::invalid {
-                    self.obsolete(copy self.span, ObsoleteModeInFnType);
-                }
-            }
-            _ => {}
-        }
-
         let t = self.parse_ty(false);
 
         {mode: m, ty: t, ident: i, id: self.get_id()}
@@ -760,10 +771,10 @@ impl parser {
                 && self.look_ahead(1u) == token::MOD_SEP;
 
             if is_not_last {
-                vec::push(ids, parse_ident(self));
+                ids.push(parse_ident(self));
                 self.expect(token::MOD_SEP);
             } else {
-                vec::push(ids, parse_last_ident(self));
+                ids.push(parse_last_ident(self));
                 break;
             }
         }
@@ -892,7 +903,7 @@ impl parser {
             }
             let mut es = ~[self.parse_expr()];
             while self.token == token::COMMA {
-                self.bump(); vec::push(es, self.parse_expr());
+                self.bump(); es.push(self.parse_expr());
             }
             hi = self.span.hi;
             self.expect(token::RPAREN);
@@ -1038,7 +1049,7 @@ impl parser {
                     self.bump();
                     let mut fields = ~[];
                     let mut base = None;
-                    vec::push(fields, self.parse_field(token::COLON));
+                    fields.push(self.parse_field(token::COLON));
                     while self.token != token::RBRACE {
 
                         if self.try_parse_obsolete_with() {
@@ -1056,7 +1067,7 @@ impl parser {
                             // Accept an optional trailing comma.
                             break;
                         }
-                        vec::push(fields, self.parse_field(token::COLON));
+                        fields.push(self.parse_field(token::COLON));
                     }
 
                     hi = pth.span.hi;
@@ -1305,7 +1316,7 @@ impl parser {
         while self.token != ket || lparens > 0u {
             if self.token == token::LPAREN { lparens += 1u; }
             if self.token == token::RPAREN { lparens -= 1u; }
-            vec::push(ret_val, self.parse_matcher(name_idx));
+            ret_val.push(self.parse_matcher(name_idx));
         }
 
         self.bump();
@@ -1711,7 +1722,7 @@ impl parser {
                 // record ends by an optional trailing comma
                 break;
             }
-            vec::push(fields, self.parse_field(token::COLON));
+            fields.push(self.parse_field(token::COLON));
         }
         self.expect(token::RBRACE);
         return expr_rec(fields, base);
@@ -1746,7 +1757,7 @@ impl parser {
                               rules: default_blk},
                        span: expr.span};
 
-            vec::push(arms, {pats: pats, guard: guard, body: blk});
+            arms.push({pats: pats, guard: guard, body: blk});
         }
         let mut hi = self.span.hi;
         self.bump();
@@ -1791,7 +1802,7 @@ impl parser {
     fn parse_pats() -> ~[@pat] {
         let mut pats = ~[];
         loop {
-            vec::push(pats, self.parse_pat(true));
+            pats.push(self.parse_pat(true));
             if self.token == token::BINOP(token::OR) { self.bump(); }
             else { return pats; }
         };
@@ -1838,7 +1849,7 @@ impl parser {
                     span: self.last_span
                 };
             }
-            vec::push(fields, {ident: fieldname, pat: subpat});
+            fields.push({ident: fieldname, pat: subpat});
         }
         return (fields, etc);
     }
@@ -1926,7 +1937,7 @@ impl parser {
                 let mut fields = ~[self.parse_pat(refutable)];
                 while self.token == token::COMMA {
                     self.bump();
-                    vec::push(fields, self.parse_pat(refutable));
+                    fields.push(self.parse_pat(refutable));
                 }
                 if vec::len(fields) == 1u { self.expect(token::COMMA); }
                 hi = self.span.hi;
@@ -2115,7 +2126,7 @@ impl parser {
         let lo = self.span.lo;
         let mut locals = ~[self.parse_local(is_mutbl, true)];
         while self.eat(token::COMMA) {
-            vec::push(locals, self.parse_local(is_mutbl, true));
+            locals.push(self.parse_local(is_mutbl, true));
         }
         return @spanned(lo, self.last_span.hi, decl_local(locals));
     }
@@ -2216,17 +2227,12 @@ impl parser {
         }
 
         let lo = self.span.lo;
-        if self.eat_keyword(~"unsafe") {
-            self.expect(token::LBRACE);
-            let {inner, next} = maybe_parse_inner_attrs_and_next(self,
-                                                                 parse_attrs);
-            return (inner, self.parse_block_tail_(lo, unsafe_blk, next));
-        } else {
-            self.expect(token::LBRACE);
-            let {inner, next} = maybe_parse_inner_attrs_and_next(self,
-                                                                 parse_attrs);
-            return (inner, self.parse_block_tail_(lo, default_blk, next));
-        }
+        let us = self.eat_keyword(~"unsafe");
+        self.expect(token::LBRACE);
+        let {inner, next} = maybe_parse_inner_attrs_and_next(self,
+                                                             parse_attrs);
+        let blk_check_mode = if us { unsafe_blk } else { default_blk };
+        return (inner, self.parse_block_tail_(lo, blk_check_mode, next));
     }
 
     fn parse_block_no_value() -> blk {
@@ -2255,8 +2261,8 @@ impl parser {
 
         for items.each |item| {
             let decl = @spanned(item.span.lo, item.span.hi, decl_item(*item));
-            push(stmts, @spanned(item.span.lo, item.span.hi,
-                                 stmt_decl(decl, self.get_id())));
+            stmts.push(@spanned(item.span.lo, item.span.hi,
+                                stmt_decl(decl, self.get_id())));
         }
 
         let mut initial_attrs = attrs_remaining;
@@ -2267,43 +2273,46 @@ impl parser {
 
         while self.token != token::RBRACE {
             match self.token {
-              token::SEMI => {
-                self.bump(); // empty
-              }
-              _ => {
-                let stmt = self.parse_stmt(initial_attrs);
-                initial_attrs = ~[];
-                match stmt.node {
-                  stmt_expr(e, stmt_id) => { // Expression without semicolon:
-                    match self.token {
-                      token::SEMI => {
-                        self.bump();
-                        push(stmts,
-                             @{node: stmt_semi(e, stmt_id),.. *stmt});
-                      }
-                      token::RBRACE => {
-                        expr = Some(e);
-                      }
-                      t => {
-                        if classify::stmt_ends_with_semi(*stmt) {
-                            self.fatal(~"expected `;` or `}` after \
-                                         expression but found `"
-                                       + token_to_str(self.reader, t) + ~"`");
+                token::SEMI => {
+                    self.bump(); // empty
+                }
+                _ => {
+                    let stmt = self.parse_stmt(initial_attrs);
+                    initial_attrs = ~[];
+                    match stmt.node {
+                        stmt_expr(e, stmt_id) => {
+                            // Expression without semicolon
+                            match self.token {
+                                token::SEMI => {
+                                    self.bump();
+                                    stmts.push(@{node: stmt_semi(e, stmt_id),
+                                                 ..*stmt});
+                                }
+                                token::RBRACE => {
+                                    expr = Some(e);
+                                }
+                                t => {
+                                    if classify::stmt_ends_with_semi(*stmt) {
+                                        self.fatal(
+                                            ~"expected `;` or `}` after \
+                                              expression but found `"
+                                            + token_to_str(self.reader, t)
+                                            + ~"`");
+                                    }
+                                    stmts.push(stmt);
+                                }
+                            }
                         }
-                        vec::push(stmts, stmt);
-                      }
-                    }
-                  }
 
-                  _ => { // All other kinds of statements:
-                    vec::push(stmts, stmt);
+                        _ => { // All other kinds of statements:
+                            stmts.push(stmt);
 
-                    if classify::stmt_ends_with_semi(*stmt) {
-                        self.expect(token::SEMI);
+                            if classify::stmt_ends_with_semi(*stmt) {
+                                self.expect(token::SEMI);
+                            }
+                        }
                     }
-                  }
                 }
-              }
             }
         }
         let mut hi = self.span.hi;
@@ -2345,16 +2354,16 @@ impl parser {
                     };
 
                     match maybe_bound {
-                      Some(bound) => {
-                        self.bump();
-                        push(bounds, bound);
-                      }
-                      None => {
-                        push(bounds, bound_trait(self.parse_ty(false)));
-                      }
+                        Some(bound) => {
+                            self.bump();
+                            bounds.push(bound);
+                        }
+                        None => {
+                            bounds.push(bound_trait(self.parse_ty(false)));
+                        }
                     }
                 } else {
-                    push(bounds, bound_trait(self.parse_ty(false)));
+                    bounds.push(bound_trait(self.parse_ty(false)));
                 }
             }
         }
@@ -2625,7 +2634,7 @@ impl parser {
         self.expect(token::LBRACE);
         while !self.eat(token::RBRACE) {
             let vis = self.parse_visibility();
-            vec::push(meths, self.parse_method(vis));
+            meths.push(self.parse_method(vis));
         }
         (ident, item_impl(tps, opt_trait, ty, meths), None)
     }
@@ -2711,9 +2720,9 @@ impl parser {
                     for mms.each |mm| {
                         match *mm {
                             @field_member(struct_field) =>
-                                vec::push(fields, struct_field),
+                                fields.push(struct_field),
                             @method_member(the_method_member) =>
-                                vec::push(methods, the_method_member)
+                                methods.push(the_method_member)
                         }
                     }
                   }
@@ -2744,7 +2753,7 @@ impl parser {
         }
 
         let actual_dtor = do the_dtor.map |dtor| {
-            let (d_body, d_attrs, d_s) = dtor;
+            let (d_body, d_attrs, d_s) = *dtor;
             {node: {id: self.get_id(),
                     attrs: d_attrs,
                     self_id: self.get_id(),
@@ -2885,7 +2894,7 @@ impl parser {
             debug!("parse_mod_items: parse_item_or_view_item(attrs=%?)",
                    attrs);
             match self.parse_item_or_view_item(attrs, true) {
-              iovi_item(item) => vec::push(items, item),
+              iovi_item(item) => items.push(item),
               iovi_view_item(view_item) => {
                 self.span_fatal(view_item.span, ~"view items must be \
                                                   declared at the top of the \
@@ -2926,7 +2935,8 @@ impl parser {
         (id, item_mod(m), Some(inner_attrs.inner))
     }
 
-    fn parse_item_foreign_fn(+attrs: ~[attribute]) -> @foreign_item {
+    fn parse_item_foreign_fn(vis: ast::visibility,
+                             +attrs: ~[attribute]) -> @foreign_item {
         let lo = self.span.lo;
         let purity = self.parse_fn_purity();
         let t = self.parse_fn_header();
@@ -2937,10 +2947,12 @@ impl parser {
                  attrs: attrs,
                  node: foreign_item_fn(decl, purity, t.tps),
                  id: self.get_id(),
-                 span: mk_sp(lo, hi)};
+                 span: mk_sp(lo, hi),
+                 vis: vis};
     }
 
-    fn parse_item_foreign_const(+attrs: ~[attribute]) -> @foreign_item {
+    fn parse_item_foreign_const(vis: ast::visibility,
+                                +attrs: ~[attribute]) -> @foreign_item {
         let lo = self.span.lo;
         self.expect_keyword(~"const");
         let ident = self.parse_ident();
@@ -2952,7 +2964,8 @@ impl parser {
                  attrs: attrs,
                  node: foreign_item_const(move ty),
                  id: self.get_id(),
-                 span: mk_sp(lo, hi)};
+                 span: mk_sp(lo, hi),
+                 vis: vis};
     }
 
     fn parse_fn_purity() -> purity {
@@ -2968,10 +2981,11 @@ impl parser {
     }
 
     fn parse_foreign_item(+attrs: ~[attribute]) -> @foreign_item {
+        let vis = self.parse_visibility();
         if self.is_keyword(~"const") {
-            self.parse_item_foreign_const(move attrs)
+            self.parse_item_foreign_const(vis, move attrs)
         } else {
-            self.parse_item_foreign_fn(move attrs)
+            self.parse_item_foreign_fn(vis, move attrs)
         }
     }
 
@@ -2989,7 +3003,7 @@ impl parser {
             let attrs = vec::append(initial_attrs,
                                     self.parse_outer_attributes());
             initial_attrs = ~[];
-            vec::push(items, self.parse_foreign_item(attrs));
+            items.push(self.parse_foreign_item(attrs));
         }
         return {sort: sort, view_items: view_items,
              items: items};
@@ -3102,9 +3116,9 @@ impl parser {
                     for mms.each |mm| {
                         match *mm {
                             @field_member(struct_field) =>
-                                vec::push(fields, struct_field),
+                                fields.push(struct_field),
                             @method_member(the_method_member) =>
-                                vec::push(methods, the_method_member)
+                                methods.push(the_method_member)
                         }
                     }
                 }
@@ -3112,7 +3126,7 @@ impl parser {
         }
         self.bump();
         let mut actual_dtor = do the_dtor.map |dtor| {
-            let (d_body, d_attrs, d_s) = dtor;
+            let (d_body, d_attrs, d_s) = *dtor;
             {node: {id: self.get_id(),
                     attrs: d_attrs,
                     self_id: self.get_id(),
@@ -3173,7 +3187,7 @@ impl parser {
                         seq_sep_trailing_disallowed(token::COMMA),
                         |p| p.parse_ty(false));
                     for arg_tys.each |ty| {
-                        vec::push(args, {ty: *ty, id: self.get_id()});
+                        args.push({ty: *ty, id: self.get_id()});
                     }
                     kind = tuple_variant_kind(args);
                 } else if self.eat(token::EQ) {
@@ -3189,7 +3203,7 @@ impl parser {
             let vr = {name: ident, attrs: variant_attrs,
                       kind: kind, id: self.get_id(),
                       disr_expr: disr_expr, vis: vis};
-            vec::push(variants, spanned(vlo, self.last_span.hi, vr));
+            variants.push(spanned(vlo, self.last_span.hi, vr));
 
             if needs_comma && !self.eat(token::COMMA) { break; }
         }
@@ -3416,7 +3430,7 @@ impl parser {
             while self.token == token::MOD_SEP {
                 self.bump();
                 let id = self.parse_ident();
-                vec::push(path, id);
+                path.push(id);
             }
             let path = @{span: mk_sp(lo, self.span.hi), global: false,
                          idents: path, rp: None, types: ~[]};
@@ -3434,7 +3448,7 @@ impl parser {
 
                   token::IDENT(i, _) => {
                     self.bump();
-                    vec::push(path, i);
+                    path.push(i);
                   }
 
                   // foo::bar::{a,b,c}
@@ -3477,7 +3491,7 @@ impl parser {
         let mut vp = ~[self.parse_view_path()];
         while self.token == token::COMMA {
             self.bump();
-            vec::push(vp, self.parse_view_path());
+            vp.push(self.parse_view_path());
         }
         return vp;
     }
@@ -3497,8 +3511,8 @@ impl parser {
                 self.token_is_keyword(~"mod", next_tok))
     }
 
-    fn parse_view_item(+attrs: ~[attribute]) -> @view_item {
-        let lo = self.span.lo, vis = self.parse_visibility();
+    fn parse_view_item(+attrs: ~[attribute], vis: visibility) -> @view_item {
+        let lo = self.span.lo;
         let node = if self.eat_keyword(~"use") {
             self.parse_use()
         } else if self.eat_keyword(~"export") {
@@ -3630,7 +3644,7 @@ impl parser {
               _ => self.unexpected()
             }
         } else if self.is_view_item() {
-            let vi = self.parse_view_item(outer_attrs);
+            let vi = self.parse_view_item(outer_attrs, vis);
             return spanned(lo, vi.span.hi, cdir_view_item(vi));
         }
         return self.fatal(~"expected crate directive");
@@ -3651,7 +3665,7 @@ impl parser {
         let mut first_outer_attr = first_outer_attr;
         while self.token != term {
             let cdir = @self.parse_crate_directive(first_outer_attr);
-            vec::push(cdirs, cdir);
+            cdirs.push(cdir);
             first_outer_attr = ~[];
         }
         return cdirs;
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 0f9041a2fcd..a328ff1bdf6 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -13,9 +13,6 @@ use std::serialization::{Serializer,
                             deserialize_bool};
 
 #[auto_serialize]
-type str_num = uint;
-
-#[auto_serialize]
 enum binop {
     PLUS,
     MINUS,
@@ -72,17 +69,17 @@ enum token {
     LIT_INT(i64, ast::int_ty),
     LIT_UINT(u64, ast::uint_ty),
     LIT_INT_UNSUFFIXED(i64),
-    LIT_FLOAT(str_num, ast::float_ty),
-    LIT_STR(str_num),
+    LIT_FLOAT(ast::ident, ast::float_ty),
+    LIT_STR(ast::ident),
 
     /* Name components */
-    IDENT(str_num, bool),
+    IDENT(ast::ident, bool),
     UNDERSCORE,
 
     /* For interpolation */
     INTERPOLATED(nonterminal),
 
-    DOC_COMMENT(str_num),
+    DOC_COMMENT(ast::ident),
     EOF,
 }
 
@@ -95,7 +92,7 @@ enum nonterminal {
     nt_pat( @ast::pat),
     nt_expr(@ast::expr),
     nt_ty(  @ast::ty),
-    nt_ident(str_num, bool),
+    nt_ident(ast::ident, bool),
     nt_path(@ast::path),
     nt_tt(  @ast::token_tree), //needs @ed to break a circularity
     nt_matchers(~[ast::matcher])
@@ -116,7 +113,7 @@ fn binop_to_str(o: binop) -> ~str {
     }
 }
 
-fn to_str(in: interner<@~str>, t: token) -> ~str {
+fn to_str(in: @ident_interner, t: token) -> ~str {
     match t {
       EQ => ~"=",
       LT => ~"<",
@@ -174,7 +171,7 @@ fn to_str(in: interner<@~str>, t: token) -> ~str {
         }
         body + ast_util::float_ty_to_str(t)
       }
-      LIT_STR(s) => { ~"\"" + str::escape_default( *in.get(s)) + ~"\"" }
+      LIT_STR(s) => { ~"\"" + str::escape_default(*in.get(s)) + ~"\"" }
 
       /* Name components */
       IDENT(s, _) => *in.get(s),
@@ -281,49 +278,66 @@ pure fn is_bar(t: token) -> bool {
 mod special_idents {
     #[legacy_exports];
     use ast::ident;
-    const underscore : ident = 0u;
-    const anon : ident = 1u;
-    const dtor : ident = 2u; // 'drop', but that's reserved
-    const invalid : ident = 3u; // ''
-    const unary : ident = 4u;
-    const not_fn : ident = 5u;
-    const idx_fn : ident = 6u;
-    const unary_minus_fn : ident = 7u;
-    const clownshoes_extensions : ident = 8u;
-
-    const self_ : ident = 9u; // 'self'
+    const underscore : ident = ident { repr: 0u };
+    const anon : ident = ident { repr: 1u };
+    const dtor : ident = ident { repr: 2u }; // 'drop', but that's reserved
+    const invalid : ident = ident { repr: 3u }; // ''
+    const unary : ident = ident { repr: 4u };
+    const not_fn : ident = ident { repr: 5u };
+    const idx_fn : ident = ident { repr: 6u };
+    const unary_minus_fn : ident = ident { repr: 7u };
+    const clownshoes_extensions : ident = ident { repr: 8u };
+
+    const self_ : ident = ident { repr: 9u }; // 'self'
 
     /* for matcher NTs */
-    const item : ident = 10u;
-    const block : ident = 11u;
-    const stmt : ident = 12u;
-    const pat : ident = 13u;
-    const expr : ident = 14u;
-    const ty : ident = 15u;
-    const ident : ident = 16u;
-    const path : ident = 17u;
-    const tt : ident = 18u;
-    const matchers : ident = 19u;
-
-    const str : ident = 20u; // for the type
+    const item : ident = ident { repr: 10u };
+    const block : ident = ident { repr: 11u };
+    const stmt : ident = ident { repr: 12u };
+    const pat : ident = ident { repr: 13u };
+    const expr : ident = ident { repr: 14u };
+    const ty : ident = ident { repr: 15u };
+    const ident : ident = ident { repr: 16u };
+    const path : ident = ident { repr: 17u };
+    const tt : ident = ident { repr: 18u };
+    const matchers : ident = ident { repr: 19u };
+
+    const str : ident = ident { repr: 20u }; // for the type
 
     /* outside of libsyntax */
-    const ty_visitor : ident = 21u;
-    const arg : ident = 22u;
-    const descrim : ident = 23u;
-    const clownshoe_abi : ident = 24u;
-    const clownshoe_stack_shim : ident = 25u;
-    const tydesc : ident = 26u;
-    const literally_dtor : ident = 27u;
-    const main : ident = 28u;
-    const opaque : ident = 29u;
-    const blk : ident = 30u;
-    const static : ident = 31u;
-    const intrinsic : ident = 32u;
-    const clownshoes_foreign_mod: ident = 33;
+    const ty_visitor : ident = ident { repr: 21u };
+    const arg : ident = ident { repr: 22u };
+    const descrim : ident = ident { repr: 23u };
+    const clownshoe_abi : ident = ident { repr: 24u };
+    const clownshoe_stack_shim : ident = ident { repr: 25u };
+    const tydesc : ident = ident { repr: 26u };
+    const literally_dtor : ident = ident { repr: 27u };
+    const main : ident = ident { repr: 28u };
+    const opaque : ident = ident { repr: 29u };
+    const blk : ident = ident { repr: 30u };
+    const static : ident = ident { repr: 31u };
+    const intrinsic : ident = ident { repr: 32u };
+    const clownshoes_foreign_mod: ident = ident { repr: 33 };
 }
 
-type ident_interner = util::interner::interner<@~str>;
+struct ident_interner {
+    priv interner: util::interner::interner<@~str>,
+}
+
+impl ident_interner {
+    fn intern(val: @~str) -> ast::ident {
+        ast::ident { repr: self.interner.intern(val) }
+    }
+    fn gensym(val: @~str) -> ast::ident {
+        ast::ident { repr: self.interner.gensym(val) }
+    }
+    pure fn get(idx: ast::ident) -> @~str {
+        self.interner.get(idx.repr)
+    }
+    fn len() -> uint {
+        self.interner.len()
+    }
+}
 
 /** Key for thread-local data for sneaking interner information to the
  * serializer/deserializer. It sounds like a hack because it is one.
@@ -335,7 +349,7 @@ macro_rules! interner_key (
         (-3 as uint, 0u)))
 )
 
-fn mk_ident_interner() -> ident_interner {
+fn mk_ident_interner() -> @ident_interner {
     /* the indices here must correspond to the numbers in special_idents */
     let init_vec = ~[@~"_", @~"anon", @~"drop", @~"", @~"unary", @~"!",
                      @~"[]", @~"unary-", @~"__extensions__", @~"self",
@@ -346,7 +360,9 @@ fn mk_ident_interner() -> ident_interner {
                      @~"dtor", @~"main", @~"<opaque>", @~"blk", @~"static",
                      @~"intrinsic", @~"__foreign_mod__"];
 
-    let rv = interner::mk_prefill::<@~str>(init_vec);
+    let rv = @ident_interner {
+        interner: interner::mk_prefill::<@~str>(init_vec)
+    };
 
     /* having multiple interners will just confuse the serializer */
     unsafe {
@@ -360,8 +376,8 @@ fn mk_ident_interner() -> ident_interner {
 
 /* for when we don't care about the contents; doesn't interact with TLD or
    serialization */
-fn mk_fake_ident_interner() -> ident_interner {
-    interner::mk::<@~str>()
+fn mk_fake_ident_interner() -> @ident_interner {
+    @ident_interner { interner: interner::mk::<@~str>() }
 }
 
 /**