]> git.lizzy.rs Git - rust.git/blob - src/libsyntax/parse/parser.rs
auto merge of #9525 : klutzy/rust/obsolete-span-fix, r=alexcrichton
[rust.git] / src / libsyntax / parse / parser.rs
1 // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 #[macro_escape];
12
13 use abi;
14 use abi::AbiSet;
15 use ast::{Sigil, BorrowedSigil, ManagedSigil, OwnedSigil};
16 use ast::{CallSugar, NoSugar, DoSugar};
17 use ast::{TyBareFn, TyClosure};
18 use ast::{RegionTyParamBound, TraitTyParamBound};
19 use ast::{provided, public, purity};
20 use ast::{_mod, BiAdd, arg, Arm, Attribute, BindByRef, BindInfer};
21 use ast::{BiBitAnd, BiBitOr, BiBitXor, Block};
22 use ast::{BlockCheckMode, UnBox};
23 use ast::{Crate, CrateConfig, Decl, DeclItem};
24 use ast::{DeclLocal, DefaultBlock, UnDeref, BiDiv, EMPTY_CTXT, enum_def, explicit_self};
25 use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain};
26 use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock};
27 use ast::{ExprBreak, ExprCall, ExprCast, ExprDoBody};
28 use ast::{ExprField, ExprFnBlock, ExprIf, ExprIndex};
29 use ast::{ExprLit, ExprLogLevel, ExprLoop, ExprMac};
30 use ast::{ExprMethodCall, ExprParen, ExprPath, ExprRepeat};
31 use ast::{ExprRet, ExprSelf, ExprStruct, ExprTup, ExprUnary};
32 use ast::{ExprVec, ExprVstore, ExprVstoreMutBox};
33 use ast::{ExprVstoreSlice, ExprVstoreBox};
34 use ast::{ExprVstoreMutSlice, ExprWhile, ExprForLoop, extern_fn, Field, fn_decl};
35 use ast::{ExprVstoreUniq, Onceness, Once, Many};
36 use ast::{foreign_item, foreign_item_static, foreign_item_fn, foreign_mod};
37 use ast::{Ident, impure_fn, inherited, item, item_, item_static};
38 use ast::{item_enum, item_fn, item_foreign_mod, item_impl};
39 use ast::{item_mac, item_mod, item_struct, item_trait, item_ty, lit, lit_};
40 use ast::{lit_bool, lit_float, lit_float_unsuffixed, lit_int, lit_char};
41 use ast::{lit_int_unsuffixed, lit_nil, lit_str, lit_uint, Local};
42 use ast::{MutImmutable, MutMutable, mac_, mac_invoc_tt, matcher, match_nonterminal};
43 use ast::{match_seq, match_tok, method, mt, BiMul, Mutability};
44 use ast::{named_field, UnNeg, noreturn, UnNot, Pat, PatBox, PatEnum};
45 use ast::{PatIdent, PatLit, PatRange, PatRegion, PatStruct};
46 use ast::{PatTup, PatUniq, PatWild, private};
47 use ast::{BiRem, required};
48 use ast::{ret_style, return_val, BiShl, BiShr, Stmt, StmtDecl};
49 use ast::{StmtExpr, StmtSemi, StmtMac, struct_def, struct_field};
50 use ast::{struct_variant_kind, BiSub};
51 use ast::{sty_box, sty_region, sty_static, sty_uniq, sty_value};
52 use ast::{token_tree, trait_method, trait_ref, tt_delim, tt_seq, tt_tok};
53 use ast::{tt_nonterminal, tuple_variant_kind, Ty, ty_, ty_bot, ty_box};
54 use ast::{TypeField, ty_fixed_length_vec, ty_closure, ty_bare_fn, ty_typeof};
55 use ast::{ty_infer, TypeMethod};
56 use ast::{ty_nil, TyParam, TyParamBound, ty_path, ty_ptr, ty_rptr};
57 use ast::{ty_tup, ty_u32, ty_uniq, ty_vec, UnUniq};
58 use ast::{unnamed_field, UnsafeBlock, unsafe_fn, view_item};
59 use ast::{view_item_, view_item_extern_mod, view_item_use};
60 use ast::{view_path, view_path_glob, view_path_list, view_path_simple};
61 use ast::visibility;
62 use ast;
63 use ast_util::{as_prec, operator_prec};
64 use ast_util;
65 use codemap::{Span, BytePos, Spanned, spanned, mk_sp};
66 use codemap;
67 use parse::attr::parser_attr;
68 use parse::classify;
69 use parse::common::{SeqSep, seq_sep_none};
70 use parse::common::{seq_sep_trailing_disallowed, seq_sep_trailing_allowed};
71 use parse::lexer::reader;
72 use parse::lexer::TokenAndSpan;
73 use parse::obsolete::*;
74 use parse::token::{can_begin_expr, get_ident_interner, ident_to_str, is_ident};
75 use parse::token::{is_ident_or_path};
76 use parse::token::{is_plain_ident, INTERPOLATED, keywords, special_idents};
77 use parse::token::{token_to_binop};
78 use parse::token;
79 use parse::{new_sub_parser_from_file, ParseSess};
80 use opt_vec;
81 use opt_vec::OptVec;
82
83 use std::hashmap::HashSet;
84 use std::util;
85 use std::vec;
86
87 #[deriving(Eq)]
88 enum restriction {
89     UNRESTRICTED,
90     RESTRICT_STMT_EXPR,
91     RESTRICT_NO_BAR_OP,
92     RESTRICT_NO_BAR_OR_DOUBLEBAR_OP,
93 }
94
95 type item_info = (Ident, item_, Option<~[Attribute]>);
96
97 /// How to parse a path. There are four different kinds of paths, all of which
98 /// are parsed somewhat differently.
99 #[deriving(Eq)]
100 pub enum PathParsingMode {
101     /// A path with no type parameters; e.g. `foo::bar::Baz`
102     NoTypesAllowed,
103     /// A path with a lifetime and type parameters, with no double colons
104     /// before the type parameters; e.g. `foo::bar<'self>::Baz<T>`
105     LifetimeAndTypesWithoutColons,
106     /// A path with a lifetime and type parameters with double colons before
107     /// the type parameters; e.g. `foo::bar::<'self>::Baz::<T>`
108     LifetimeAndTypesWithColons,
109     /// A path with a lifetime and type parameters with bounds before the last
110     /// set of type parameters only; e.g. `foo::bar<'self>::Baz:X+Y<T>` This
111     /// form does not use extra double colons.
112     LifetimeAndTypesAndBounds,
113 }
114
115 /// A pair of a path segment and group of type parameter bounds. (See `ast.rs`
116 /// for the definition of a path segment.)
117 struct PathSegmentAndBoundSet {
118     segment: ast::PathSegment,
119     bound_set: Option<OptVec<TyParamBound>>,
120 }
121
122 /// A path paired with optional type bounds.
123 struct PathAndBounds {
124     path: ast::Path,
125     bounds: Option<OptVec<TyParamBound>>,
126 }
127
128 pub enum item_or_view_item {
129     // Indicates a failure to parse any kind of item. The attributes are
130     // returned.
131     iovi_none(~[Attribute]),
132     iovi_item(@item),
133     iovi_foreign_item(@foreign_item),
134     iovi_view_item(view_item)
135 }
136
137 #[deriving(Eq)]
138 enum view_item_parse_mode {
139     VIEW_ITEMS_AND_ITEMS_ALLOWED,
140     FOREIGN_ITEMS_ALLOWED,
141     IMPORTS_AND_ITEMS_ALLOWED
142 }
143
144 /* The expr situation is not as complex as I thought it would be.
145 The important thing is to make sure that lookahead doesn't balk
146 at INTERPOLATED tokens */
147 macro_rules! maybe_whole_expr (
148     ($p:expr) => (
149         {
150             // This horrible convolution is brought to you by
151             // @mut, have a terrible day
152             let ret = match *($p).token {
153                 INTERPOLATED(token::nt_expr(e)) => {
154                     Some(e)
155                 }
156                 INTERPOLATED(token::nt_path(ref pt)) => {
157                     Some($p.mk_expr(
158                         ($p).span.lo,
159                         ($p).span.hi,
160                         ExprPath(/* bad */ (**pt).clone())))
161                 }
162                 _ => None
163             };
164             match ret {
165                 Some(e) => {
166                     $p.bump();
167                     return e;
168                 }
169                 None => ()
170             }
171         }
172     )
173 )
174
175 macro_rules! maybe_whole (
176     ($p:expr, $constructor:ident) => (
177         {
178             let __found__ = match *($p).token {
179                 INTERPOLATED(token::$constructor(_)) => {
180                     Some(($p).bump_and_get())
181                 }
182                 _ => None
183             };
184             match __found__ {
185                 Some(INTERPOLATED(token::$constructor(x))) => {
186                     return x.clone()
187                 }
188                 _ => {}
189             }
190         }
191     );
192     (deref $p:expr, $constructor:ident) => (
193         {
194             let __found__ = match *($p).token {
195                 INTERPOLATED(token::$constructor(_)) => {
196                     Some(($p).bump_and_get())
197                 }
198                 _ => None
199             };
200             match __found__ {
201                 Some(INTERPOLATED(token::$constructor(x))) => {
202                     return (*x).clone()
203                 }
204                 _ => {}
205             }
206         }
207     );
208     (Some $p:expr, $constructor:ident) => (
209         {
210             let __found__ = match *($p).token {
211                 INTERPOLATED(token::$constructor(_)) => {
212                     Some(($p).bump_and_get())
213                 }
214                 _ => None
215             };
216             match __found__ {
217                 Some(INTERPOLATED(token::$constructor(x))) => {
218                     return Some(x.clone()),
219                 }
220                 _ => {}
221             }
222         }
223     );
224     (iovi $p:expr, $constructor:ident) => (
225         {
226             let __found__ = match *($p).token {
227                 INTERPOLATED(token::$constructor(_)) => {
228                     Some(($p).bump_and_get())
229                 }
230                 _ => None
231             };
232             match __found__ {
233                 Some(INTERPOLATED(token::$constructor(x))) => {
234                     return iovi_item(x.clone())
235                 }
236                 _ => {}
237             }
238         }
239     );
240     (pair_empty $p:expr, $constructor:ident) => (
241         {
242             let __found__ = match *($p).token {
243                 INTERPOLATED(token::$constructor(_)) => {
244                     Some(($p).bump_and_get())
245                 }
246                 _ => None
247             };
248             match __found__ {
249                 Some(INTERPOLATED(token::$constructor(ref x))) => {
250                     return (~[], (**x).clone())
251                 }
252                 _ => {}
253             }
254         }
255     )
256 )
257
258
259 fn maybe_append(lhs: ~[Attribute], rhs: Option<~[Attribute]>)
260              -> ~[Attribute] {
261     match rhs {
262         None => lhs,
263         Some(ref attrs) => vec::append(lhs, (*attrs))
264     }
265 }
266
267
268 struct ParsedItemsAndViewItems {
269     attrs_remaining: ~[Attribute],
270     view_items: ~[view_item],
271     items: ~[@item],
272     foreign_items: ~[@foreign_item]
273 }
274
275 /* ident is handled by common.rs */
276
277 pub fn Parser(sess: @mut ParseSess,
278               cfg: ast::CrateConfig,
279               rdr: @mut reader)
280            -> Parser {
281     let tok0 = rdr.next_token();
282     let interner = get_ident_interner();
283     let span = tok0.sp;
284     let placeholder = TokenAndSpan {
285         tok: token::UNDERSCORE,
286         sp: span,
287     };
288
289     Parser {
290         reader: rdr,
291         interner: interner,
292         sess: sess,
293         cfg: cfg,
294         token: @mut tok0.tok,
295         span: @mut span,
296         last_span: @mut span,
297         last_token: @mut None,
298         buffer: @mut ([
299             placeholder.clone(),
300             placeholder.clone(),
301             placeholder.clone(),
302             placeholder.clone(),
303         ]),
304         buffer_start: @mut 0,
305         buffer_end: @mut 0,
306         tokens_consumed: @mut 0,
307         restriction: @mut UNRESTRICTED,
308         quote_depth: @mut 0,
309         obsolete_set: @mut HashSet::new(),
310         mod_path_stack: @mut ~[],
311     }
312 }
313
314 // ooh, nasty mutable fields everywhere....
315 pub struct Parser {
316     sess: @mut ParseSess,
317     cfg: CrateConfig,
318     // the current token:
319     token: @mut token::Token,
320     // the span of the current token:
321     span: @mut Span,
322     // the span of the prior token:
323     last_span: @mut Span,
324     // the previous token or None (only stashed sometimes).
325     last_token: @mut Option<~token::Token>,
326     buffer: @mut [TokenAndSpan, ..4],
327     buffer_start: @mut int,
328     buffer_end: @mut int,
329     tokens_consumed: @mut uint,
330     restriction: @mut restriction,
331     quote_depth: @mut uint, // not (yet) related to the quasiquoter
332     reader: @mut reader,
333     interner: @token::ident_interner,
334     /// The set of seen errors about obsolete syntax. Used to suppress
335     /// extra detail when the same error is seen twice
336     obsolete_set: @mut HashSet<ObsoleteSyntax>,
337     /// Used to determine the path to externally loaded source files
338     mod_path_stack: @mut ~[@str],
339 }
340
341 #[unsafe_destructor]
342 impl Drop for Parser {
343     /* do not copy the parser; its state is tied to outside state */
344     fn drop(&mut self) {}
345 }
346
347 fn is_plain_ident_or_underscore(t: &token::Token) -> bool {
348     is_plain_ident(t) || *t == token::UNDERSCORE
349 }
350
351 impl Parser {
352     // convert a token to a string using self's reader
353     pub fn token_to_str(&self, token: &token::Token) -> ~str {
354         token::to_str(get_ident_interner(), token)
355     }
356
357     // convert the current token to a string using self's reader
358     pub fn this_token_to_str(&self) -> ~str {
359         self.token_to_str(self.token)
360     }
361
362     pub fn unexpected_last(&self, t: &token::Token) -> ! {
363         self.span_fatal(
364             *self.last_span,
365             fmt!(
366                 "unexpected token: `%s`",
367                 self.token_to_str(t)
368             )
369         );
370     }
371
372     pub fn unexpected(&self) -> ! {
373         self.fatal(
374             fmt!(
375                 "unexpected token: `%s`",
376                 self.this_token_to_str()
377             )
378         );
379     }
380
381     // expect and consume the token t. Signal an error if
382     // the next token is not t.
383     pub fn expect(&self, t: &token::Token) {
384         if *self.token == *t {
385             self.bump();
386         } else {
387             self.fatal(
388                 fmt!(
389                     "expected `%s` but found `%s`",
390                     self.token_to_str(t),
391                     self.this_token_to_str()
392                 )
393             )
394         }
395     }
396
397     // Expect next token to be edible or inedible token.  If edible,
398     // then consume it; if inedible, then return without consuming
399     // anything.  Signal a fatal error if next token is unexpected.
400     pub fn expect_one_of(&self, edible: &[token::Token], inedible: &[token::Token]) {
401         fn tokens_to_str(p:&Parser, tokens: &[token::Token]) -> ~str {
402             let mut i = tokens.iter();
403             // This might be a sign we need a connect method on Iterator.
404             let b = i.next().map_default(~"", |t| p.token_to_str(*t));
405             i.fold(b, |b,a| b + " " + p.token_to_str(a))
406         }
407         if edible.contains(self.token) {
408             self.bump();
409         } else if inedible.contains(self.token) {
410             // leave it in the input
411         } else {
412             let expected = vec::append(edible.to_owned(), inedible);
413             let expect = tokens_to_str(self, expected);
414             let actual = self.this_token_to_str();
415             self.fatal(
416                 if expected.len() != 1 {
417                     fmt!("expected one of `%s` but found `%s`", expect, actual)
418                 } else {
419                     fmt!("expected `%s` but found `%s`", expect, actual)
420                 }
421             )
422         }
423     }
424
425     // Check for erroneous `ident { }`; if matches, signal error and
426     // recover (without consuming any expected input token).  Returns
427     // true if and only if input was consumed for recovery.
428     pub fn check_for_erroneous_unit_struct_expecting(&self, expected: &[token::Token]) -> bool {
429         if *self.token == token::LBRACE
430             && expected.iter().all(|t| *t != token::LBRACE)
431             && self.look_ahead(1, |t| *t == token::RBRACE) {
432             // matched; signal non-fatal error and recover.
433             self.span_err(*self.span,
434                           "Unit-like struct construction is written with no trailing `{ }`");
435             self.eat(&token::LBRACE);
436             self.eat(&token::RBRACE);
437             true
438         } else {
439             false
440         }
441     }
442
443     // Commit to parsing a complete expression `e` expected to be
444     // followed by some token from the set edible + inedible.  Recover
445     // from anticipated input errors, discarding erroneous characters.
446     pub fn commit_expr(&self, e: @Expr, edible: &[token::Token], inedible: &[token::Token]) {
447         debug!("commit_expr %?", e);
448         match e.node {
449             ExprPath(*) => {
450                 // might be unit-struct construction; check for recoverableinput error.
451                 let expected = vec::append(edible.to_owned(), inedible);
452                 self.check_for_erroneous_unit_struct_expecting(expected);
453             }
454             _ => {}
455         }
456         self.expect_one_of(edible, inedible)
457     }
458
459     pub fn commit_expr_expecting(&self, e: @Expr, edible: token::Token) {
460         self.commit_expr(e, &[edible], &[])
461     }
462
463     // Commit to parsing a complete statement `s`, which expects to be
464     // followed by some token from the set edible + inedible.  Check
465     // for recoverable input errors, discarding erroneous characters.
466     pub fn commit_stmt(&self, s: @Stmt, edible: &[token::Token], inedible: &[token::Token]) {
467         debug!("commit_stmt %?", s);
468         let _s = s; // unused, but future checks might want to inspect `s`.
469         if self.last_token.map_default(false, |t|is_ident_or_path(*t)) {
470             let expected = vec::append(edible.to_owned(), inedible);
471             self.check_for_erroneous_unit_struct_expecting(expected);
472         }
473         self.expect_one_of(edible, inedible)
474     }
475
476     pub fn commit_stmt_expecting(&self, s: @Stmt, edible: token::Token) {
477         self.commit_stmt(s, &[edible], &[])
478     }
479
480     pub fn parse_ident(&self) -> ast::Ident {
481         self.check_strict_keywords();
482         self.check_reserved_keywords();
483         match *self.token {
484             token::IDENT(i, _) => {
485                 self.bump();
486                 i
487             }
488             token::INTERPOLATED(token::nt_ident(*)) => {
489                 self.bug("ident interpolation not converted to real token");
490             }
491             _ => {
492                 self.fatal(
493                     fmt!(
494                         "expected ident, found `%s`",
495                         self.this_token_to_str()
496                     )
497                 );
498             }
499         }
500     }
501
502     pub fn parse_path_list_ident(&self) -> ast::path_list_ident {
503         let lo = self.span.lo;
504         let ident = self.parse_ident();
505         let hi = self.last_span.hi;
506         spanned(lo, hi, ast::path_list_ident_ { name: ident,
507                                                 id: ast::DUMMY_NODE_ID })
508     }
509
510     // consume token 'tok' if it exists. Returns true if the given
511     // token was present, false otherwise.
512     pub fn eat(&self, tok: &token::Token) -> bool {
513         let is_present = *self.token == *tok;
514         if is_present { self.bump() }
515         is_present
516     }
517
518     pub fn is_keyword(&self, kw: keywords::Keyword) -> bool {
519         token::is_keyword(kw, self.token)
520     }
521
522     // if the next token is the given keyword, eat it and return
523     // true. Otherwise, return false.
524     pub fn eat_keyword(&self, kw: keywords::Keyword) -> bool {
525         let is_kw = match *self.token {
526             token::IDENT(sid, false) => kw.to_ident().name == sid.name,
527             _ => false
528         };
529         if is_kw { self.bump() }
530         is_kw
531     }
532
533     // if the given word is not a keyword, signal an error.
534     // if the next token is not the given word, signal an error.
535     // otherwise, eat it.
536     pub fn expect_keyword(&self, kw: keywords::Keyword) {
537         if !self.eat_keyword(kw) {
538             self.fatal(
539                 fmt!(
540                     "expected `%s`, found `%s`",
541                     self.id_to_str(kw.to_ident()).to_str(),
542                     self.this_token_to_str()
543                 )
544             );
545         }
546     }
547
548     // signal an error if the given string is a strict keyword
549     pub fn check_strict_keywords(&self) {
550         if token::is_strict_keyword(self.token) {
551             self.span_err(*self.last_span,
552                           fmt!("found `%s` in ident position", self.this_token_to_str()));
553         }
554     }
555
556     // signal an error if the current token is a reserved keyword
557     pub fn check_reserved_keywords(&self) {
558         if token::is_reserved_keyword(self.token) {
559             self.fatal(fmt!("`%s` is a reserved keyword", self.this_token_to_str()));
560         }
561     }
562
563     // expect and consume a GT. if a >> is seen, replace it
564     // with a single > and continue. If a GT is not seen,
565     // signal an error.
566     pub fn expect_gt(&self) {
567         match *self.token {
568             token::GT => self.bump(),
569             token::BINOP(token::SHR) => self.replace_token(
570                 token::GT,
571                 self.span.lo + BytePos(1u),
572                 self.span.hi
573             ),
574             _ => self.fatal(fmt!("expected `%s`, found `%s`",
575                                  self.token_to_str(&token::GT),
576                                  self.this_token_to_str()))
577         }
578     }
579
580     // parse a sequence bracketed by '<' and '>', stopping
581     // before the '>'.
582     pub fn parse_seq_to_before_gt<T>(&self,
583                                      sep: Option<token::Token>,
584                                      f: &fn(&Parser) -> T)
585                                      -> OptVec<T> {
586         let mut first = true;
587         let mut v = opt_vec::Empty;
588         while *self.token != token::GT
589             && *self.token != token::BINOP(token::SHR) {
590             match sep {
591               Some(ref t) => {
592                 if first { first = false; }
593                 else { self.expect(t); }
594               }
595               _ => ()
596             }
597             v.push(f(self));
598         }
599         return v;
600     }
601
602     pub fn parse_seq_to_gt<T>(&self,
603                               sep: Option<token::Token>,
604                               f: &fn(&Parser) -> T)
605                               -> OptVec<T> {
606         let v = self.parse_seq_to_before_gt(sep, f);
607         self.expect_gt();
608         return v;
609     }
610
611     // parse a sequence, including the closing delimiter. The function
612     // f must consume tokens until reaching the next separator or
613     // closing bracket.
614     pub fn parse_seq_to_end<T>(&self,
615                                ket: &token::Token,
616                                sep: SeqSep,
617                                f: &fn(&Parser) -> T)
618                                -> ~[T] {
619         let val = self.parse_seq_to_before_end(ket, sep, f);
620         self.bump();
621         val
622     }
623
624     // parse a sequence, not including the closing delimiter. The function
625     // f must consume tokens until reaching the next separator or
626     // closing bracket.
627     pub fn parse_seq_to_before_end<T>(&self,
628                                       ket: &token::Token,
629                                       sep: SeqSep,
630                                       f: &fn(&Parser) -> T)
631                                       -> ~[T] {
632         let mut first: bool = true;
633         let mut v: ~[T] = ~[];
634         while *self.token != *ket {
635             match sep.sep {
636               Some(ref t) => {
637                 if first { first = false; }
638                 else { self.expect(t); }
639               }
640               _ => ()
641             }
642             if sep.trailing_sep_allowed && *self.token == *ket { break; }
643             v.push(f(self));
644         }
645         return v;
646     }
647
648     // parse a sequence, including the closing delimiter. The function
649     // f must consume tokens until reaching the next separator or
650     // closing bracket.
651     pub fn parse_unspanned_seq<T>(&self,
652                                   bra: &token::Token,
653                                   ket: &token::Token,
654                                   sep: SeqSep,
655                                   f: &fn(&Parser) -> T)
656                                   -> ~[T] {
657         self.expect(bra);
658         let result = self.parse_seq_to_before_end(ket, sep, f);
659         self.bump();
660         result
661     }
662
663     // NB: Do not use this function unless you actually plan to place the
664     // spanned list in the AST.
665     pub fn parse_seq<T>(&self,
666                         bra: &token::Token,
667                         ket: &token::Token,
668                         sep: SeqSep,
669                         f: &fn(&Parser) -> T)
670                         -> Spanned<~[T]> {
671         let lo = self.span.lo;
672         self.expect(bra);
673         let result = self.parse_seq_to_before_end(ket, sep, f);
674         let hi = self.span.hi;
675         self.bump();
676         spanned(lo, hi, result)
677     }
678
679     // advance the parser by one token
680     pub fn bump(&self) {
681         *self.last_span = *self.span;
682         // Stash token for error recovery (sometimes; clone is not necessarily cheap).
683         *self.last_token = if is_ident_or_path(self.token) {
684             Some(~(*self.token).clone())
685         } else {
686             None
687         };
688         let next = if *self.buffer_start == *self.buffer_end {
689             self.reader.next_token()
690         } else {
691             // Avoid token copies with `util::replace`.
692             let buffer_start = *self.buffer_start as uint;
693             let next_index = (buffer_start + 1) & 3 as uint;
694             *self.buffer_start = next_index as int;
695
696             let placeholder = TokenAndSpan {
697                 tok: token::UNDERSCORE,
698                 sp: *self.span,
699             };
700             util::replace(&mut self.buffer[buffer_start], placeholder)
701         };
702         *self.span = next.sp;
703         *self.token = next.tok;
704         *self.tokens_consumed += 1u;
705     }
706
707     // Advance the parser by one token and return the bumped token.
708     pub fn bump_and_get(&self) -> token::Token {
709         let old_token = util::replace(self.token, token::UNDERSCORE);
710         self.bump();
711         old_token
712     }
713
714     // EFFECT: replace the current token and span with the given one
715     pub fn replace_token(&self,
716                          next: token::Token,
717                          lo: BytePos,
718                          hi: BytePos) {
719         *self.token = next;
720         *self.span = mk_sp(lo, hi);
721     }
722     pub fn buffer_length(&self) -> int {
723         if *self.buffer_start <= *self.buffer_end {
724             return *self.buffer_end - *self.buffer_start;
725         }
726         return (4 - *self.buffer_start) + *self.buffer_end;
727     }
728     pub fn look_ahead<R>(&self, distance: uint, f: &fn(&token::Token) -> R)
729                          -> R {
730         let dist = distance as int;
731         while self.buffer_length() < dist {
732             self.buffer[*self.buffer_end] = self.reader.next_token();
733             *self.buffer_end = (*self.buffer_end + 1) & 3;
734         }
735         f(&self.buffer[(*self.buffer_start + dist - 1) & 3].tok)
736     }
737     pub fn fatal(&self, m: &str) -> ! {
738         self.sess.span_diagnostic.span_fatal(*self.span, m)
739     }
740     pub fn span_fatal(&self, sp: Span, m: &str) -> ! {
741         self.sess.span_diagnostic.span_fatal(sp, m)
742     }
743     pub fn span_note(&self, sp: Span, m: &str) {
744         self.sess.span_diagnostic.span_note(sp, m)
745     }
746     pub fn bug(&self, m: &str) -> ! {
747         self.sess.span_diagnostic.span_bug(*self.span, m)
748     }
749     pub fn warn(&self, m: &str) {
750         self.sess.span_diagnostic.span_warn(*self.span, m)
751     }
752     pub fn span_err(&self, sp: Span, m: &str) {
753         self.sess.span_diagnostic.span_err(sp, m)
754     }
755     pub fn abort_if_errors(&self) {
756         self.sess.span_diagnostic.handler().abort_if_errors();
757     }
758
759     pub fn id_to_str(&self, id: Ident) -> @str {
760         get_ident_interner().get(id.name)
761     }
762
763     // is this one of the keywords that signals a closure type?
764     pub fn token_is_closure_keyword(&self, tok: &token::Token) -> bool {
765         token::is_keyword(keywords::Pure, tok) ||
766             token::is_keyword(keywords::Unsafe, tok) ||
767             token::is_keyword(keywords::Once, tok) ||
768             token::is_keyword(keywords::Fn, tok)
769     }
770
771     pub fn token_is_lifetime(&self, tok: &token::Token) -> bool {
772         match *tok {
773             token::LIFETIME(*) => true,
774             _ => false,
775         }
776     }
777
778     pub fn get_lifetime(&self, tok: &token::Token) -> ast::Ident {
779         match *tok {
780             token::LIFETIME(ref ident) => *ident,
781             _ => self.bug("not a lifetime"),
782         }
783     }
784
785     // parse a ty_bare_fun type:
786     pub fn parse_ty_bare_fn(&self) -> ty_ {
787         /*
788
789         extern "ABI" [pure|unsafe] fn <'lt> (S) -> T
790                ^~~~^ ^~~~~~~~~~~~^    ^~~~^ ^~^    ^
791                  |     |                |    |     |
792                  |     |                |    |   Return type
793                  |     |                |  Argument types
794                  |     |            Lifetimes
795                  |     |
796                  |   Purity
797                 ABI
798
799         */
800
801         let opt_abis = self.parse_opt_abis();
802         let abis = opt_abis.unwrap_or(AbiSet::Rust());
803         let purity = self.parse_unsafety();
804         self.expect_keyword(keywords::Fn);
805         let (decl, lifetimes) = self.parse_ty_fn_decl();
806         return ty_bare_fn(@TyBareFn {
807             abis: abis,
808             purity: purity,
809             lifetimes: lifetimes,
810             decl: decl
811         });
812     }
813
814     // parse a ty_closure type
815     pub fn parse_ty_closure(&self,
816                             sigil: ast::Sigil,
817                             region: Option<ast::Lifetime>)
818                             -> ty_ {
819         /*
820
821         (&|~|@) ['r] [pure|unsafe] [once] fn [:Bounds] <'lt> (S) -> T
822         ^~~~~~^ ^~~^ ^~~~~~~~~~~~^ ^~~~~^    ^~~~~~~~^ ^~~~^ ^~^    ^
823            |     |     |             |           |       |    |     |
824            |     |     |             |           |       |    |   Return type
825            |     |     |             |           |       |  Argument types
826            |     |     |             |           |   Lifetimes
827            |     |     |             |       Closure bounds
828            |     |     |          Once-ness (a.k.a., affine)
829            |     |   Purity
830            | Lifetime bound
831         Allocation type
832
833         */
834
835         // At this point, the allocation type and lifetime bound have been
836         // parsed.
837
838         let purity = self.parse_unsafety();
839         let onceness = parse_onceness(self);
840         self.expect_keyword(keywords::Fn);
841         let bounds = self.parse_optional_ty_param_bounds();
842
843         if self.parse_fn_ty_sigil().is_some() {
844             self.obsolete(*self.span, ObsoletePostFnTySigil);
845         }
846
847         let (decl, lifetimes) = self.parse_ty_fn_decl();
848
849         return ty_closure(@TyClosure {
850             sigil: sigil,
851             region: region,
852             purity: purity,
853             onceness: onceness,
854             bounds: bounds,
855             decl: decl,
856             lifetimes: lifetimes,
857         });
858
859         fn parse_onceness(this: &Parser) -> Onceness {
860             if this.eat_keyword(keywords::Once) {
861                 Once
862             } else {
863                 Many
864             }
865         }
866     }
867
868     // looks like this should be called parse_unsafety
869     pub fn parse_unsafety(&self) -> purity {
870         if self.eat_keyword(keywords::Pure) {
871             self.obsolete(*self.last_span, ObsoletePurity);
872             return impure_fn;
873         } else if self.eat_keyword(keywords::Unsafe) {
874             return unsafe_fn;
875         } else {
876             return impure_fn;
877         }
878     }
879
880     // parse a function type (following the 'fn')
881     pub fn parse_ty_fn_decl(&self) -> (fn_decl, OptVec<ast::Lifetime>) {
882         /*
883
884         (fn) <'lt> (S) -> T
885              ^~~~^ ^~^    ^
886                |    |     |
887                |    |   Return type
888                |  Argument types
889            Lifetimes
890
891         */
892         let lifetimes = if self.eat(&token::LT) {
893             let lifetimes = self.parse_lifetimes();
894             self.expect_gt();
895             lifetimes
896         } else {
897             opt_vec::Empty
898         };
899
900         let inputs = self.parse_unspanned_seq(
901             &token::LPAREN,
902             &token::RPAREN,
903             seq_sep_trailing_disallowed(token::COMMA),
904             |p| p.parse_arg_general(false)
905         );
906         let (ret_style, ret_ty) = self.parse_ret_ty();
907         let decl = ast::fn_decl {
908             inputs: inputs,
909             output: ret_ty,
910             cf: ret_style
911         };
912         (decl, lifetimes)
913     }
914
915     // parse the methods in a trait declaration
916     pub fn parse_trait_methods(&self) -> ~[trait_method] {
917         do self.parse_unspanned_seq(
918             &token::LBRACE,
919             &token::RBRACE,
920             seq_sep_none()
921         ) |p| {
922             let attrs = p.parse_outer_attributes();
923             let lo = p.span.lo;
924
925             let vis_span = *self.span;
926             let vis = p.parse_visibility();
927             let pur = p.parse_fn_purity();
928             // NB: at the moment, trait methods are public by default; this
929             // could change.
930             let ident = p.parse_ident();
931
932             let generics = p.parse_generics();
933
934             let (explicit_self, d) = do self.parse_fn_decl_with_self() |p| {
935                 // This is somewhat dubious; We don't want to allow argument
936                 // names to be left off if there is a definition...
937                 p.parse_arg_general(false)
938             };
939
940             let hi = p.last_span.hi;
941             debug!("parse_trait_methods(): trait method signature ends in \
942                     `%s`",
943                    self.this_token_to_str());
944             match *p.token {
945               token::SEMI => {
946                 p.bump();
947                 debug!("parse_trait_methods(): parsing required method");
948                 // NB: at the moment, visibility annotations on required
949                 // methods are ignored; this could change.
950                 if vis != ast::inherited {
951                     self.obsolete(vis_span,
952                                   ObsoleteTraitFuncVisibility);
953                 }
954                 required(TypeMethod {
955                     ident: ident,
956                     attrs: attrs,
957                     purity: pur,
958                     decl: d,
959                     generics: generics,
960                     explicit_self: explicit_self,
961                     id: ast::DUMMY_NODE_ID,
962                     span: mk_sp(lo, hi)
963                 })
964               }
965               token::LBRACE => {
966                 debug!("parse_trait_methods(): parsing provided method");
967                 let (inner_attrs, body) =
968                     p.parse_inner_attrs_and_block();
969                 let attrs = vec::append(attrs, inner_attrs);
970                 provided(@ast::method {
971                     ident: ident,
972                     attrs: attrs,
973                     generics: generics,
974                     explicit_self: explicit_self,
975                     purity: pur,
976                     decl: d,
977                     body: body,
978                     id: ast::DUMMY_NODE_ID,
979                     span: mk_sp(lo, hi),
980                     self_id: ast::DUMMY_NODE_ID,
981                     vis: vis,
982                 })
983               }
984
985               _ => {
986                     p.fatal(
987                         fmt!(
988                             "expected `;` or `{` but found `%s`",
989                             self.this_token_to_str()
990                         )
991                     );
992                 }
993             }
994         }
995     }
996
997     // parse a possibly mutable type
998     pub fn parse_mt(&self) -> mt {
999         let mutbl = self.parse_mutability();
1000         let t = ~self.parse_ty(false);
1001         mt { ty: t, mutbl: mutbl }
1002     }
1003
1004     // parse [mut/const/imm] ID : TY
1005     // now used only by obsolete record syntax parser...
1006     pub fn parse_ty_field(&self) -> TypeField {
1007         let lo = self.span.lo;
1008         let mutbl = self.parse_mutability();
1009         let id = self.parse_ident();
1010         self.expect(&token::COLON);
1011         let ty = ~self.parse_ty(false);
1012         let hi = ty.span.hi;
1013         ast::TypeField {
1014             ident: id,
1015             mt: ast::mt { ty: ty, mutbl: mutbl },
1016             span: mk_sp(lo, hi),
1017         }
1018     }
1019
1020     // parse optional return type [ -> TY ] in function decl
1021     pub fn parse_ret_ty(&self) -> (ret_style, Ty) {
1022         return if self.eat(&token::RARROW) {
1023             let lo = self.span.lo;
1024             if self.eat(&token::NOT) {
1025                 (
1026                     noreturn,
1027                     Ty {
1028                         id: ast::DUMMY_NODE_ID,
1029                         node: ty_bot,
1030                         span: mk_sp(lo, self.last_span.hi)
1031                     }
1032                 )
1033             } else {
1034                 (return_val, self.parse_ty(false))
1035             }
1036         } else {
1037             let pos = self.span.lo;
1038             (
1039                 return_val,
1040                 Ty {
1041                     id: ast::DUMMY_NODE_ID,
1042                     node: ty_nil,
1043                     span: mk_sp(pos, pos),
1044                 }
1045             )
1046         }
1047     }
1048
1049     // parse a type.
1050     // Useless second parameter for compatibility with quasiquote macros.
1051     // Bleh!
1052     pub fn parse_ty(&self, _: bool) -> Ty {
1053         maybe_whole!(deref self, nt_ty);
1054
1055         let lo = self.span.lo;
1056
1057         let t = if *self.token == token::LPAREN {
1058             self.bump();
1059             if *self.token == token::RPAREN {
1060                 self.bump();
1061                 ty_nil
1062             } else {
1063                 // (t) is a parenthesized ty
1064                 // (t,) is the type of a tuple with only one field,
1065                 // of type t
1066                 let mut ts = ~[self.parse_ty(false)];
1067                 let mut one_tuple = false;
1068                 while *self.token == token::COMMA {
1069                     self.bump();
1070                     if *self.token != token::RPAREN {
1071                         ts.push(self.parse_ty(false));
1072                     }
1073                     else {
1074                         one_tuple = true;
1075                     }
1076                 }
1077
1078                 if ts.len() == 1 && !one_tuple {
1079                     self.expect(&token::RPAREN);
1080                     return ts[0]
1081                 }
1082
1083                 let t = ty_tup(ts);
1084                 self.expect(&token::RPAREN);
1085                 t
1086             }
1087         } else if *self.token == token::AT {
1088             // MANAGED POINTER
1089             self.bump();
1090             self.parse_box_or_uniq_pointee(ManagedSigil, ty_box)
1091         } else if *self.token == token::TILDE {
1092             // OWNED POINTER
1093             self.bump();
1094             self.parse_box_or_uniq_pointee(OwnedSigil, ty_uniq)
1095         } else if *self.token == token::BINOP(token::STAR) {
1096             // STAR POINTER (bare pointer?)
1097             self.bump();
1098             ty_ptr(self.parse_mt())
1099         } else if *self.token == token::LBRACE {
1100             // STRUCTURAL RECORD (remove?)
1101             let elems = self.parse_unspanned_seq(
1102                 &token::LBRACE,
1103                 &token::RBRACE,
1104                 seq_sep_trailing_allowed(token::COMMA),
1105                 |p| p.parse_ty_field()
1106             );
1107             if elems.len() == 0 {
1108                 self.unexpected_last(&token::RBRACE);
1109             }
1110             self.obsolete(*self.last_span, ObsoleteRecordType);
1111             ty_nil
1112         } else if *self.token == token::LBRACKET {
1113             // VECTOR
1114             self.expect(&token::LBRACKET);
1115             let mt = self.parse_mt();
1116             if mt.mutbl == MutMutable {    // `m_const` too after snapshot
1117                 self.obsolete(*self.last_span, ObsoleteMutVector);
1118             }
1119
1120             // Parse the `, ..e` in `[ int, ..e ]`
1121             // where `e` is a const expression
1122             let t = match self.maybe_parse_fixed_vstore() {
1123                 None => ty_vec(mt),
1124                 Some(suffix) => ty_fixed_length_vec(mt, suffix)
1125             };
1126             self.expect(&token::RBRACKET);
1127             t
1128         } else if *self.token == token::BINOP(token::AND) {
1129             // BORROWED POINTER
1130             self.bump();
1131             self.parse_borrowed_pointee()
1132         } else if self.eat_keyword(keywords::Extern) {
1133             // EXTERN FUNCTION
1134             self.parse_ty_bare_fn()
1135         } else if self.token_is_closure_keyword(self.token) {
1136             // CLOSURE
1137             let result = self.parse_ty_closure(ast::BorrowedSigil, None);
1138             self.obsolete(*self.last_span, ObsoleteBareFnType);
1139             result
1140         } else if self.eat_keyword(keywords::Typeof) {
1141             // TYPEOF
1142             // In order to not be ambiguous, the type must be surrounded by parens.
1143             self.expect(&token::LPAREN);
1144             let e = self.parse_expr();
1145             self.expect(&token::RPAREN);
1146             ty_typeof(e)
1147         } else if *self.token == token::MOD_SEP
1148             || is_ident_or_path(self.token) {
1149             // NAMED TYPE
1150             let PathAndBounds {
1151                 path,
1152                 bounds
1153             } = self.parse_path(LifetimeAndTypesAndBounds);
1154             ty_path(path, bounds, ast::DUMMY_NODE_ID)
1155         } else {
1156             self.fatal(fmt!("expected type, found token %?",
1157                             *self.token));
1158         };
1159
1160         let sp = mk_sp(lo, self.last_span.hi);
1161         Ty {id: ast::DUMMY_NODE_ID, node: t, span: sp}
1162     }
1163
1164     // parse the type following a @ or a ~
1165     pub fn parse_box_or_uniq_pointee(&self,
1166                                      sigil: ast::Sigil,
1167                                      ctor: &fn(v: mt) -> ty_) -> ty_ {
1168         // @'foo fn() or @foo/fn() or @fn() are parsed directly as fn types:
1169         match *self.token {
1170             token::LIFETIME(*) => {
1171                 let lifetime = self.parse_lifetime();
1172                 return self.parse_ty_closure(sigil, Some(lifetime));
1173             }
1174
1175             token::IDENT(*) => {
1176                 if self.look_ahead(1, |t| *t == token::BINOP(token::SLASH)) &&
1177                         self.look_ahead(2, |t|
1178                                         self.token_is_closure_keyword(t)) {
1179                     let lifetime = self.parse_lifetime();
1180                     self.obsolete(*self.last_span, ObsoleteLifetimeNotation);
1181                     return self.parse_ty_closure(sigil, Some(lifetime));
1182                 } else if self.token_is_closure_keyword(self.token) {
1183                     return self.parse_ty_closure(sigil, None);
1184                 }
1185             }
1186             _ => {}
1187         }
1188
1189         // other things are parsed as @ + a type.  Note that constructs like
1190         // @[] and @str will be resolved during typeck to slices and so forth,
1191         // rather than boxed ptrs.  But the special casing of str/vec is not
1192         // reflected in the AST type.
1193         let mt = self.parse_mt();
1194
1195         if mt.mutbl != MutImmutable && sigil == OwnedSigil {
1196             self.obsolete(*self.last_span, ObsoleteMutOwnedPointer);
1197         }
1198
1199         ctor(mt)
1200     }
1201
1202     pub fn parse_borrowed_pointee(&self) -> ty_ {
1203         // look for `&'lt` or `&'foo ` and interpret `foo` as the region name:
1204         let opt_lifetime = self.parse_opt_lifetime();
1205
1206         if self.token_is_closure_keyword(self.token) {
1207             return self.parse_ty_closure(BorrowedSigil, opt_lifetime);
1208         }
1209
1210         let mt = self.parse_mt();
1211         return ty_rptr(opt_lifetime, mt);
1212     }
1213
1214     // parse an optional, obsolete argument mode.
1215     pub fn parse_arg_mode(&self) {
1216         if self.eat(&token::BINOP(token::MINUS)) {
1217             self.obsolete(*self.last_span, ObsoleteMode);
1218         } else if self.eat(&token::ANDAND) {
1219             self.obsolete(*self.last_span, ObsoleteMode);
1220         } else if self.eat(&token::BINOP(token::PLUS)) {
1221             let lo = self.last_span.lo;
1222             if self.eat(&token::BINOP(token::PLUS)) {
1223                 let hi = self.last_span.hi;
1224                 self.obsolete(mk_sp(lo, hi), ObsoleteMode);
1225             } else {
1226                 self.obsolete(*self.last_span, ObsoleteMode);
1227             }
1228         } else {
1229             // Ignore.
1230         }
1231     }
1232
1233     pub fn is_named_argument(&self) -> bool {
1234         let offset = match *self.token {
1235             token::BINOP(token::AND) => 1,
1236             token::BINOP(token::MINUS) => 1,
1237             token::ANDAND => 1,
1238             token::BINOP(token::PLUS) => {
1239                 if self.look_ahead(1, |t| *t == token::BINOP(token::PLUS)) {
1240                     2
1241                 } else {
1242                     1
1243                 }
1244             },
1245             _ => 0
1246         };
1247
1248         debug!("parser is_named_argument offset:%u", offset);
1249
1250         if offset == 0 {
1251             is_plain_ident_or_underscore(&*self.token)
1252                 && self.look_ahead(1, |t| *t == token::COLON)
1253         } else {
1254             self.look_ahead(offset, |t| is_plain_ident_or_underscore(t))
1255                 && self.look_ahead(offset + 1, |t| *t == token::COLON)
1256         }
1257     }
1258
1259     // This version of parse arg doesn't necessarily require
1260     // identifier names.
1261     pub fn parse_arg_general(&self, require_name: bool) -> arg {
1262         let is_mutbl = self.eat_keyword(keywords::Mut);
1263         let pat = if require_name || self.is_named_argument() {
1264             debug!("parse_arg_general parse_pat (require_name:%?)",
1265                    require_name);
1266             self.parse_arg_mode();
1267             let pat = self.parse_pat();
1268
1269             if is_mutbl && !ast_util::pat_is_ident(pat) {
1270                 self.obsolete(*self.span, ObsoleteMutWithMultipleBindings)
1271             }
1272
1273             self.expect(&token::COLON);
1274             pat
1275         } else {
1276             debug!("parse_arg_general ident_to_pat");
1277             ast_util::ident_to_pat(ast::DUMMY_NODE_ID,
1278                                    *self.last_span,
1279                                    special_idents::invalid)
1280         };
1281
1282         let t = self.parse_ty(false);
1283
1284         ast::arg {
1285             is_mutbl: is_mutbl,
1286             ty: t,
1287             pat: pat,
1288             id: ast::DUMMY_NODE_ID,
1289         }
1290     }
1291
1292     // parse a single function argument
1293     pub fn parse_arg(&self) -> arg {
1294         self.parse_arg_general(true)
1295     }
1296
1297     // parse an argument in a lambda header e.g. |arg, arg|
1298     pub fn parse_fn_block_arg(&self) -> arg {
1299         self.parse_arg_mode();
1300         let is_mutbl = self.eat_keyword(keywords::Mut);
1301         let pat = self.parse_pat();
1302         let t = if self.eat(&token::COLON) {
1303             self.parse_ty(false)
1304         } else {
1305             Ty {
1306                 id: ast::DUMMY_NODE_ID,
1307                 node: ty_infer,
1308                 span: mk_sp(self.span.lo, self.span.hi),
1309             }
1310         };
1311         ast::arg {
1312             is_mutbl: is_mutbl,
1313             ty: t,
1314             pat: pat,
1315             id: ast::DUMMY_NODE_ID
1316         }
1317     }
1318
1319     pub fn maybe_parse_fixed_vstore(&self) -> Option<@ast::Expr> {
1320         if self.eat(&token::BINOP(token::STAR)) {
1321             self.obsolete(*self.last_span, ObsoleteFixedLengthVectorType);
1322             Some(self.parse_expr())
1323         } else if *self.token == token::COMMA &&
1324                 self.look_ahead(1, |t| *t == token::DOTDOT) {
1325             self.bump();
1326             self.bump();
1327             Some(self.parse_expr())
1328         } else {
1329             None
1330         }
1331     }
1332
1333     // matches token_lit = LIT_INT | ...
1334     pub fn lit_from_token(&self, tok: &token::Token) -> lit_ {
1335         match *tok {
1336             token::LIT_CHAR(i) => lit_char(i),
1337             token::LIT_INT(i, it) => lit_int(i, it),
1338             token::LIT_UINT(u, ut) => lit_uint(u, ut),
1339             token::LIT_INT_UNSUFFIXED(i) => lit_int_unsuffixed(i),
1340             token::LIT_FLOAT(s, ft) => lit_float(self.id_to_str(s), ft),
1341             token::LIT_FLOAT_UNSUFFIXED(s) =>
1342                 lit_float_unsuffixed(self.id_to_str(s)),
1343             token::LIT_STR(s) => lit_str(self.id_to_str(s)),
1344             token::LPAREN => { self.expect(&token::RPAREN); lit_nil },
1345             _ => { self.unexpected_last(tok); }
1346         }
1347     }
1348
1349     // matches lit = true | false | token_lit
1350     pub fn parse_lit(&self) -> lit {
1351         let lo = self.span.lo;
1352         let lit = if self.eat_keyword(keywords::True) {
1353             lit_bool(true)
1354         } else if self.eat_keyword(keywords::False) {
1355             lit_bool(false)
1356         } else {
1357             let token = self.bump_and_get();
1358             let lit = self.lit_from_token(&token);
1359             lit
1360         };
1361         codemap::Spanned { node: lit, span: mk_sp(lo, self.last_span.hi) }
1362     }
1363
1364     // matches '-' lit | lit
1365     pub fn parse_literal_maybe_minus(&self) -> @Expr {
1366         let minus_lo = self.span.lo;
1367         let minus_present = self.eat(&token::BINOP(token::MINUS));
1368
1369         let lo = self.span.lo;
1370         let literal = @self.parse_lit();
1371         let hi = self.span.hi;
1372         let expr = self.mk_expr(lo, hi, ExprLit(literal));
1373
1374         if minus_present {
1375             let minus_hi = self.span.hi;
1376             self.mk_expr(minus_lo, minus_hi, self.mk_unary(UnNeg, expr))
1377         } else {
1378             expr
1379         }
1380     }
1381
1382     /// Parses a path and optional type parameter bounds, depending on the
1383     /// mode. The `mode` parameter determines whether lifetimes, types, and/or
1384     /// bounds are permitted and whether `::` must precede type parameter
1385     /// groups.
1386     pub fn parse_path(&self, mode: PathParsingMode) -> PathAndBounds {
1387         // Check for a whole path...
1388         let found = match *self.token {
1389             INTERPOLATED(token::nt_path(_)) => Some(self.bump_and_get()),
1390             _ => None,
1391         };
1392         match found {
1393             Some(INTERPOLATED(token::nt_path(~path))) => {
1394                 return PathAndBounds {
1395                     path: path,
1396                     bounds: None,
1397                 }
1398             }
1399             _ => {}
1400         }
1401
1402         let lo = self.span.lo;
1403         let is_global = self.eat(&token::MOD_SEP);
1404
1405         // Parse any number of segments and bound sets. A segment is an
1406         // identifier followed by an optional lifetime and a set of types.
1407         // A bound set is a set of type parameter bounds.
1408         let mut segments = ~[];
1409         loop {
1410             // First, parse an identifier.
1411             match *self.token {
1412                 token::IDENT(*) => {}
1413                 _ => break,
1414             }
1415             let identifier = self.parse_ident();
1416
1417             // Next, parse a colon and bounded type parameters, if applicable.
1418             let bound_set = if mode == LifetimeAndTypesAndBounds {
1419                 self.parse_optional_ty_param_bounds()
1420             } else {
1421                 None
1422             };
1423
1424             // Parse the '::' before type parameters if it's required. If
1425             // it is required and wasn't present, then we're done.
1426             if mode == LifetimeAndTypesWithColons &&
1427                     !self.eat(&token::MOD_SEP) {
1428                 segments.push(PathSegmentAndBoundSet {
1429                     segment: ast::PathSegment {
1430                         identifier: identifier,
1431                         lifetime: None,
1432                         types: opt_vec::Empty,
1433                     },
1434                     bound_set: bound_set
1435                 });
1436                 break
1437             }
1438
1439             // Parse the `<` before the lifetime and types, if applicable.
1440             let (any_lifetime_or_types, optional_lifetime, types) =
1441                     if mode != NoTypesAllowed && self.eat(&token::LT) {
1442                 // Parse an optional lifetime.
1443                 let optional_lifetime = match *self.token {
1444                     token::LIFETIME(*) => Some(self.parse_lifetime()),
1445                     _ => None,
1446                 };
1447
1448                 // Parse type parameters.
1449                 let mut types = opt_vec::Empty;
1450                 let mut need_comma = optional_lifetime.is_some();
1451                 loop {
1452                     // We're done if we see a `>`.
1453                     match *self.token {
1454                         token::GT | token::BINOP(token::SHR) => {
1455                             self.expect_gt();
1456                             break
1457                         }
1458                         _ => {} // Go on.
1459                     }
1460
1461                     if need_comma {
1462                         self.expect(&token::COMMA)
1463                     } else {
1464                         need_comma = true
1465                     }
1466
1467                     types.push(self.parse_ty(false))
1468                 }
1469
1470                 (true, optional_lifetime, types)
1471             } else {
1472                 (false, None, opt_vec::Empty)
1473             };
1474
1475             // Assemble and push the result.
1476             segments.push(PathSegmentAndBoundSet {
1477                 segment: ast::PathSegment {
1478                     identifier: identifier,
1479                     lifetime: optional_lifetime,
1480                     types: types,
1481                 },
1482                 bound_set: bound_set
1483             });
1484
1485             // We're done if we don't see a '::', unless the mode required
1486             // a double colon to get here in the first place.
1487             if !(mode == LifetimeAndTypesWithColons &&
1488                     !any_lifetime_or_types) {
1489                 if !self.eat(&token::MOD_SEP) {
1490                     break
1491                 }
1492             }
1493         }
1494
1495         // Assemble the span.
1496         let span = mk_sp(lo, self.last_span.hi);
1497
1498         // Assemble the path segments.
1499         let mut path_segments = ~[];
1500         let mut bounds = None;
1501         let last_segment_index = segments.len() - 1;
1502         for (i, segment_and_bounds) in segments.move_iter().enumerate() {
1503             let PathSegmentAndBoundSet {
1504                 segment: segment,
1505                 bound_set: bound_set
1506             } = segment_and_bounds;
1507             path_segments.push(segment);
1508
1509             if bound_set.is_some() {
1510                 if i != last_segment_index {
1511                     self.span_err(span,
1512                                   "type parameter bounds are allowed only \
1513                                    before the last segment in a path")
1514                 }
1515
1516                 bounds = bound_set
1517             }
1518         }
1519
1520         // Assemble the result.
1521         let path_and_bounds = PathAndBounds {
1522             path: ast::Path {
1523                 span: span,
1524                 global: is_global,
1525                 segments: path_segments,
1526             },
1527             bounds: bounds,
1528         };
1529
1530         path_and_bounds
1531     }
1532
1533     /// parses 0 or 1 lifetime
1534     pub fn parse_opt_lifetime(&self) -> Option<ast::Lifetime> {
1535         match *self.token {
1536             token::LIFETIME(*) => {
1537                 Some(self.parse_lifetime())
1538             }
1539
1540             // Also accept the (obsolete) syntax `foo/`
1541             token::IDENT(*) => {
1542                 if self.look_ahead(1, |t| *t == token::BINOP(token::SLASH)) {
1543                     self.obsolete(*self.last_span, ObsoleteLifetimeNotation);
1544                     Some(self.parse_lifetime())
1545                 } else {
1546                     None
1547                 }
1548             }
1549
1550             _ => {
1551                 None
1552             }
1553         }
1554     }
1555
1556     /// Parses a single lifetime
1557     // matches lifetime = ( LIFETIME ) | ( IDENT / )
1558     pub fn parse_lifetime(&self) -> ast::Lifetime {
1559         match *self.token {
1560             token::LIFETIME(i) => {
1561                 let span = self.span;
1562                 self.bump();
1563                 return ast::Lifetime {
1564                     id: ast::DUMMY_NODE_ID,
1565                     span: *span,
1566                     ident: i
1567                 };
1568             }
1569
1570             // Also accept the (obsolete) syntax `foo/`
1571             token::IDENT(i, _) => {
1572                 let span = self.span;
1573                 self.bump();
1574                 self.expect(&token::BINOP(token::SLASH));
1575                 self.obsolete(*self.last_span, ObsoleteLifetimeNotation);
1576                 return ast::Lifetime {
1577                     id: ast::DUMMY_NODE_ID,
1578                     span: *span,
1579                     ident: i
1580                 };
1581             }
1582
1583             _ => {
1584                 self.fatal(fmt!("Expected a lifetime name"));
1585             }
1586         }
1587     }
1588
1589     // matches lifetimes = ( lifetime ) | ( lifetime , lifetimes )
1590     // actually, it matches the empty one too, but putting that in there
1591     // messes up the grammar....
1592     pub fn parse_lifetimes(&self) -> OptVec<ast::Lifetime> {
1593         /*!
1594          *
1595          * Parses zero or more comma separated lifetimes.
1596          * Expects each lifetime to be followed by either
1597          * a comma or `>`.  Used when parsing type parameter
1598          * lists, where we expect something like `<'a, 'b, T>`.
1599          */
1600
1601         let mut res = opt_vec::Empty;
1602         loop {
1603             match *self.token {
1604                 token::LIFETIME(_) => {
1605                     res.push(self.parse_lifetime());
1606                 }
1607                 _ => {
1608                     return res;
1609                 }
1610             }
1611
1612             match *self.token {
1613                 token::COMMA => { self.bump();}
1614                 token::GT => { return res; }
1615                 token::BINOP(token::SHR) => { return res; }
1616                 _ => {
1617                     self.fatal(fmt!("expected `,` or `>` after lifetime name, got: %?",
1618                                     *self.token));
1619                 }
1620             }
1621         }
1622     }
1623
1624     pub fn token_is_mutability(&self, tok: &token::Token) -> bool {
1625         token::is_keyword(keywords::Mut, tok) ||
1626         token::is_keyword(keywords::Const, tok)
1627     }
1628
1629     // parse mutability declaration (mut/const/imm)
1630     pub fn parse_mutability(&self) -> Mutability {
1631         if self.eat_keyword(keywords::Mut) {
1632             MutMutable
1633         } else if self.eat_keyword(keywords::Const) {
1634             self.obsolete(*self.last_span, ObsoleteConstPointer);
1635             MutImmutable
1636         } else {
1637             MutImmutable
1638         }
1639     }
1640
1641     // parse ident COLON expr
1642     pub fn parse_field(&self) -> Field {
1643         let lo = self.span.lo;
1644         let i = self.parse_ident();
1645         self.expect(&token::COLON);
1646         let e = self.parse_expr();
1647         ast::Field {
1648             ident: i,
1649             expr: e,
1650             span: mk_sp(lo, e.span.hi),
1651         }
1652     }
1653
1654     pub fn mk_expr(&self, lo: BytePos, hi: BytePos, node: Expr_) -> @Expr {
1655         @Expr {
1656             id: ast::DUMMY_NODE_ID,
1657             node: node,
1658             span: mk_sp(lo, hi),
1659         }
1660     }
1661
1662     pub fn mk_unary(&self, unop: ast::UnOp, expr: @Expr) -> ast::Expr_ {
1663         ExprUnary(ast::DUMMY_NODE_ID, unop, expr)
1664     }
1665
1666     pub fn mk_binary(&self, binop: ast::BinOp, lhs: @Expr, rhs: @Expr) -> ast::Expr_ {
1667         ExprBinary(ast::DUMMY_NODE_ID, binop, lhs, rhs)
1668     }
1669
1670     pub fn mk_call(&self, f: @Expr, args: ~[@Expr], sugar: CallSugar) -> ast::Expr_ {
1671         ExprCall(f, args, sugar)
1672     }
1673
1674     pub fn mk_method_call(&self,
1675                       rcvr: @Expr,
1676                       ident: Ident,
1677                       tps: ~[Ty],
1678                       args: ~[@Expr],
1679                       sugar: CallSugar) -> ast::Expr_ {
1680         ExprMethodCall(ast::DUMMY_NODE_ID, rcvr, ident, tps, args, sugar)
1681     }
1682
1683     pub fn mk_index(&self, expr: @Expr, idx: @Expr) -> ast::Expr_ {
1684         ExprIndex(ast::DUMMY_NODE_ID, expr, idx)
1685     }
1686
1687     pub fn mk_field(&self, expr: @Expr, ident: Ident, tys: ~[Ty]) -> ast::Expr_ {
1688         ExprField(expr, ident, tys)
1689     }
1690
1691     pub fn mk_assign_op(&self, binop: ast::BinOp, lhs: @Expr, rhs: @Expr) -> ast::Expr_ {
1692         ExprAssignOp(ast::DUMMY_NODE_ID, binop, lhs, rhs)
1693     }
1694
1695     pub fn mk_mac_expr(&self, lo: BytePos, hi: BytePos, m: mac_) -> @Expr {
1696         @Expr {
1697             id: ast::DUMMY_NODE_ID,
1698             node: ExprMac(codemap::Spanned {node: m, span: mk_sp(lo, hi)}),
1699             span: mk_sp(lo, hi),
1700         }
1701     }
1702
1703     pub fn mk_lit_u32(&self, i: u32) -> @Expr {
1704         let span = self.span;
1705         let lv_lit = @codemap::Spanned {
1706             node: lit_uint(i as u64, ty_u32),
1707             span: *span
1708         };
1709
1710         @Expr {
1711             id: ast::DUMMY_NODE_ID,
1712             node: ExprLit(lv_lit),
1713             span: *span,
1714         }
1715     }
1716
1717     // at the bottom (top?) of the precedence hierarchy,
1718     // parse things like parenthesized exprs,
1719     // macros, return, etc.
1720     pub fn parse_bottom_expr(&self) -> @Expr {
1721         maybe_whole_expr!(self);
1722
1723         let lo = self.span.lo;
1724         let mut hi = self.span.hi;
1725
1726         let ex: Expr_;
1727
1728         if *self.token == token::LPAREN {
1729             self.bump();
1730             // (e) is parenthesized e
1731             // (e,) is a tuple with only one field, e
1732             let mut trailing_comma = false;
1733             if *self.token == token::RPAREN {
1734                 hi = self.span.hi;
1735                 self.bump();
1736                 let lit = @spanned(lo, hi, lit_nil);
1737                 return self.mk_expr(lo, hi, ExprLit(lit));
1738             }
1739             let mut es = ~[self.parse_expr()];
1740             self.commit_expr(*es.last(), &[], &[token::COMMA, token::RPAREN]);
1741             while *self.token == token::COMMA {
1742                 self.bump();
1743                 if *self.token != token::RPAREN {
1744                     es.push(self.parse_expr());
1745                     self.commit_expr(*es.last(), &[], &[token::COMMA, token::RPAREN]);
1746                 }
1747                 else {
1748                     trailing_comma = true;
1749                 }
1750             }
1751             hi = self.span.hi;
1752             self.commit_expr_expecting(*es.last(), token::RPAREN);
1753
1754             return if es.len() == 1 && !trailing_comma {
1755                 self.mk_expr(lo, self.span.hi, ExprParen(es[0]))
1756             }
1757             else {
1758                 self.mk_expr(lo, hi, ExprTup(es))
1759             }
1760         } else if *self.token == token::LBRACE {
1761             self.bump();
1762             let blk = self.parse_block_tail(lo, DefaultBlock);
1763             return self.mk_expr(blk.span.lo, blk.span.hi,
1764                                  ExprBlock(blk));
1765         } else if token::is_bar(&*self.token) {
1766             return self.parse_lambda_expr();
1767         } else if self.eat_keyword(keywords::Self) {
1768             ex = ExprSelf;
1769             hi = self.span.hi;
1770         } else if self.eat_keyword(keywords::If) {
1771             return self.parse_if_expr();
1772         } else if self.eat_keyword(keywords::For) {
1773             return self.parse_for_expr(None);
1774         } else if self.eat_keyword(keywords::Do) {
1775             return self.parse_sugary_call_expr(lo, ~"do", DoSugar,
1776                                                ExprDoBody);
1777         } else if self.eat_keyword(keywords::While) {
1778             return self.parse_while_expr();
1779         } else if self.token_is_lifetime(&*self.token) {
1780             let lifetime = self.get_lifetime(&*self.token);
1781             self.bump();
1782             self.expect(&token::COLON);
1783             if self.eat_keyword(keywords::For) {
1784                 return self.parse_for_expr(Some(lifetime))
1785             } else if self.eat_keyword(keywords::Loop) {
1786                 return self.parse_loop_expr(Some(lifetime))
1787             } else {
1788                 self.fatal("expected `for` or `loop` after a label")
1789             }
1790         } else if self.eat_keyword(keywords::Loop) {
1791             return self.parse_loop_expr(None);
1792         } else if self.eat_keyword(keywords::Continue) {
1793             let lo = self.span.lo;
1794             let ex = if self.token_is_lifetime(&*self.token) {
1795                 let lifetime = self.get_lifetime(&*self.token);
1796                 self.bump();
1797                 ExprAgain(Some(lifetime.name))
1798             } else {
1799                 ExprAgain(None)
1800             };
1801             let hi = self.span.hi;
1802             return self.mk_expr(lo, hi, ex);
1803         } else if self.eat_keyword(keywords::Match) {
1804             return self.parse_match_expr();
1805         } else if self.eat_keyword(keywords::Unsafe) {
1806             return self.parse_block_expr(lo, UnsafeBlock(ast::UserProvided));
1807         } else if *self.token == token::LBRACKET {
1808             self.bump();
1809             let mutbl = self.parse_mutability();
1810             if mutbl == MutMutable {
1811                 self.obsolete(*self.last_span, ObsoleteMutVector);
1812             }
1813
1814             if *self.token == token::RBRACKET {
1815                 // Empty vector.
1816                 self.bump();
1817                 ex = ExprVec(~[], mutbl);
1818             } else {
1819                 // Nonempty vector.
1820                 let first_expr = self.parse_expr();
1821                 if *self.token == token::COMMA &&
1822                         self.look_ahead(1, |t| *t == token::DOTDOT) {
1823                     // Repeating vector syntax: [ 0, ..512 ]
1824                     self.bump();
1825                     self.bump();
1826                     let count = self.parse_expr();
1827                     self.expect(&token::RBRACKET);
1828                     ex = ExprRepeat(first_expr, count, mutbl);
1829                 } else if *self.token == token::COMMA {
1830                     // Vector with two or more elements.
1831                     self.bump();
1832                     let remaining_exprs = self.parse_seq_to_end(
1833                         &token::RBRACKET,
1834                         seq_sep_trailing_allowed(token::COMMA),
1835                         |p| p.parse_expr()
1836                     );
1837                     ex = ExprVec(~[first_expr] + remaining_exprs, mutbl);
1838                 } else {
1839                     // Vector with one element.
1840                     self.expect(&token::RBRACKET);
1841                     ex = ExprVec(~[first_expr], mutbl);
1842                 }
1843             }
1844             hi = self.last_span.hi;
1845         } else if self.eat_keyword(keywords::__LogLevel) {
1846             // LOG LEVEL expression
1847             self.expect(&token::LPAREN);
1848             ex = ExprLogLevel;
1849             hi = self.span.hi;
1850             self.expect(&token::RPAREN);
1851         } else if self.eat_keyword(keywords::Return) {
1852             // RETURN expression
1853             if can_begin_expr(&*self.token) {
1854                 let e = self.parse_expr();
1855                 hi = e.span.hi;
1856                 ex = ExprRet(Some(e));
1857             } else { ex = ExprRet(None); }
1858         } else if self.eat_keyword(keywords::Break) {
1859             // BREAK expression
1860             if self.token_is_lifetime(&*self.token) {
1861                 let lifetime = self.get_lifetime(&*self.token);
1862                 self.bump();
1863                 ex = ExprBreak(Some(lifetime.name));
1864             } else {
1865                 ex = ExprBreak(None);
1866             }
1867             hi = self.span.hi;
1868         } else if *self.token == token::MOD_SEP ||
1869                 is_ident(&*self.token) && !self.is_keyword(keywords::True) &&
1870                 !self.is_keyword(keywords::False) {
1871             let pth = self.parse_path(LifetimeAndTypesWithColons).path;
1872
1873             // `!`, as an operator, is prefix, so we know this isn't that
1874             if *self.token == token::NOT {
1875                 // MACRO INVOCATION expression
1876                 self.bump();
1877                 match *self.token {
1878                     token::LPAREN | token::LBRACE => {}
1879                     _ => self.fatal("expected open delimiter")
1880                 };
1881
1882                 let ket = token::flip_delimiter(&*self.token);
1883                 self.bump();
1884
1885                 let tts = self.parse_seq_to_end(&ket,
1886                                                 seq_sep_none(),
1887                                                 |p| p.parse_token_tree());
1888                 let hi = self.span.hi;
1889
1890                 return self.mk_mac_expr(lo, hi, mac_invoc_tt(pth, tts, EMPTY_CTXT));
1891             } else if *self.token == token::LBRACE {
1892                 // This might be a struct literal.
1893                 if self.looking_at_record_literal() {
1894                     // It's a struct literal.
1895                     self.bump();
1896                     let mut fields = ~[];
1897                     let mut base = None;
1898
1899                     fields.push(self.parse_field());
1900                     while *self.token != token::RBRACE {
1901                         if self.try_parse_obsolete_with() {
1902                             break;
1903                         }
1904
1905                         self.commit_expr(fields.last().expr, &[token::COMMA], &[token::RBRACE]);
1906
1907                         if self.eat(&token::DOTDOT) {
1908                             base = Some(self.parse_expr());
1909                             break;
1910                         }
1911
1912                         if *self.token == token::RBRACE {
1913                             // Accept an optional trailing comma.
1914                             break;
1915                         }
1916                         fields.push(self.parse_field());
1917                     }
1918
1919                     hi = pth.span.hi;
1920                     self.commit_expr_expecting(fields.last().expr, token::RBRACE);
1921                     ex = ExprStruct(pth, fields, base);
1922                     return self.mk_expr(lo, hi, ex);
1923                 }
1924             }
1925
1926             hi = pth.span.hi;
1927             ex = ExprPath(pth);
1928         } else {
1929             // other literal expression
1930             let lit = self.parse_lit();
1931             hi = lit.span.hi;
1932             ex = ExprLit(@lit);
1933         }
1934
1935         return self.mk_expr(lo, hi, ex);
1936     }
1937
1938     // parse a block or unsafe block
1939     pub fn parse_block_expr(&self, lo: BytePos, blk_mode: BlockCheckMode)
1940                             -> @Expr {
1941         self.expect(&token::LBRACE);
1942         let blk = self.parse_block_tail(lo, blk_mode);
1943         return self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk));
1944     }
1945
1946     // parse a.b or a(13) or a[4] or just a
1947     pub fn parse_dot_or_call_expr(&self) -> @Expr {
1948         let b = self.parse_bottom_expr();
1949         self.parse_dot_or_call_expr_with(b)
1950     }
1951
1952     pub fn parse_dot_or_call_expr_with(&self, e0: @Expr) -> @Expr {
1953         let mut e = e0;
1954         let lo = e.span.lo;
1955         let mut hi;
1956         loop {
1957             // expr.f
1958             if self.eat(&token::DOT) {
1959                 match *self.token {
1960                   token::IDENT(i, _) => {
1961                     hi = self.span.hi;
1962                     self.bump();
1963                     let (_, tys) = if self.eat(&token::MOD_SEP) {
1964                         self.expect(&token::LT);
1965                         self.parse_generic_values_after_lt()
1966                     } else {
1967                         (opt_vec::Empty, ~[])
1968                     };
1969
1970                     // expr.f() method call
1971                     match *self.token {
1972                         token::LPAREN => {
1973                             let es = self.parse_unspanned_seq(
1974                                 &token::LPAREN,
1975                                 &token::RPAREN,
1976                                 seq_sep_trailing_disallowed(token::COMMA),
1977                                 |p| p.parse_expr()
1978                             );
1979                             hi = self.span.hi;
1980
1981                             let nd = self.mk_method_call(e, i, tys, es, NoSugar);
1982                             e = self.mk_expr(lo, hi, nd);
1983                         }
1984                         _ => {
1985                             e = self.mk_expr(lo, hi, self.mk_field(e, i, tys));
1986                         }
1987                     }
1988                   }
1989                   _ => self.unexpected()
1990                 }
1991                 loop;
1992             }
1993             if self.expr_is_complete(e) { break; }
1994             match *self.token {
1995               // expr(...)
1996               token::LPAREN => {
1997                 let es = self.parse_unspanned_seq(
1998                     &token::LPAREN,
1999                     &token::RPAREN,
2000                     seq_sep_trailing_disallowed(token::COMMA),
2001                     |p| p.parse_expr()
2002                 );
2003                 hi = self.span.hi;
2004
2005                 let nd = self.mk_call(e, es, NoSugar);
2006                 e = self.mk_expr(lo, hi, nd);
2007               }
2008
2009               // expr[...]
2010               token::LBRACKET => {
2011                 self.bump();
2012                 let ix = self.parse_expr();
2013                 hi = ix.span.hi;
2014                 self.commit_expr_expecting(ix, token::RBRACKET);
2015                 e = self.mk_expr(lo, hi, self.mk_index(e, ix));
2016               }
2017
2018               _ => return e
2019             }
2020         }
2021         return e;
2022     }
2023
2024     // parse an optional separator followed by a kleene-style
2025     // repetition token (+ or *).
2026     pub fn parse_sep_and_zerok(&self) -> (Option<token::Token>, bool) {
2027         fn parse_zerok(parser: &Parser) -> Option<bool> {
2028             match *parser.token {
2029                 token::BINOP(token::STAR) | token::BINOP(token::PLUS) => {
2030                     let zerok = *parser.token == token::BINOP(token::STAR);
2031                     parser.bump();
2032                     Some(zerok)
2033                 },
2034                 _ => None
2035             }
2036         };
2037
2038         match parse_zerok(self) {
2039             Some(zerok) => return (None, zerok),
2040             None => {}
2041         }
2042
2043         let separator = self.bump_and_get();
2044         match parse_zerok(self) {
2045             Some(zerok) => (Some(separator), zerok),
2046             None => self.fatal("expected `*` or `+`")
2047         }
2048     }
2049
2050     // parse a single token tree from the input.
2051     pub fn parse_token_tree(&self) -> token_tree {
2052         // FIXME #6994: currently, this is too eager. It
2053         // parses token trees but also identifies tt_seq's
2054         // and tt_nonterminals; it's too early to know yet
2055         // whether something will be a nonterminal or a seq
2056         // yet.
2057         maybe_whole!(deref self, nt_tt);
2058
2059         // this is the fall-through for the 'match' below.
2060         // invariants: the current token is not a left-delimiter,
2061         // not an EOF, and not the desired right-delimiter (if
2062         // it were, parse_seq_to_before_end would have prevented
2063         // reaching this point.
2064         fn parse_non_delim_tt_tok(p: &Parser) -> token_tree {
2065             maybe_whole!(deref p, nt_tt);
2066             match *p.token {
2067               token::RPAREN | token::RBRACE | token::RBRACKET
2068               => {
2069                 p.fatal(
2070                     fmt!(
2071                         "incorrect close delimiter: `%s`",
2072                         p.this_token_to_str()
2073                     )
2074                 );
2075               }
2076               /* we ought to allow different depths of unquotation */
2077               token::DOLLAR if *p.quote_depth > 0u => {
2078                 p.bump();
2079                 let sp = *p.span;
2080
2081                 if *p.token == token::LPAREN {
2082                     let seq = p.parse_seq(
2083                         &token::LPAREN,
2084                         &token::RPAREN,
2085                         seq_sep_none(),
2086                         |p| p.parse_token_tree()
2087                     );
2088                     let (s, z) = p.parse_sep_and_zerok();
2089                     let seq = match seq {
2090                         Spanned { node, _ } => node,
2091                     };
2092                     tt_seq(
2093                         mk_sp(sp.lo, p.span.hi),
2094                         @mut seq,
2095                         s,
2096                         z
2097                     )
2098                 } else {
2099                     tt_nonterminal(sp, p.parse_ident())
2100                 }
2101               }
2102               _ => {
2103                   parse_any_tt_tok(p)
2104               }
2105             }
2106         }
2107
2108         // turn the next token into a tt_tok:
2109         fn parse_any_tt_tok(p: &Parser) -> token_tree{
2110             tt_tok(*p.span, p.bump_and_get())
2111         }
2112
2113         match *self.token {
2114             token::EOF => {
2115                 self.fatal("file ended with unbalanced delimiters");
2116             }
2117             token::LPAREN | token::LBRACE | token::LBRACKET => {
2118                 let close_delim = token::flip_delimiter(&*self.token);
2119
2120                 // Parse the open delimiter.
2121                 let mut result = ~[parse_any_tt_tok(self)];
2122
2123                 let trees =
2124                     self.parse_seq_to_before_end(&close_delim,
2125                                                  seq_sep_none(),
2126                                                  |p| p.parse_token_tree());
2127                 result.push_all_move(trees);
2128
2129                 // Parse the close delimiter.
2130                 result.push(parse_any_tt_tok(self));
2131
2132                 tt_delim(@mut result)
2133             }
2134             _ => parse_non_delim_tt_tok(self)
2135         }
2136     }
2137
2138     // parse a stream of tokens into a list of token_trees,
2139     // up to EOF.
2140     pub fn parse_all_token_trees(&self) -> ~[token_tree] {
2141         let mut tts = ~[];
2142         while *self.token != token::EOF {
2143             tts.push(self.parse_token_tree());
2144         }
2145         tts
2146     }
2147
2148     pub fn parse_matchers(&self) -> ~[matcher] {
2149         // unification of matchers and token_trees would vastly improve
2150         // the interpolation of matchers
2151         maybe_whole!(self, nt_matchers);
2152         let name_idx = @mut 0u;
2153         match *self.token {
2154             token::LBRACE | token::LPAREN | token::LBRACKET => {
2155                 let other_delimiter = token::flip_delimiter(self.token);
2156                 self.bump();
2157                 self.parse_matcher_subseq_upto(name_idx, &other_delimiter)
2158             }
2159             _ => self.fatal("expected open delimiter")
2160         }
2161     }
2162
2163     // This goofy function is necessary to correctly match parens in matchers.
2164     // Otherwise, `$( ( )` would be a valid matcher, and `$( () )` would be
2165     // invalid. It's similar to common::parse_seq.
2166     pub fn parse_matcher_subseq_upto(&self,
2167                                      name_idx: @mut uint,
2168                                      ket: &token::Token)
2169                                      -> ~[matcher] {
2170         let mut ret_val = ~[];
2171         let mut lparens = 0u;
2172
2173         while *self.token != *ket || lparens > 0u {
2174             if *self.token == token::LPAREN { lparens += 1u; }
2175             if *self.token == token::RPAREN { lparens -= 1u; }
2176             ret_val.push(self.parse_matcher(name_idx));
2177         }
2178
2179         self.bump();
2180
2181         return ret_val;
2182     }
2183
2184     pub fn parse_matcher(&self, name_idx: @mut uint) -> matcher {
2185         let lo = self.span.lo;
2186
2187         let m = if *self.token == token::DOLLAR {
2188             self.bump();
2189             if *self.token == token::LPAREN {
2190                 let name_idx_lo = *name_idx;
2191                 self.bump();
2192                 let ms = self.parse_matcher_subseq_upto(name_idx,
2193                                                         &token::RPAREN);
2194                 if ms.len() == 0u {
2195                     self.fatal("repetition body must be nonempty");
2196                 }
2197                 let (sep, zerok) = self.parse_sep_and_zerok();
2198                 match_seq(ms, sep, zerok, name_idx_lo, *name_idx)
2199             } else {
2200                 let bound_to = self.parse_ident();
2201                 self.expect(&token::COLON);
2202                 let nt_name = self.parse_ident();
2203                 let m = match_nonterminal(bound_to, nt_name, *name_idx);
2204                 *name_idx += 1u;
2205                 m
2206             }
2207         } else {
2208             match_tok(self.bump_and_get())
2209         };
2210
2211         return spanned(lo, self.span.hi, m);
2212     }
2213
2214     // parse a prefix-operator expr
2215     pub fn parse_prefix_expr(&self) -> @Expr {
2216         let lo = self.span.lo;
2217         let hi;
2218
2219         let ex;
2220         match *self.token {
2221           token::NOT => {
2222             self.bump();
2223             let e = self.parse_prefix_expr();
2224             hi = e.span.hi;
2225             ex = self.mk_unary(UnNot, e);
2226           }
2227           token::BINOP(b) => {
2228             match b {
2229               token::MINUS => {
2230                 self.bump();
2231                 let e = self.parse_prefix_expr();
2232                 hi = e.span.hi;
2233                 ex = self.mk_unary(UnNeg, e);
2234               }
2235               token::STAR => {
2236                 self.bump();
2237                 let e = self.parse_prefix_expr();
2238                 hi = e.span.hi;
2239                 ex = self.mk_unary(UnDeref, e);
2240               }
2241               token::AND => {
2242                 self.bump();
2243                 let _lt = self.parse_opt_lifetime();
2244                 let m = self.parse_mutability();
2245                 let e = self.parse_prefix_expr();
2246                 hi = e.span.hi;
2247                 // HACK: turn &[...] into a &-evec
2248                 ex = match e.node {
2249                   ExprVec(*) | ExprLit(@codemap::Spanned {
2250                     node: lit_str(_), span: _
2251                   })
2252                   if m == MutImmutable => {
2253                     ExprVstore(e, ExprVstoreSlice)
2254                   }
2255                   ExprVec(*) if m == MutMutable => {
2256                     ExprVstore(e, ExprVstoreMutSlice)
2257                   }
2258                   _ => ExprAddrOf(m, e)
2259                 };
2260               }
2261               _ => return self.parse_dot_or_call_expr()
2262             }
2263           }
2264           token::AT => {
2265             self.bump();
2266             let m = self.parse_mutability();
2267             let e = self.parse_prefix_expr();
2268             hi = e.span.hi;
2269             // HACK: turn @[...] into a @-evec
2270             ex = match e.node {
2271               ExprVec(*) | ExprRepeat(*) if m == MutMutable =>
2272                 ExprVstore(e, ExprVstoreMutBox),
2273               ExprVec(*) |
2274               ExprLit(@codemap::Spanned { node: lit_str(_), span: _}) |
2275               ExprRepeat(*) if m == MutImmutable => ExprVstore(e, ExprVstoreBox),
2276               _ => self.mk_unary(UnBox(m), e)
2277             };
2278           }
2279           token::TILDE => {
2280             self.bump();
2281             let m = self.parse_mutability();
2282             if m != MutImmutable {
2283                 self.obsolete(*self.last_span, ObsoleteMutOwnedPointer);
2284             }
2285
2286             let e = self.parse_prefix_expr();
2287             hi = e.span.hi;
2288             // HACK: turn ~[...] into a ~-evec
2289             ex = match e.node {
2290               ExprVec(*) |
2291               ExprLit(@codemap::Spanned { node: lit_str(_), span: _}) |
2292               ExprRepeat(*) => ExprVstore(e, ExprVstoreUniq),
2293               _ => self.mk_unary(UnUniq, e)
2294             };
2295           }
2296           _ => return self.parse_dot_or_call_expr()
2297         }
2298         return self.mk_expr(lo, hi, ex);
2299     }
2300
2301     // parse an expression of binops
2302     pub fn parse_binops(&self) -> @Expr {
2303         self.parse_more_binops(self.parse_prefix_expr(), 0)
2304     }
2305
2306     // parse an expression of binops of at least min_prec precedence
2307     pub fn parse_more_binops(&self, lhs: @Expr, min_prec: uint) -> @Expr {
2308         if self.expr_is_complete(lhs) { return lhs; }
2309
2310         // Prevent dynamic borrow errors later on by limiting the
2311         // scope of the borrows.
2312         {
2313             let token: &token::Token = self.token;
2314             let restriction: &restriction = self.restriction;
2315             match (token, restriction) {
2316                 (&token::BINOP(token::OR), &RESTRICT_NO_BAR_OP) => return lhs,
2317                 (&token::BINOP(token::OR),
2318                  &RESTRICT_NO_BAR_OR_DOUBLEBAR_OP) => return lhs,
2319                 (&token::OROR, &RESTRICT_NO_BAR_OR_DOUBLEBAR_OP) => return lhs,
2320                 _ => { }
2321             }
2322         }
2323
2324         let cur_opt = token_to_binop(self.token);
2325         match cur_opt {
2326             Some(cur_op) => {
2327                 let cur_prec = operator_prec(cur_op);
2328                 if cur_prec > min_prec {
2329                     self.bump();
2330                     let expr = self.parse_prefix_expr();
2331                     let rhs = self.parse_more_binops(expr, cur_prec);
2332                     let bin = self.mk_expr(lhs.span.lo, rhs.span.hi,
2333                                            self.mk_binary(cur_op, lhs, rhs));
2334                     self.parse_more_binops(bin, min_prec)
2335                 } else {
2336                     lhs
2337                 }
2338             }
2339             None => {
2340                 if as_prec > min_prec && self.eat_keyword(keywords::As) {
2341                     let rhs = self.parse_ty(true);
2342                     let _as = self.mk_expr(lhs.span.lo,
2343                                            rhs.span.hi,
2344                                            ExprCast(lhs, rhs));
2345                     self.parse_more_binops(_as, min_prec)
2346                 } else {
2347                     lhs
2348                 }
2349             }
2350         }
2351     }
2352
2353     // parse an assignment expression....
2354     // actually, this seems to be the main entry point for
2355     // parsing an arbitrary expression.
2356     pub fn parse_assign_expr(&self) -> @Expr {
2357         let lo = self.span.lo;
2358         let lhs = self.parse_binops();
2359         match *self.token {
2360           token::EQ => {
2361               self.bump();
2362               let rhs = self.parse_expr();
2363               self.mk_expr(lo, rhs.span.hi, ExprAssign(lhs, rhs))
2364           }
2365           token::BINOPEQ(op) => {
2366               self.bump();
2367               let rhs = self.parse_expr();
2368               let aop = match op {
2369                   token::PLUS =>    BiAdd,
2370                   token::MINUS =>   BiSub,
2371                   token::STAR =>    BiMul,
2372                   token::SLASH =>   BiDiv,
2373                   token::PERCENT => BiRem,
2374                   token::CARET =>   BiBitXor,
2375                   token::AND =>     BiBitAnd,
2376                   token::OR =>      BiBitOr,
2377                   token::SHL =>     BiShl,
2378                   token::SHR =>     BiShr
2379               };
2380               self.mk_expr(lo, rhs.span.hi,
2381                            self.mk_assign_op(aop, lhs, rhs))
2382           }
2383           token::LARROW => {
2384               self.obsolete(*self.span, ObsoleteBinaryMove);
2385               // Bogus value (but it's an error)
2386               self.bump(); // <-
2387               self.bump(); // rhs
2388               self.bump(); // ;
2389               self.mk_expr(lo, self.span.hi,
2390                            ExprBreak(None))
2391           }
2392           token::DARROW => {
2393             self.obsolete(*self.span, ObsoleteSwap);
2394             self.bump();
2395             // Ignore what we get, this is an error anyway
2396             self.parse_expr();
2397             self.mk_expr(lo, self.span.hi, ExprBreak(None))
2398           }
2399           _ => {
2400               lhs
2401           }
2402         }
2403     }
2404
2405     // parse an 'if' expression ('if' token already eaten)
2406     pub fn parse_if_expr(&self) -> @Expr {
2407         let lo = self.last_span.lo;
2408         let cond = self.parse_expr();
2409         let thn = self.parse_block();
2410         let mut els: Option<@Expr> = None;
2411         let mut hi = thn.span.hi;
2412         if self.eat_keyword(keywords::Else) {
2413             let elexpr = self.parse_else_expr();
2414             els = Some(elexpr);
2415             hi = elexpr.span.hi;
2416         }
2417         self.mk_expr(lo, hi, ExprIf(cond, thn, els))
2418     }
2419
2420     // `|args| { ... }` or `{ ...}` like in `do` expressions
2421     pub fn parse_lambda_block_expr(&self) -> @Expr {
2422         self.parse_lambda_expr_(
2423             || {
2424                 match *self.token {
2425                   token::BINOP(token::OR) | token::OROR => {
2426                     self.parse_fn_block_decl()
2427                   }
2428                   _ => {
2429                     // No argument list - `do foo {`
2430                       ast::fn_decl {
2431                           inputs: ~[],
2432                           output: Ty {
2433                               id: ast::DUMMY_NODE_ID,
2434                               node: ty_infer,
2435                               span: *self.span
2436                           },
2437                           cf: return_val
2438                       }
2439                   }
2440                 }
2441             },
2442             || {
2443                 let blk = self.parse_block();
2444                 self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk))
2445             })
2446     }
2447
2448     // `|args| expr`
2449     pub fn parse_lambda_expr(&self) -> @Expr {
2450         self.parse_lambda_expr_(|| self.parse_fn_block_decl(),
2451                                 || self.parse_expr())
2452     }
2453
2454     // parse something of the form |args| expr
2455     // this is used both in parsing a lambda expr
2456     // and in parsing a block expr as e.g. in for...
2457     pub fn parse_lambda_expr_(&self,
2458                               parse_decl: &fn() -> fn_decl,
2459                               parse_body: &fn() -> @Expr)
2460                               -> @Expr {
2461         let lo = self.last_span.lo;
2462         let decl = parse_decl();
2463         let body = parse_body();
2464         let fakeblock = ast::Block {
2465             view_items: ~[],
2466             stmts: ~[],
2467             expr: Some(body),
2468             id: ast::DUMMY_NODE_ID,
2469             rules: DefaultBlock,
2470             span: body.span,
2471         };
2472
2473         return self.mk_expr(lo, body.span.hi,
2474                             ExprFnBlock(decl, fakeblock));
2475     }
2476
2477     pub fn parse_else_expr(&self) -> @Expr {
2478         if self.eat_keyword(keywords::If) {
2479             return self.parse_if_expr();
2480         } else {
2481             let blk = self.parse_block();
2482             return self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk));
2483         }
2484     }
2485
2486     // parse a 'for' .. 'in' expression ('for' token already eaten)
2487     pub fn parse_for_expr(&self, opt_ident: Option<ast::Ident>) -> @Expr {
2488         // Parse: `for <src_pat> in <src_expr> <src_loop_block>`
2489
2490         let lo = self.last_span.lo;
2491         let pat = self.parse_pat();
2492         self.expect_keyword(keywords::In);
2493         let expr = self.parse_expr();
2494         let loop_block = self.parse_block();
2495         let hi = self.span.hi;
2496
2497         self.mk_expr(lo, hi, ExprForLoop(pat, expr, loop_block, opt_ident))
2498     }
2499
2500
2501     // parse a 'for' or 'do'.
2502     // the 'for' and 'do' expressions parse as calls, but look like
2503     // function calls followed by a closure expression.
2504     pub fn parse_sugary_call_expr(&self, lo: BytePos,
2505                                   keyword: ~str,
2506                                   sugar: CallSugar,
2507                                   ctor: &fn(v: @Expr) -> Expr_)
2508                                   -> @Expr {
2509         // Parse the callee `foo` in
2510         //    for foo || {
2511         //    for foo.bar || {
2512         // etc, or the portion of the call expression before the lambda in
2513         //    for foo() || {
2514         // or
2515         //    for foo.bar(a) || {
2516         // Turn on the restriction to stop at | or || so we can parse
2517         // them as the lambda arguments
2518         let e = self.parse_expr_res(RESTRICT_NO_BAR_OR_DOUBLEBAR_OP);
2519         match e.node {
2520             ExprCall(f, ref args, NoSugar) => {
2521                 let block = self.parse_lambda_block_expr();
2522                 let last_arg = self.mk_expr(block.span.lo, block.span.hi,
2523                                             ctor(block));
2524                 let args = vec::append((*args).clone(), [last_arg]);
2525                 self.mk_expr(lo, block.span.hi, ExprCall(f, args, sugar))
2526             }
2527             ExprMethodCall(_, f, i, ref tps, ref args, NoSugar) => {
2528                 let block = self.parse_lambda_block_expr();
2529                 let last_arg = self.mk_expr(block.span.lo, block.span.hi,
2530                                             ctor(block));
2531                 let args = vec::append((*args).clone(), [last_arg]);
2532                 self.mk_expr(lo, block.span.hi,
2533                              self.mk_method_call(f,
2534                                                  i,
2535                                                  (*tps).clone(),
2536                                                  args,
2537                                                  sugar))
2538             }
2539             ExprField(f, i, ref tps) => {
2540                 let block = self.parse_lambda_block_expr();
2541                 let last_arg = self.mk_expr(block.span.lo, block.span.hi,
2542                                             ctor(block));
2543                 self.mk_expr(lo, block.span.hi,
2544                              self.mk_method_call(f,
2545                                                  i,
2546                                                  (*tps).clone(),
2547                                                  ~[last_arg],
2548                                                  sugar))
2549             }
2550             ExprPath(*) | ExprCall(*) | ExprMethodCall(*) |
2551                 ExprParen(*) => {
2552                 let block = self.parse_lambda_block_expr();
2553                 let last_arg = self.mk_expr(block.span.lo, block.span.hi,
2554                                             ctor(block));
2555                 self.mk_expr(
2556                     lo,
2557                     last_arg.span.hi,
2558                     self.mk_call(e, ~[last_arg], sugar))
2559             }
2560             _ => {
2561                 // There may be other types of expressions that can
2562                 // represent the callee in `for` and `do` expressions
2563                 // but they aren't represented by tests
2564                 debug!("sugary call on %?", e.node);
2565                 self.span_fatal(
2566                     e.span,
2567                     fmt!("`%s` must be followed by a block call", keyword));
2568             }
2569         }
2570     }
2571
2572     pub fn parse_while_expr(&self) -> @Expr {
2573         let lo = self.last_span.lo;
2574         let cond = self.parse_expr();
2575         let body = self.parse_block();
2576         let hi = body.span.hi;
2577         return self.mk_expr(lo, hi, ExprWhile(cond, body));
2578     }
2579
2580     pub fn parse_loop_expr(&self, opt_ident: Option<ast::Ident>) -> @Expr {
2581         // loop headers look like 'loop {' or 'loop unsafe {'
2582         let is_loop_header =
2583             *self.token == token::LBRACE
2584             || (is_ident(&*self.token)
2585                 && self.look_ahead(1, |t| *t == token::LBRACE));
2586
2587         if is_loop_header {
2588             // This is a loop body
2589             let lo = self.last_span.lo;
2590             let body = self.parse_block();
2591             let hi = body.span.hi;
2592             return self.mk_expr(lo, hi, ExprLoop(body, opt_ident));
2593         } else {
2594             // This is a 'continue' expression
2595             // FIXME #9467 rm support for 'loop' here after snapshot
2596             if opt_ident.is_some() {
2597                 self.span_err(*self.last_span,
2598                               "a label may not be used with a `loop` expression");
2599             }
2600
2601             let lo = self.span.lo;
2602             let ex = if self.token_is_lifetime(&*self.token) {
2603                 let lifetime = self.get_lifetime(&*self.token);
2604                 self.bump();
2605                 ExprAgain(Some(lifetime.name))
2606             } else {
2607                 ExprAgain(None)
2608             };
2609             let hi = self.span.hi;
2610             return self.mk_expr(lo, hi, ex);
2611         }
2612     }
2613
2614     // For distingishing between record literals and blocks
2615     fn looking_at_record_literal(&self) -> bool {
2616         *self.token == token::LBRACE &&
2617             (self.look_ahead(1, |t| token::is_keyword(keywords::Mut, t)) ||
2618              (self.look_ahead(1, |t| token::is_plain_ident(t)) &&
2619               self.look_ahead(2, |t| *t == token::COLON)))
2620     }
2621
2622     fn parse_match_expr(&self) -> @Expr {
2623         let lo = self.last_span.lo;
2624         let discriminant = self.parse_expr();
2625         self.commit_expr_expecting(discriminant, token::LBRACE);
2626         let mut arms: ~[Arm] = ~[];
2627         while *self.token != token::RBRACE {
2628             let pats = self.parse_pats();
2629             let mut guard = None;
2630             if self.eat_keyword(keywords::If) {
2631                 guard = Some(self.parse_expr());
2632             }
2633             self.expect(&token::FAT_ARROW);
2634             let expr = self.parse_expr_res(RESTRICT_STMT_EXPR);
2635
2636             let require_comma =
2637                 !classify::expr_is_simple_block(expr)
2638                 && *self.token != token::RBRACE;
2639
2640             if require_comma {
2641                 self.commit_expr(expr, &[token::COMMA], &[token::RBRACE]);
2642             } else {
2643                 self.eat(&token::COMMA);
2644             }
2645
2646             let blk = ast::Block {
2647                 view_items: ~[],
2648                 stmts: ~[],
2649                 expr: Some(expr),
2650                 id: ast::DUMMY_NODE_ID,
2651                 rules: DefaultBlock,
2652                 span: expr.span,
2653             };
2654
2655             arms.push(ast::Arm { pats: pats, guard: guard, body: blk });
2656         }
2657         let hi = self.span.hi;
2658         self.bump();
2659         return self.mk_expr(lo, hi, ExprMatch(discriminant, arms));
2660     }
2661
2662     // parse an expression
2663     pub fn parse_expr(&self) -> @Expr {
2664         return self.parse_expr_res(UNRESTRICTED);
2665     }
2666
2667     // parse an expression, subject to the given restriction
2668     fn parse_expr_res(&self, r: restriction) -> @Expr {
2669         let old = *self.restriction;
2670         *self.restriction = r;
2671         let e = self.parse_assign_expr();
2672         *self.restriction = old;
2673         return e;
2674     }
2675
2676     // parse the RHS of a local variable declaration (e.g. '= 14;')
2677     fn parse_initializer(&self) -> Option<@Expr> {
2678         match *self.token {
2679           token::EQ => {
2680             self.bump();
2681             return Some(self.parse_expr());
2682           }
2683           token::LARROW => {
2684               self.obsolete(*self.span, ObsoleteMoveInit);
2685               self.bump();
2686               self.bump();
2687               return None;
2688           }
2689           _ => {
2690             return None;
2691           }
2692         }
2693     }
2694
2695     // parse patterns, separated by '|' s
2696     fn parse_pats(&self) -> ~[@Pat] {
2697         let mut pats = ~[];
2698         loop {
2699             pats.push(self.parse_pat());
2700             if *self.token == token::BINOP(token::OR) { self.bump(); }
2701             else { return pats; }
2702         };
2703     }
2704
2705     fn parse_pat_vec_elements(
2706         &self,
2707     ) -> (~[@Pat], Option<@Pat>, ~[@Pat]) {
2708         let mut before = ~[];
2709         let mut slice = None;
2710         let mut after = ~[];
2711         let mut first = true;
2712         let mut before_slice = true;
2713
2714         while *self.token != token::RBRACKET {
2715             if first { first = false; }
2716             else { self.expect(&token::COMMA); }
2717
2718             let mut is_slice = false;
2719             if before_slice {
2720                 if *self.token == token::DOTDOT {
2721                     self.bump();
2722                     is_slice = true;
2723                     before_slice = false;
2724                 }
2725             }
2726
2727             let subpat = self.parse_pat();
2728             if is_slice {
2729                 match subpat {
2730                     @ast::Pat { node: PatWild, _ } => (),
2731                     @ast::Pat { node: PatIdent(_, _, _), _ } => (),
2732                     @ast::Pat { span, _ } => self.span_fatal(
2733                         span, "expected an identifier or `_`"
2734                     )
2735                 }
2736                 slice = Some(subpat);
2737             } else {
2738                 if before_slice {
2739                     before.push(subpat);
2740                 } else {
2741                     after.push(subpat);
2742                 }
2743             }
2744         }
2745
2746         (before, slice, after)
2747     }
2748
2749     // parse the fields of a struct-like pattern
2750     fn parse_pat_fields(&self) -> (~[ast::FieldPat], bool) {
2751         let mut fields = ~[];
2752         let mut etc = false;
2753         let mut first = true;
2754         while *self.token != token::RBRACE {
2755             if first { first = false; }
2756             else { self.expect(&token::COMMA); }
2757
2758             if *self.token == token::UNDERSCORE {
2759                 self.bump();
2760                 if *self.token != token::RBRACE {
2761                     self.fatal(
2762                         fmt!(
2763                             "expected `}`, found `%s`",
2764                             self.this_token_to_str()
2765                         )
2766                     );
2767                 }
2768                 etc = true;
2769                 break;
2770             }
2771
2772             let lo1 = self.last_span.lo;
2773             let fieldname = self.parse_ident();
2774             let hi1 = self.last_span.lo;
2775             let fieldpath = ast_util::ident_to_path(mk_sp(lo1, hi1),
2776                                                     fieldname);
2777             let subpat;
2778             if *self.token == token::COLON {
2779                 self.bump();
2780                 subpat = self.parse_pat();
2781             } else {
2782                 subpat = @ast::Pat {
2783                     id: ast::DUMMY_NODE_ID,
2784                     node: PatIdent(BindInfer, fieldpath, None),
2785                     span: *self.last_span
2786                 };
2787             }
2788             fields.push(ast::FieldPat { ident: fieldname, pat: subpat });
2789         }
2790         return (fields, etc);
2791     }
2792
2793     // parse a pattern.
2794     pub fn parse_pat(&self) -> @Pat {
2795         maybe_whole!(self, nt_pat);
2796
2797         let lo = self.span.lo;
2798         let mut hi;
2799         let pat;
2800         match *self.token {
2801             // parse _
2802           token::UNDERSCORE => {
2803             self.bump();
2804             pat = PatWild;
2805             hi = self.last_span.hi;
2806             return @ast::Pat {
2807                 id: ast::DUMMY_NODE_ID,
2808                 node: pat,
2809                 span: mk_sp(lo, hi)
2810             }
2811           }
2812           // parse @pat
2813           token::AT => {
2814             self.bump();
2815             let sub = self.parse_pat();
2816             hi = sub.span.hi;
2817             // HACK: parse @"..." as a literal of a vstore @str
2818             pat = match sub.node {
2819               PatLit(e@@Expr {
2820                 node: ExprLit(@codemap::Spanned {
2821                     node: lit_str(_),
2822                     span: _}), _
2823               }) => {
2824                 let vst = @Expr {
2825                     id: ast::DUMMY_NODE_ID,
2826                     node: ExprVstore(e, ExprVstoreBox),
2827                     span: mk_sp(lo, hi),
2828                 };
2829                 PatLit(vst)
2830               }
2831               _ => PatBox(sub)
2832             };
2833             hi = self.last_span.hi;
2834             return @ast::Pat {
2835                 id: ast::DUMMY_NODE_ID,
2836                 node: pat,
2837                 span: mk_sp(lo, hi)
2838             }
2839           }
2840           token::TILDE => {
2841             // parse ~pat
2842             self.bump();
2843             let sub = self.parse_pat();
2844             hi = sub.span.hi;
2845             // HACK: parse ~"..." as a literal of a vstore ~str
2846             pat = match sub.node {
2847               PatLit(e@@Expr {
2848                 node: ExprLit(@codemap::Spanned {
2849                     node: lit_str(_),
2850                     span: _}), _
2851               }) => {
2852                 let vst = @Expr {
2853                     id: ast::DUMMY_NODE_ID,
2854                     node: ExprVstore(e, ExprVstoreUniq),
2855                     span: mk_sp(lo, hi),
2856                 };
2857                 PatLit(vst)
2858               }
2859               _ => PatUniq(sub)
2860             };
2861             hi = self.last_span.hi;
2862             return @ast::Pat {
2863                 id: ast::DUMMY_NODE_ID,
2864                 node: pat,
2865                 span: mk_sp(lo, hi)
2866             }
2867           }
2868           token::BINOP(token::AND) => {
2869               // parse &pat
2870               let lo = self.span.lo;
2871               self.bump();
2872               let sub = self.parse_pat();
2873               hi = sub.span.hi;
2874               // HACK: parse &"..." as a literal of a borrowed str
2875               pat = match sub.node {
2876                   PatLit(e@@Expr {
2877                       node: ExprLit(@codemap::Spanned {
2878                             node: lit_str(_), span: _}), _
2879                   }) => {
2880                       let vst = @Expr {
2881                           id: ast::DUMMY_NODE_ID,
2882                           node: ExprVstore(e, ExprVstoreSlice),
2883                           span: mk_sp(lo, hi)
2884                       };
2885                       PatLit(vst)
2886                   }
2887               _ => PatRegion(sub)
2888             };
2889             hi = self.last_span.hi;
2890             return @ast::Pat {
2891                 id: ast::DUMMY_NODE_ID,
2892                 node: pat,
2893                 span: mk_sp(lo, hi)
2894             }
2895           }
2896           token::LBRACE => {
2897             self.bump();
2898             let (_, _) = self.parse_pat_fields();
2899             self.bump();
2900             self.obsolete(*self.span, ObsoleteRecordPattern);
2901             pat = PatWild;
2902             hi = self.last_span.hi;
2903             return @ast::Pat {
2904                 id: ast::DUMMY_NODE_ID,
2905                 node: pat,
2906                 span: mk_sp(lo, hi)
2907             }
2908           }
2909           token::LPAREN => {
2910             // parse (pat,pat,pat,...) as tuple
2911             self.bump();
2912             if *self.token == token::RPAREN {
2913                 hi = self.span.hi;
2914                 self.bump();
2915                 let lit = @codemap::Spanned {
2916                     node: lit_nil,
2917                     span: mk_sp(lo, hi)};
2918                 let expr = self.mk_expr(lo, hi, ExprLit(lit));
2919                 pat = PatLit(expr);
2920             } else {
2921                 let mut fields = ~[self.parse_pat()];
2922                 if self.look_ahead(1, |t| *t != token::RPAREN) {
2923                     while *self.token == token::COMMA {
2924                         self.bump();
2925                         fields.push(self.parse_pat());
2926                     }
2927                 }
2928                 if fields.len() == 1 { self.expect(&token::COMMA); }
2929                 self.expect(&token::RPAREN);
2930                 pat = PatTup(fields);
2931             }
2932             hi = self.last_span.hi;
2933             return @ast::Pat {
2934                 id: ast::DUMMY_NODE_ID,
2935                 node: pat,
2936                 span: mk_sp(lo, hi)
2937             }
2938           }
2939           token::LBRACKET => {
2940             // parse [pat,pat,...] as vector pattern
2941             self.bump();
2942             let (before, slice, after) =
2943                 self.parse_pat_vec_elements();
2944
2945             self.expect(&token::RBRACKET);
2946             pat = ast::PatVec(before, slice, after);
2947             hi = self.last_span.hi;
2948             return @ast::Pat {
2949                 id: ast::DUMMY_NODE_ID,
2950                 node: pat,
2951                 span: mk_sp(lo, hi)
2952             }
2953           }
2954           _ => {}
2955         }
2956
2957         let tok = self.token;
2958         if !is_ident_or_path(tok)
2959                 || self.is_keyword(keywords::True)
2960                 || self.is_keyword(keywords::False) {
2961             // Parse an expression pattern or exp .. exp.
2962             //
2963             // These expressions are limited to literals (possibly
2964             // preceded by unary-minus) or identifiers.
2965             let val = self.parse_literal_maybe_minus();
2966             if self.eat(&token::DOTDOT) {
2967                 let end = if is_ident_or_path(tok) {
2968                     let path = self.parse_path(LifetimeAndTypesWithColons)
2969                                    .path;
2970                     let hi = self.span.hi;
2971                     self.mk_expr(lo, hi, ExprPath(path))
2972                 } else {
2973                     self.parse_literal_maybe_minus()
2974                 };
2975                 pat = PatRange(val, end);
2976             } else {
2977                 pat = PatLit(val);
2978             }
2979         } else if self.eat_keyword(keywords::Ref) {
2980             // parse ref pat
2981             let mutbl = self.parse_mutability();
2982             pat = self.parse_pat_ident(BindByRef(mutbl));
2983         } else {
2984             let can_be_enum_or_struct = do self.look_ahead(1) |t| {
2985                 match *t {
2986                     token::LPAREN | token::LBRACKET | token::LT |
2987                     token::LBRACE | token::MOD_SEP => true,
2988                     _ => false,
2989                 }
2990             };
2991
2992             if self.look_ahead(1, |t| *t == token::DOTDOT) {
2993                 let start = self.parse_expr_res(RESTRICT_NO_BAR_OP);
2994                 self.eat(&token::DOTDOT);
2995                 let end = self.parse_expr_res(RESTRICT_NO_BAR_OP);
2996                 pat = PatRange(start, end);
2997             } else if is_plain_ident(&*self.token) && !can_be_enum_or_struct {
2998                 let name = self.parse_path(NoTypesAllowed).path;
2999                 let sub;
3000                 if self.eat(&token::AT) {
3001                     // parse foo @ pat
3002                     sub = Some(self.parse_pat());
3003                 } else {
3004                     // or just foo
3005                     sub = None;
3006                 }
3007                 pat = PatIdent(BindInfer, name, sub);
3008             } else {
3009                 // parse an enum pat
3010                 let enum_path = self.parse_path(LifetimeAndTypesWithColons)
3011                                     .path;
3012                 match *self.token {
3013                     token::LBRACE => {
3014                         self.bump();
3015                         let (fields, etc) =
3016                             self.parse_pat_fields();
3017                         self.bump();
3018                         pat = PatStruct(enum_path, fields, etc);
3019                     }
3020                     _ => {
3021                         let mut args: ~[@Pat] = ~[];
3022                         match *self.token {
3023                           token::LPAREN => {
3024                             let is_star = do self.look_ahead(1) |t| {
3025                                 match *t {
3026                                     token::BINOP(token::STAR) => true,
3027                                     _ => false,
3028                                 }
3029                             };
3030                             if is_star {
3031                                 // This is a "top constructor only" pat
3032                                 self.bump();
3033                                 self.bump();
3034                                 self.expect(&token::RPAREN);
3035                                 pat = PatEnum(enum_path, None);
3036                             } else {
3037                                 args = self.parse_unspanned_seq(
3038                                     &token::LPAREN,
3039                                     &token::RPAREN,
3040                                     seq_sep_trailing_disallowed(token::COMMA),
3041                                     |p| p.parse_pat()
3042                                 );
3043                                 pat = PatEnum(enum_path, Some(args));
3044                             }
3045                           },
3046                           _ => {
3047                               if enum_path.segments.len() == 1 {
3048                                   // it could still be either an enum
3049                                   // or an identifier pattern, resolve
3050                                   // will sort it out:
3051                                   pat = PatIdent(BindInfer,
3052                                                   enum_path,
3053                                                   None);
3054                               } else {
3055                                   pat = PatEnum(enum_path, Some(args));
3056                               }
3057                           }
3058                         }
3059                     }
3060                 }
3061             }
3062         }
3063         hi = self.last_span.hi;
3064         @ast::Pat {
3065             id: ast::DUMMY_NODE_ID,
3066             node: pat,
3067             span: mk_sp(lo, hi),
3068         }
3069     }
3070
3071     // parse ident or ident @ pat
3072     // used by the copy foo and ref foo patterns to give a good
3073     // error message when parsing mistakes like ref foo(a,b)
3074     fn parse_pat_ident(&self,
3075                        binding_mode: ast::BindingMode)
3076                        -> ast::Pat_ {
3077         if !is_plain_ident(&*self.token) {
3078             self.span_fatal(*self.last_span,
3079                             "expected identifier, found path");
3080         }
3081         // why a path here, and not just an identifier?
3082         let name = self.parse_path(NoTypesAllowed).path;
3083         let sub = if self.eat(&token::AT) {
3084             Some(self.parse_pat())
3085         } else {
3086             None
3087         };
3088
3089         // just to be friendly, if they write something like
3090         //   ref Some(i)
3091         // we end up here with ( as the current token.  This shortly
3092         // leads to a parse error.  Note that if there is no explicit
3093         // binding mode then we do not end up here, because the lookahead
3094         // will direct us over to parse_enum_variant()
3095         if *self.token == token::LPAREN {
3096             self.span_fatal(
3097                 *self.last_span,
3098                 "expected identifier, found enum pattern");
3099         }
3100
3101         PatIdent(binding_mode, name, sub)
3102     }
3103
3104     // parse a local variable declaration
3105     fn parse_local(&self, is_mutbl: bool) -> @Local {
3106         let lo = self.span.lo;
3107         let pat = self.parse_pat();
3108
3109         if is_mutbl && !ast_util::pat_is_ident(pat) {
3110             self.obsolete(*self.span, ObsoleteMutWithMultipleBindings)
3111         }
3112
3113         let mut ty = Ty {
3114             id: ast::DUMMY_NODE_ID,
3115             node: ty_infer,
3116             span: mk_sp(lo, lo),
3117         };
3118         if self.eat(&token::COLON) { ty = self.parse_ty(false); }
3119         let init = self.parse_initializer();
3120         @ast::Local {
3121             is_mutbl: is_mutbl,
3122             ty: ty,
3123             pat: pat,
3124             init: init,
3125             id: ast::DUMMY_NODE_ID,
3126             span: mk_sp(lo, self.last_span.hi),
3127         }
3128     }
3129
3130     // parse a "let" stmt
3131     fn parse_let(&self) -> @Decl {
3132         let is_mutbl = self.eat_keyword(keywords::Mut);
3133         let lo = self.span.lo;
3134         let local = self.parse_local(is_mutbl);
3135         while self.eat(&token::COMMA) {
3136             let _ = self.parse_local(is_mutbl);
3137             self.obsolete(*self.span, ObsoleteMultipleLocalDecl);
3138         }
3139         return @spanned(lo, self.last_span.hi, DeclLocal(local));
3140     }
3141
3142     // parse a structure field
3143     fn parse_name_and_ty(&self,
3144                          pr: visibility,
3145                          attrs: ~[Attribute]) -> @struct_field {
3146         let lo = self.span.lo;
3147         if !is_plain_ident(&*self.token) {
3148             self.fatal("expected ident");
3149         }
3150         let name = self.parse_ident();
3151         self.expect(&token::COLON);
3152         let ty = self.parse_ty(false);
3153         @spanned(lo, self.last_span.hi, ast::struct_field_ {
3154             kind: named_field(name, pr),
3155             id: ast::DUMMY_NODE_ID,
3156             ty: ty,
3157             attrs: attrs,
3158         })
3159     }
3160
3161     // parse a statement. may include decl.
3162     // precondition: any attributes are parsed already
3163     pub fn parse_stmt(&self, item_attrs: ~[Attribute]) -> @Stmt {
3164         maybe_whole!(self, nt_stmt);
3165
3166         fn check_expected_item(p: &Parser, found_attrs: bool) {
3167             // If we have attributes then we should have an item
3168             if found_attrs {
3169                 p.span_err(*p.last_span, "expected item after attributes");
3170             }
3171         }
3172
3173         let lo = self.span.lo;
3174         if self.is_keyword(keywords::Let) {
3175             check_expected_item(self, !item_attrs.is_empty());
3176             self.expect_keyword(keywords::Let);
3177             let decl = self.parse_let();
3178             return @spanned(lo, decl.span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID));
3179         } else if is_ident(&*self.token)
3180             && !token::is_any_keyword(self.token)
3181             && self.look_ahead(1, |t| *t == token::NOT) {
3182             // parse a macro invocation. Looks like there's serious
3183             // overlap here; if this clause doesn't catch it (and it
3184             // won't, for brace-delimited macros) it will fall through
3185             // to the macro clause of parse_item_or_view_item. This
3186             // could use some cleanup, it appears to me.
3187
3188             // whoops! I now have a guess: I'm guessing the "parens-only"
3189             // rule here is deliberate, to allow macro users to use parens
3190             // for things that should be parsed as stmt_mac, and braces
3191             // for things that should expand into items. Tricky, and
3192             // somewhat awkward... and probably undocumented. Of course,
3193             // I could just be wrong.
3194
3195             check_expected_item(self, !item_attrs.is_empty());
3196
3197             // Potential trouble: if we allow macros with paths instead of
3198             // idents, we'd need to look ahead past the whole path here...
3199             let pth = self.parse_path(NoTypesAllowed).path;
3200             self.bump();
3201
3202             let id = if *self.token == token::LPAREN {
3203                 token::special_idents::invalid // no special identifier
3204             } else {
3205                 self.parse_ident()
3206             };
3207
3208             let tts = self.parse_unspanned_seq(
3209                 &token::LPAREN,
3210                 &token::RPAREN,
3211                 seq_sep_none(),
3212                 |p| p.parse_token_tree()
3213             );
3214             let hi = self.span.hi;
3215
3216             if id == token::special_idents::invalid {
3217                 return @spanned(lo, hi, StmtMac(
3218                     spanned(lo, hi, mac_invoc_tt(pth, tts, EMPTY_CTXT)), false));
3219             } else {
3220                 // if it has a special ident, it's definitely an item
3221                 return @spanned(lo, hi, StmtDecl(
3222                     @spanned(lo, hi, DeclItem(
3223                         self.mk_item(
3224                             lo, hi, id /*id is good here*/,
3225                             item_mac(spanned(lo, hi, mac_invoc_tt(pth, tts, EMPTY_CTXT))),
3226                             inherited, ~[/*no attrs*/]))),
3227                     ast::DUMMY_NODE_ID));
3228             }
3229
3230         } else {
3231             let found_attrs = !item_attrs.is_empty();
3232             match self.parse_item_or_view_item(item_attrs, false) {
3233                 iovi_item(i) => {
3234                     let hi = i.span.hi;
3235                     let decl = @spanned(lo, hi, DeclItem(i));
3236                     return @spanned(lo, hi, StmtDecl(decl, ast::DUMMY_NODE_ID));
3237                 }
3238                 iovi_view_item(vi) => {
3239                     self.span_fatal(vi.span,
3240                                     "view items must be declared at the top of the block");
3241                 }
3242                 iovi_foreign_item(_) => {
3243                     self.fatal("foreign items are not allowed here");
3244                 }
3245                 iovi_none(_) => { /* fallthrough */ }
3246             }
3247
3248             check_expected_item(self, found_attrs);
3249
3250             // Remainder are line-expr stmts.
3251             let e = self.parse_expr_res(RESTRICT_STMT_EXPR);
3252             return @spanned(lo, e.span.hi, StmtExpr(e, ast::DUMMY_NODE_ID));
3253         }
3254     }
3255
3256     // is this expression a successfully-parsed statement?
3257     fn expr_is_complete(&self, e: @Expr) -> bool {
3258         return *self.restriction == RESTRICT_STMT_EXPR &&
3259             !classify::expr_requires_semi_to_be_stmt(e);
3260     }
3261
3262     // parse a block. No inner attrs are allowed.
3263     pub fn parse_block(&self) -> Block {
3264         maybe_whole!(deref self, nt_block);
3265
3266         let lo = self.span.lo;
3267         if self.eat_keyword(keywords::Unsafe) {
3268             self.obsolete(*self.span, ObsoleteUnsafeBlock);
3269         }
3270         self.expect(&token::LBRACE);
3271
3272         return self.parse_block_tail_(lo, DefaultBlock, ~[]);
3273     }
3274
3275     // parse a block. Inner attrs are allowed.
3276     fn parse_inner_attrs_and_block(&self)
3277         -> (~[Attribute], Block) {
3278
3279         maybe_whole!(pair_empty self, nt_block);
3280
3281         let lo = self.span.lo;
3282         if self.eat_keyword(keywords::Unsafe) {
3283             self.obsolete(*self.span, ObsoleteUnsafeBlock);
3284         }
3285         self.expect(&token::LBRACE);
3286         let (inner, next) = self.parse_inner_attrs_and_next();
3287
3288         (inner, self.parse_block_tail_(lo, DefaultBlock, next))
3289     }
3290
3291     // Precondition: already parsed the '{' or '#{'
3292     // I guess that also means "already parsed the 'impure'" if
3293     // necessary, and this should take a qualifier.
3294     // some blocks start with "#{"...
3295     fn parse_block_tail(&self, lo: BytePos, s: BlockCheckMode) -> Block {
3296         self.parse_block_tail_(lo, s, ~[])
3297     }
3298
3299     // parse the rest of a block expression or function body
3300     fn parse_block_tail_(&self, lo: BytePos, s: BlockCheckMode,
3301                          first_item_attrs: ~[Attribute]) -> Block {
3302         let mut stmts = ~[];
3303         let mut expr = None;
3304
3305         // wouldn't it be more uniform to parse view items only, here?
3306         let ParsedItemsAndViewItems {
3307             attrs_remaining: attrs_remaining,
3308             view_items: view_items,
3309             items: items,
3310             _
3311         } = self.parse_items_and_view_items(first_item_attrs,
3312                                             false, false);
3313
3314         for item in items.iter() {
3315             let decl = @spanned(item.span.lo, item.span.hi, DeclItem(*item));
3316             stmts.push(@spanned(item.span.lo, item.span.hi,
3317                                 StmtDecl(decl, ast::DUMMY_NODE_ID)));
3318         }
3319
3320         let mut attributes_box = attrs_remaining;
3321
3322         while (*self.token != token::RBRACE) {
3323             // parsing items even when they're not allowed lets us give
3324             // better error messages and recover more gracefully.
3325             attributes_box.push_all(self.parse_outer_attributes());
3326             match *self.token {
3327                 token::SEMI => {
3328                     if !attributes_box.is_empty() {
3329                         self.span_err(*self.last_span, "expected item after attributes");
3330                         attributes_box = ~[];
3331                     }
3332                     self.bump(); // empty
3333                 }
3334                 token::RBRACE => {
3335                     // fall through and out.
3336                 }
3337                 _ => {
3338                     let stmt = self.parse_stmt(attributes_box);
3339                     attributes_box = ~[];
3340                     match stmt.node {
3341                         StmtExpr(e, stmt_id) => {
3342                             // expression without semicolon
3343                             if classify::stmt_ends_with_semi(stmt) {
3344                                 // Just check for errors and recover; do not eat semicolon yet.
3345                                 self.commit_stmt(stmt, &[], &[token::SEMI, token::RBRACE]);
3346                             }
3347
3348                             match *self.token {
3349                                 token::SEMI => {
3350                                     self.bump();
3351                                     stmts.push(@codemap::Spanned {
3352                                         node: StmtSemi(e, stmt_id),
3353                                         span: stmt.span,
3354                                     });
3355                                 }
3356                                 token::RBRACE => {
3357                                     expr = Some(e);
3358                                 }
3359                                 _ => {
3360                                     stmts.push(stmt);
3361                                 }
3362                             }
3363                         }
3364                         StmtMac(ref m, _) => {
3365                             // statement macro; might be an expr
3366                             let has_semi;
3367                             match *self.token {
3368                                 token::SEMI => {
3369                                     has_semi = true;
3370                                 }
3371                                 token::RBRACE => {
3372                                     // if a block ends in `m!(arg)` without
3373                                     // a `;`, it must be an expr
3374                                     has_semi = false;
3375                                     expr = Some(
3376                                         self.mk_mac_expr(stmt.span.lo,
3377                                                          stmt.span.hi,
3378                                                          m.node.clone()));
3379                                 }
3380                                 _ => {
3381                                     has_semi = false;
3382                                     stmts.push(stmt);
3383                                 }
3384                             }
3385
3386                             if has_semi {
3387                                 self.bump();
3388                                 stmts.push(@codemap::Spanned {
3389                                     node: StmtMac((*m).clone(), true),
3390                                     span: stmt.span,
3391                                 });
3392                             }
3393                         }
3394                         _ => { // all other kinds of statements:
3395                             stmts.push(stmt);
3396
3397                             if classify::stmt_ends_with_semi(stmt) {
3398                                 self.commit_stmt_expecting(stmt, token::SEMI);
3399                             }
3400                         }
3401                     }
3402                 }
3403             }
3404         }
3405
3406         if !attributes_box.is_empty() {
3407             self.span_err(*self.last_span, "expected item after attributes");
3408         }
3409
3410         let hi = self.span.hi;
3411         self.bump();
3412         ast::Block {
3413             view_items: view_items,
3414             stmts: stmts,
3415             expr: expr,
3416             id: ast::DUMMY_NODE_ID,
3417             rules: s,
3418             span: mk_sp(lo, hi),
3419         }
3420     }
3421
3422     fn parse_optional_purity(&self) -> ast::purity {
3423         if self.eat_keyword(keywords::Pure) {
3424             self.obsolete(*self.last_span, ObsoletePurity);
3425             ast::impure_fn
3426         } else if self.eat_keyword(keywords::Unsafe) {
3427             ast::unsafe_fn
3428         } else {
3429             ast::impure_fn
3430         }
3431     }
3432
3433     fn parse_optional_onceness(&self) -> ast::Onceness {
3434         if self.eat_keyword(keywords::Once) { ast::Once } else { ast::Many }
3435     }
3436
3437     // matches optbounds = ( ( : ( boundseq )? )? )
3438     // where   boundseq  = ( bound + boundseq ) | bound
3439     // and     bound     = 'static | ty
3440     // Returns "None" if there's no colon (e.g. "T");
3441     // Returns "Some(Empty)" if there's a colon but nothing after (e.g. "T:")
3442     // Returns "Some(stuff)" otherwise (e.g. "T:stuff").
3443     // NB: The None/Some distinction is important for issue #7264.
3444     fn parse_optional_ty_param_bounds(&self) -> Option<OptVec<TyParamBound>> {
3445         if !self.eat(&token::COLON) {
3446             return None;
3447         }
3448
3449         let mut result = opt_vec::Empty;
3450         loop {
3451             match *self.token {
3452                 token::LIFETIME(lifetime) => {
3453                     if "static" == self.id_to_str(lifetime) {
3454                         result.push(RegionTyParamBound);
3455                     } else {
3456                         self.span_err(*self.span,
3457                                       "`'static` is the only permissible region bound here");
3458                     }
3459                     self.bump();
3460                 }
3461                 token::MOD_SEP | token::IDENT(*) => {
3462                     let tref = self.parse_trait_ref();
3463                     result.push(TraitTyParamBound(tref));
3464                 }
3465                 _ => break,
3466             }
3467
3468             if !self.eat(&token::BINOP(token::PLUS)) {
3469                 break;
3470             }
3471         }
3472
3473         return Some(result);
3474     }
3475
3476     // matches typaram = IDENT optbounds
3477     fn parse_ty_param(&self) -> TyParam {
3478         let ident = self.parse_ident();
3479         let opt_bounds = self.parse_optional_ty_param_bounds();
3480         // For typarams we don't care about the difference b/w "<T>" and "<T:>".
3481         let bounds = opt_bounds.unwrap_or_default();
3482         ast::TyParam { ident: ident, id: ast::DUMMY_NODE_ID, bounds: bounds }
3483     }
3484
3485     // parse a set of optional generic type parameter declarations
3486     // matches generics = ( ) | ( < > ) | ( < typaramseq ( , )? > ) | ( < lifetimes ( , )? > )
3487     //                  | ( < lifetimes , typaramseq ( , )? > )
3488     // where   typaramseq = ( typaram ) | ( typaram , typaramseq )
3489     pub fn parse_generics(&self) -> ast::Generics {
3490         if self.eat(&token::LT) {
3491             let lifetimes = self.parse_lifetimes();
3492             let ty_params = self.parse_seq_to_gt(
3493                 Some(token::COMMA),
3494                 |p| p.parse_ty_param());
3495             ast::Generics { lifetimes: lifetimes, ty_params: ty_params }
3496         } else {
3497             ast_util::empty_generics()
3498         }
3499     }
3500
3501     // parse a generic use site
3502     fn parse_generic_values(&self) -> (OptVec<ast::Lifetime>, ~[Ty]) {
3503         if !self.eat(&token::LT) {
3504             (opt_vec::Empty, ~[])
3505         } else {
3506             self.parse_generic_values_after_lt()
3507         }
3508     }
3509
3510     fn parse_generic_values_after_lt(&self) -> (OptVec<ast::Lifetime>, ~[Ty]) {
3511         let lifetimes = self.parse_lifetimes();
3512         let result = self.parse_seq_to_gt(
3513             Some(token::COMMA),
3514             |p| p.parse_ty(false));
3515         (lifetimes, opt_vec::take_vec(result))
3516     }
3517
3518     // parse the argument list and result type of a function declaration
3519     pub fn parse_fn_decl(&self) -> fn_decl {
3520         let args: ~[arg] =
3521             self.parse_unspanned_seq(
3522                 &token::LPAREN,
3523                 &token::RPAREN,
3524                 seq_sep_trailing_disallowed(token::COMMA),
3525                 |p| p.parse_arg()
3526             );
3527
3528         let (ret_style, ret_ty) = self.parse_ret_ty();
3529         ast::fn_decl {
3530             inputs: args,
3531             output: ret_ty,
3532             cf: ret_style,
3533         }
3534     }
3535
3536     fn is_self_ident(&self) -> bool {
3537         match *self.token {
3538           token::IDENT(id, false) => id.name == special_idents::self_.name,
3539           _ => false
3540         }
3541     }
3542
3543     fn expect_self_ident(&self) {
3544         if !self.is_self_ident() {
3545             self.fatal(
3546                 fmt!(
3547                     "expected `self` but found `%s`",
3548                     self.this_token_to_str()
3549                 )
3550             );
3551         }
3552         self.bump();
3553     }
3554
3555     // parse the argument list and result type of a function
3556     // that may have a self type.
3557     fn parse_fn_decl_with_self(
3558         &self,
3559         parse_arg_fn:
3560         &fn(&Parser) -> arg
3561     ) -> (explicit_self, fn_decl) {
3562         fn maybe_parse_explicit_self(
3563             cnstr: &fn(v: Mutability) -> ast::explicit_self_,
3564             p: &Parser
3565         ) -> ast::explicit_self_ {
3566             // We need to make sure it isn't a mode or a type
3567             if p.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) ||
3568                 ((p.look_ahead(1, |t| token::is_keyword(keywords::Const, t)) ||
3569                   p.look_ahead(1, |t| token::is_keyword(keywords::Mut, t))) &&
3570                  p.look_ahead(2, |t| token::is_keyword(keywords::Self, t))) {
3571
3572                 p.bump();
3573                 let mutability = p.parse_mutability();
3574                 p.expect_self_ident();
3575                 cnstr(mutability)
3576             } else {
3577                 sty_static
3578             }
3579         }
3580
3581         fn maybe_parse_borrowed_explicit_self(this: &Parser) -> ast::explicit_self_ {
3582             // The following things are possible to see here:
3583             //
3584             //     fn(&self)
3585             //     fn(&mut self)
3586             //     fn(&'lt self)
3587             //     fn(&'lt mut self)
3588             //
3589             // We already know that the current token is `&`.
3590
3591             if this.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) {
3592                 this.bump();
3593                 this.expect_self_ident();
3594                 sty_region(None, MutImmutable)
3595             } else if this.look_ahead(1, |t| this.token_is_mutability(t)) &&
3596                     this.look_ahead(2,
3597                                     |t| token::is_keyword(keywords::Self,
3598                                                           t)) {
3599                 this.bump();
3600                 let mutability = this.parse_mutability();
3601                 this.expect_self_ident();
3602                 sty_region(None, mutability)
3603             } else if this.look_ahead(1, |t| this.token_is_lifetime(t)) &&
3604                        this.look_ahead(2,
3605                                        |t| token::is_keyword(keywords::Self,
3606                                                              t)) {
3607                 this.bump();
3608                 let lifetime = this.parse_lifetime();
3609                 this.expect_self_ident();
3610                 sty_region(Some(lifetime), MutImmutable)
3611             } else if this.look_ahead(1, |t| this.token_is_lifetime(t)) &&
3612                       this.look_ahead(2, |t| this.token_is_mutability(t)) &&
3613                       this.look_ahead(3, |t| token::is_keyword(keywords::Self,
3614                                                                t)) {
3615                 this.bump();
3616                 let lifetime = this.parse_lifetime();
3617                 let mutability = this.parse_mutability();
3618                 this.expect_self_ident();
3619                 sty_region(Some(lifetime), mutability)
3620             } else {
3621                 sty_static
3622             }
3623         }
3624
3625         self.expect(&token::LPAREN);
3626
3627         // A bit of complexity and lookahead is needed here in order to be
3628         // backwards compatible.
3629         let lo = self.span.lo;
3630         let explicit_self = match *self.token {
3631           token::BINOP(token::AND) => {
3632             maybe_parse_borrowed_explicit_self(self)
3633           }
3634           token::AT => {
3635             maybe_parse_explicit_self(sty_box, self)
3636           }
3637           token::TILDE => {
3638             maybe_parse_explicit_self(|mutability| {
3639                 if mutability != MutImmutable {
3640                     self.obsolete(*self.last_span, ObsoleteMutOwnedPointer);
3641                 }
3642                 sty_uniq
3643             }, self)
3644           }
3645           token::IDENT(*) if self.is_self_ident() => {
3646             self.bump();
3647             sty_value
3648           }
3649           token::BINOP(token::STAR) => {
3650             // Possibly "*self" or "*mut self" -- not supported. Try to avoid
3651             // emitting cryptic "unexpected token" errors.
3652             self.bump();
3653             if self.token_is_mutability(self.token) {
3654                 self.bump();
3655             }
3656             if self.is_self_ident() {
3657                 self.span_err(*self.span, "cannot pass self by unsafe pointer");
3658                 self.bump();
3659             }
3660             sty_value
3661           }
3662           _ => {
3663             sty_static
3664           }
3665         };
3666
3667         // If we parsed a self type, expect a comma before the argument list.
3668         let fn_inputs;
3669         if explicit_self != sty_static {
3670             match *self.token {
3671                 token::COMMA => {
3672                     self.bump();
3673                     let sep = seq_sep_trailing_disallowed(token::COMMA);
3674                     fn_inputs = self.parse_seq_to_before_end(
3675                         &token::RPAREN,
3676                         sep,
3677                         parse_arg_fn
3678                     );
3679                 }
3680                 token::RPAREN => {
3681                     fn_inputs = ~[];
3682                 }
3683                 _ => {
3684                     self.fatal(
3685                         fmt!(
3686                             "expected `,` or `)`, found `%s`",
3687                             self.this_token_to_str()
3688                         )
3689                     );
3690                 }
3691             }
3692         } else {
3693             let sep = seq_sep_trailing_disallowed(token::COMMA);
3694             fn_inputs = self.parse_seq_to_before_end(
3695                 &token::RPAREN,
3696                 sep,
3697                 parse_arg_fn
3698             );
3699         }
3700
3701         self.expect(&token::RPAREN);
3702
3703         let hi = self.span.hi;
3704
3705         let (ret_style, ret_ty) = self.parse_ret_ty();
3706
3707         let fn_decl = ast::fn_decl {
3708             inputs: fn_inputs,
3709             output: ret_ty,
3710             cf: ret_style
3711         };
3712
3713         (spanned(lo, hi, explicit_self), fn_decl)
3714     }
3715
3716     // parse the |arg, arg| header on a lambda
3717     fn parse_fn_block_decl(&self) -> fn_decl {
3718         let inputs_captures = {
3719             if self.eat(&token::OROR) {
3720                 ~[]
3721             } else {
3722                 self.parse_unspanned_seq(
3723                     &token::BINOP(token::OR),
3724                     &token::BINOP(token::OR),
3725                     seq_sep_trailing_disallowed(token::COMMA),
3726                     |p| p.parse_fn_block_arg()
3727                 )
3728             }
3729         };
3730         let output = if self.eat(&token::RARROW) {
3731             self.parse_ty(false)
3732         } else {
3733             Ty { id: ast::DUMMY_NODE_ID, node: ty_infer, span: *self.span }
3734         };
3735
3736         ast::fn_decl {
3737             inputs: inputs_captures,
3738             output: output,
3739             cf: return_val,
3740         }
3741     }
3742
3743     // parse the name and optional generic types of a function header.
3744     fn parse_fn_header(&self) -> (Ident, ast::Generics) {
3745         let id = self.parse_ident();
3746         let generics = self.parse_generics();
3747         (id, generics)
3748     }
3749
3750     fn mk_item(&self, lo: BytePos, hi: BytePos, ident: Ident,
3751                node: item_, vis: visibility,
3752                attrs: ~[Attribute]) -> @item {
3753         @ast::item { ident: ident,
3754                      attrs: attrs,
3755                      id: ast::DUMMY_NODE_ID,
3756                      node: node,
3757                      vis: vis,
3758                      span: mk_sp(lo, hi) }
3759     }
3760
3761     // parse an item-position function declaration.
3762     fn parse_item_fn(&self, purity: purity, abis: AbiSet) -> item_info {
3763         let (ident, generics) = self.parse_fn_header();
3764         let decl = self.parse_fn_decl();
3765         let (inner_attrs, body) = self.parse_inner_attrs_and_block();
3766         (ident,
3767          item_fn(decl, purity, abis, generics, body),
3768          Some(inner_attrs))
3769     }
3770
3771     // parse a method in a trait impl
3772     fn parse_method(&self) -> @method {
3773         let attrs = self.parse_outer_attributes();
3774         let lo = self.span.lo;
3775
3776         let visa = self.parse_visibility();
3777         let pur = self.parse_fn_purity();
3778         let ident = self.parse_ident();
3779         let generics = self.parse_generics();
3780         let (explicit_self, decl) = do self.parse_fn_decl_with_self() |p| {
3781             p.parse_arg()
3782         };
3783
3784         let (inner_attrs, body) = self.parse_inner_attrs_and_block();
3785         let hi = body.span.hi;
3786         let attrs = vec::append(attrs, inner_attrs);
3787         @ast::method {
3788             ident: ident,
3789             attrs: attrs,
3790             generics: generics,
3791             explicit_self: explicit_self,
3792             purity: pur,
3793             decl: decl,
3794             body: body,
3795             id: ast::DUMMY_NODE_ID,
3796             span: mk_sp(lo, hi),
3797             self_id: ast::DUMMY_NODE_ID,
3798             vis: visa,
3799         }
3800     }
3801
3802     // parse trait Foo { ... }
3803     fn parse_item_trait(&self) -> item_info {
3804         let ident = self.parse_ident();
3805         self.parse_region_param();
3806         let tps = self.parse_generics();
3807
3808         // Parse traits, if necessary.
3809         let traits;
3810         if *self.token == token::COLON {
3811             self.bump();
3812             traits = self.parse_trait_ref_list(&token::LBRACE);
3813         } else {
3814             traits = ~[];
3815         }
3816
3817         let meths = self.parse_trait_methods();
3818         (ident, item_trait(tps, traits, meths), None)
3819     }
3820
3821     // Parses two variants (with the region/type params always optional):
3822     //    impl<T> Foo { ... }
3823     //    impl<T> ToStr for ~[T] { ... }
3824     fn parse_item_impl(&self) -> item_info {
3825         // First, parse type parameters if necessary.
3826         let generics = self.parse_generics();
3827
3828         // This is a new-style impl declaration.
3829         // XXX: clownshoes
3830         let ident = special_idents::clownshoes_extensions;
3831
3832         // Special case: if the next identifier that follows is '(', don't
3833         // allow this to be parsed as a trait.
3834         let could_be_trait = *self.token != token::LPAREN;
3835
3836         // Parse the trait.
3837         let mut ty = self.parse_ty(false);
3838
3839         // Parse traits, if necessary.
3840         let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) {
3841             // New-style trait. Reinterpret the type as a trait.
3842             let opt_trait_ref = match ty.node {
3843                 ty_path(ref path, None, node_id) => {
3844                     Some(trait_ref {
3845                         path: /* bad */ (*path).clone(),
3846                         ref_id: node_id
3847                     })
3848                 }
3849                 ty_path(*) => {
3850                     self.span_err(ty.span,
3851                                   "bounded traits are only valid in type position");
3852                     None
3853                 }
3854                 _ => {
3855                     self.span_err(ty.span, "not a trait");
3856                     None
3857                 }
3858             };
3859
3860             ty = self.parse_ty(false);
3861             opt_trait_ref
3862         } else if self.eat(&token::COLON) {
3863             self.obsolete(*self.span, ObsoleteImplSyntax);
3864             Some(self.parse_trait_ref())
3865         } else {
3866             None
3867         };
3868
3869         let mut meths = ~[];
3870         if self.eat(&token::SEMI) {
3871             self.obsolete(*self.last_span, ObsoleteEmptyImpl);
3872         } else {
3873             self.expect(&token::LBRACE);
3874             while !self.eat(&token::RBRACE) {
3875                 meths.push(self.parse_method());
3876             }
3877         }
3878
3879         (ident, item_impl(generics, opt_trait, ty, meths), None)
3880     }
3881
3882     // parse a::B<~str,int>
3883     fn parse_trait_ref(&self) -> trait_ref {
3884         ast::trait_ref {
3885             path: self.parse_path(LifetimeAndTypesWithoutColons).path,
3886             ref_id: ast::DUMMY_NODE_ID,
3887         }
3888     }
3889
3890     // parse B + C<~str,int> + D
3891     fn parse_trait_ref_list(&self, ket: &token::Token) -> ~[trait_ref] {
3892         self.parse_seq_to_before_end(
3893             ket,
3894             seq_sep_trailing_disallowed(token::BINOP(token::PLUS)),
3895             |p| p.parse_trait_ref()
3896         )
3897     }
3898
3899     // parse struct Foo { ... }
3900     fn parse_item_struct(&self) -> item_info {
3901         let class_name = self.parse_ident();
3902         self.parse_region_param();
3903         let generics = self.parse_generics();
3904         if self.eat(&token::COLON) {
3905             self.obsolete(*self.span, ObsoleteClassTraits);
3906             let _ = self.parse_trait_ref_list(&token::LBRACE);
3907         }
3908
3909         let mut fields: ~[@struct_field];
3910         let is_tuple_like;
3911
3912         if self.eat(&token::LBRACE) {
3913             // It's a record-like struct.
3914             is_tuple_like = false;
3915             fields = ~[];
3916             while *self.token != token::RBRACE {
3917                 let r = self.parse_struct_decl_field();
3918                 for struct_field in r.iter() {
3919                     fields.push(*struct_field)
3920                 }
3921             }
3922             if fields.len() == 0 {
3923                 self.fatal(fmt!("Unit-like struct definition should be written as `struct %s;`",
3924                                 get_ident_interner().get(class_name.name)));
3925             }
3926             self.bump();
3927         } else if *self.token == token::LPAREN {
3928             // It's a tuple-like struct.
3929             is_tuple_like = true;
3930             fields = do self.parse_unspanned_seq(
3931                 &token::LPAREN,
3932                 &token::RPAREN,
3933                 seq_sep_trailing_allowed(token::COMMA)
3934             ) |p| {
3935                 let attrs = self.parse_outer_attributes();
3936                 let lo = p.span.lo;
3937                 let struct_field_ = ast::struct_field_ {
3938                     kind: unnamed_field,
3939                     id: ast::DUMMY_NODE_ID,
3940                     ty: p.parse_ty(false),
3941                     attrs: attrs,
3942                 };
3943                 @spanned(lo, p.span.hi, struct_field_)
3944             };
3945             self.expect(&token::SEMI);
3946         } else if self.eat(&token::SEMI) {
3947             // It's a unit-like struct.
3948             is_tuple_like = true;
3949             fields = ~[];
3950         } else {
3951             self.fatal(
3952                 fmt!(
3953                     "expected `{`, `(`, or `;` after struct name \
3954                     but found `%s`",
3955                     self.this_token_to_str()
3956                 )
3957             );
3958         }
3959
3960         let _ = ast::DUMMY_NODE_ID;  // XXX: Workaround for crazy bug.
3961         let new_id = ast::DUMMY_NODE_ID;
3962         (class_name,
3963          item_struct(@ast::struct_def {
3964              fields: fields,
3965              ctor_id: if is_tuple_like { Some(new_id) } else { None }
3966          }, generics),
3967          None)
3968     }
3969
3970     fn token_is_pound_or_doc_comment(&self, tok: token::Token) -> bool {
3971         match tok {
3972             token::POUND | token::DOC_COMMENT(_) => true,
3973             _ => false
3974         }
3975     }
3976
3977     // parse a structure field declaration
3978     pub fn parse_single_struct_field(&self,
3979                                      vis: visibility,
3980                                      attrs: ~[Attribute])
3981                                      -> @struct_field {
3982         if self.eat_obsolete_ident("let") {
3983             self.obsolete(*self.last_span, ObsoleteLet);
3984         }
3985
3986         let a_var = self.parse_name_and_ty(vis, attrs);
3987         match *self.token {
3988             token::SEMI => {
3989                 self.obsolete(*self.span, ObsoleteFieldTerminator);
3990                 self.bump();
3991             }
3992             token::COMMA => {
3993                 self.bump();
3994             }
3995             token::RBRACE => {}
3996             _ => {
3997                 self.span_fatal(*self.span,
3998                                 fmt!("expected `,`, or '}' but found `%s`",
3999                                      self.this_token_to_str()));
4000             }
4001         }
4002         a_var
4003     }
4004
4005     // parse an element of a struct definition
4006     fn parse_struct_decl_field(&self) -> ~[@struct_field] {
4007
4008         let attrs = self.parse_outer_attributes();
4009
4010         if self.try_parse_obsolete_priv_section(attrs) {
4011             return ~[];
4012         }
4013
4014         if self.eat_keyword(keywords::Priv) {
4015             return ~[self.parse_single_struct_field(private, attrs)]
4016         }
4017
4018         if self.eat_keyword(keywords::Pub) {
4019            return ~[self.parse_single_struct_field(public, attrs)];
4020         }
4021
4022         return ~[self.parse_single_struct_field(inherited, attrs)];
4023     }
4024
4025     // parse visiility: PUB, PRIV, or nothing
4026     fn parse_visibility(&self) -> visibility {
4027         if self.eat_keyword(keywords::Pub) { public }
4028         else if self.eat_keyword(keywords::Priv) { private }
4029         else { inherited }
4030     }
4031
4032     fn parse_staticness(&self) -> bool {
4033         if self.eat_keyword(keywords::Static) {
4034             self.obsolete(*self.last_span, ObsoleteStaticMethod);
4035             true
4036         } else {
4037             false
4038         }
4039     }
4040
4041     // given a termination token and a vector of already-parsed
4042     // attributes (of length 0 or 1), parse all of the items in a module
4043     fn parse_mod_items(&self,
4044                        term: token::Token,
4045                        first_item_attrs: ~[Attribute])
4046                        -> _mod {
4047         // parse all of the items up to closing or an attribute.
4048         // view items are legal here.
4049         let ParsedItemsAndViewItems {
4050             attrs_remaining: attrs_remaining,
4051             view_items: view_items,
4052             items: starting_items,
4053             _
4054         } = self.parse_items_and_view_items(first_item_attrs, true, true);
4055         let mut items: ~[@item] = starting_items;
4056         let attrs_remaining_len = attrs_remaining.len();
4057
4058         // don't think this other loop is even necessary....
4059
4060         let mut first = true;
4061         while *self.token != term {
4062             let mut attrs = self.parse_outer_attributes();
4063             if first {
4064                 attrs = attrs_remaining + attrs;
4065                 first = false;
4066             }
4067             debug!("parse_mod_items: parse_item_or_view_item(attrs=%?)",
4068                    attrs);
4069             match self.parse_item_or_view_item(attrs,
4070                                                true /* macros allowed */) {
4071               iovi_item(item) => items.push(item),
4072               iovi_view_item(view_item) => {
4073                 self.span_fatal(view_item.span,
4074                                 "view items must be declared at the top of \
4075                                  the module");
4076               }
4077               _ => {
4078                 self.fatal(fmt!("expected item but found `%s`",
4079                                 self.this_token_to_str()));
4080               }
4081             }
4082         }
4083
4084         if first && attrs_remaining_len > 0u {
4085             // We parsed attributes for the first item but didn't find it
4086             self.span_err(*self.last_span, "expected item after attributes");
4087         }
4088
4089         ast::_mod { view_items: view_items, items: items }
4090     }
4091
4092     fn parse_item_const(&self) -> item_info {
4093         let m = if self.eat_keyword(keywords::Mut) {MutMutable} else {MutImmutable};
4094         let id = self.parse_ident();
4095         self.expect(&token::COLON);
4096         let ty = self.parse_ty(false);
4097         self.expect(&token::EQ);
4098         let e = self.parse_expr();
4099         self.commit_expr_expecting(e, token::SEMI);
4100         (id, item_static(ty, m, e), None)
4101     }
4102
4103     // parse a `mod <foo> { ... }` or `mod <foo>;` item
4104     fn parse_item_mod(&self, outer_attrs: &[Attribute]) -> item_info {
4105         let id_span = *self.span;
4106         let id = self.parse_ident();
4107         if *self.token == token::SEMI {
4108             self.bump();
4109             // This mod is in an external file. Let's go get it!
4110             let (m, attrs) = self.eval_src_mod(id, outer_attrs, id_span);
4111             (id, m, Some(attrs))
4112         } else {
4113             self.push_mod_path(id, outer_attrs);
4114             self.expect(&token::LBRACE);
4115             let (inner, next) = self.parse_inner_attrs_and_next();
4116             let m = self.parse_mod_items(token::RBRACE, next);
4117             self.expect(&token::RBRACE);
4118             self.pop_mod_path();
4119             (id, item_mod(m), Some(inner))
4120         }
4121     }
4122
4123     fn push_mod_path(&self, id: Ident, attrs: &[Attribute]) {
4124         let default_path = token::interner_get(id.name);
4125         let file_path = match ::attr::first_attr_value_str_by_name(attrs,
4126                                                                    "path") {
4127             Some(d) => d,
4128             None => default_path
4129         };
4130         self.mod_path_stack.push(file_path)
4131     }
4132
4133     fn pop_mod_path(&self) {
4134         self.mod_path_stack.pop();
4135     }
4136
4137     // read a module from a source file.
4138     fn eval_src_mod(&self,
4139                     id: ast::Ident,
4140                     outer_attrs: &[ast::Attribute],
4141                     id_sp: Span)
4142                     -> (ast::item_, ~[ast::Attribute]) {
4143         let prefix = Path(self.sess.cm.span_to_filename(*self.span));
4144         let prefix = prefix.dir_path();
4145         let mod_path_stack = &*self.mod_path_stack;
4146         let mod_path = Path(".").push_many(*mod_path_stack);
4147         let dir_path = prefix.push_many(mod_path.components);
4148         let file_path = match ::attr::first_attr_value_str_by_name(
4149                 outer_attrs, "path") {
4150             Some(d) => {
4151                 let path = Path(d);
4152                 if !path.is_absolute {
4153                     dir_path.push(d)
4154                 } else {
4155                     path
4156                 }
4157             }
4158             None => {
4159                 let mod_name = token::interner_get(id.name).to_owned();
4160                 let default_path_str = mod_name + ".rs";
4161                 let secondary_path_str = mod_name + "/mod.rs";
4162                 let default_path = dir_path.push(default_path_str);
4163                 let secondary_path = dir_path.push(secondary_path_str);
4164                 let default_exists = default_path.exists();
4165                 let secondary_exists = secondary_path.exists();
4166                 match (default_exists, secondary_exists) {
4167                     (true, false) => default_path,
4168                     (false, true) => secondary_path,
4169                     (false, false) => {
4170                         self.span_fatal(id_sp, fmt!("file not found for module `%s`", mod_name));
4171                     }
4172                     (true, true) => {
4173                         self.span_fatal(id_sp,
4174                                         fmt!("file for module `%s` found at both %s and %s",
4175                                              mod_name, default_path_str, secondary_path_str));
4176                     }
4177                 }
4178             }
4179         };
4180
4181         self.eval_src_mod_from_path(file_path,
4182                                     outer_attrs.to_owned(),
4183                                     id_sp)
4184     }
4185
4186     fn eval_src_mod_from_path(&self,
4187                               path: Path,
4188                               outer_attrs: ~[ast::Attribute],
4189                               id_sp: Span) -> (ast::item_, ~[ast::Attribute]) {
4190         let full_path = path.normalize();
4191
4192         let maybe_i = do self.sess.included_mod_stack.iter().position |p| { *p == full_path };
4193         match maybe_i {
4194             Some(i) => {
4195                 let stack = &self.sess.included_mod_stack;
4196                 let mut err = ~"circular modules: ";
4197                 for p in stack.slice(i, stack.len()).iter() {
4198                     err.push_str(p.to_str());
4199                     err.push_str(" -> ");
4200                 }
4201                 err.push_str(full_path.to_str());
4202                 self.span_fatal(id_sp, err);
4203             }
4204             None => ()
4205         }
4206         self.sess.included_mod_stack.push(full_path.clone());
4207
4208         let p0 =
4209             new_sub_parser_from_file(self.sess,
4210                                      self.cfg.clone(),
4211                                      &full_path,
4212                                      id_sp);
4213         let (inner, next) = p0.parse_inner_attrs_and_next();
4214         let mod_attrs = vec::append(outer_attrs, inner);
4215         let first_item_outer_attrs = next;
4216         let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs);
4217         self.sess.included_mod_stack.pop();
4218         return (ast::item_mod(m0), mod_attrs);
4219     }
4220
4221     // parse a function declaration from a foreign module
4222     fn parse_item_foreign_fn(&self,  attrs: ~[Attribute]) -> @foreign_item {
4223         let lo = self.span.lo;
4224         let vis = self.parse_visibility();
4225
4226         // Parse obsolete purity.
4227         let purity = self.parse_fn_purity();
4228         if purity != impure_fn {
4229             self.obsolete(*self.last_span, ObsoleteUnsafeExternFn);
4230         }
4231
4232         let (ident, generics) = self.parse_fn_header();
4233         let decl = self.parse_fn_decl();
4234         let hi = self.span.hi;
4235         self.expect(&token::SEMI);
4236         @ast::foreign_item { ident: ident,
4237                              attrs: attrs,
4238                              node: foreign_item_fn(decl, generics),
4239                              id: ast::DUMMY_NODE_ID,
4240                              span: mk_sp(lo, hi),
4241                              vis: vis }
4242     }
4243
4244     // parse a const definition from a foreign module
4245     fn parse_item_foreign_const(&self, vis: ast::visibility,
4246                                 attrs: ~[Attribute]) -> @foreign_item {
4247         let lo = self.span.lo;
4248
4249         // XXX: Obsolete; remove after snap.
4250         if self.eat_keyword(keywords::Const) {
4251             self.obsolete(*self.last_span, ObsoleteConstItem);
4252         } else {
4253             self.expect_keyword(keywords::Static);
4254         }
4255         let mutbl = self.eat_keyword(keywords::Mut);
4256
4257         let ident = self.parse_ident();
4258         self.expect(&token::COLON);
4259         let ty = self.parse_ty(false);
4260         let hi = self.span.hi;
4261         self.expect(&token::SEMI);
4262         @ast::foreign_item { ident: ident,
4263                              attrs: attrs,
4264                              node: foreign_item_static(ty, mutbl),
4265                              id: ast::DUMMY_NODE_ID,
4266                              span: mk_sp(lo, hi),
4267                              vis: vis }
4268     }
4269
4270     // parse safe/unsafe and fn
4271     fn parse_fn_purity(&self) -> purity {
4272         if self.eat_keyword(keywords::Fn) { impure_fn }
4273         else if self.eat_keyword(keywords::Pure) {
4274             self.obsolete(*self.last_span, ObsoletePurity);
4275             self.expect_keyword(keywords::Fn);
4276             // NB: We parse this as impure for bootstrapping purposes.
4277             impure_fn
4278         } else if self.eat_keyword(keywords::Unsafe) {
4279             self.expect_keyword(keywords::Fn);
4280             unsafe_fn
4281         }
4282         else { self.unexpected(); }
4283     }
4284
4285
4286     // at this point, this is essentially a wrapper for
4287     // parse_foreign_items.
4288     fn parse_foreign_mod_items(&self,
4289                                sort: ast::foreign_mod_sort,
4290                                abis: AbiSet,
4291                                first_item_attrs: ~[Attribute])
4292                                -> foreign_mod {
4293         let ParsedItemsAndViewItems {
4294             attrs_remaining: attrs_remaining,
4295             view_items: view_items,
4296             items: _,
4297             foreign_items: foreign_items
4298         } = self.parse_foreign_items(first_item_attrs, true);
4299         if (! attrs_remaining.is_empty()) {
4300             self.span_err(*self.last_span,
4301                           "expected item after attributes");
4302         }
4303         assert!(*self.token == token::RBRACE);
4304         ast::foreign_mod {
4305             sort: sort,
4306             abis: abis,
4307             view_items: view_items,
4308             items: foreign_items
4309         }
4310     }
4311
4312     // parse extern foo; or extern mod foo { ... } or extern { ... }
4313     fn parse_item_foreign_mod(&self,
4314                               lo: BytePos,
4315                               opt_abis: Option<AbiSet>,
4316                               visibility: visibility,
4317                               attrs: ~[Attribute],
4318                               items_allowed: bool)
4319                               -> item_or_view_item {
4320         let mut must_be_named_mod = false;
4321         if self.is_keyword(keywords::Mod) {
4322             must_be_named_mod = true;
4323             self.expect_keyword(keywords::Mod);
4324         } else if *self.token != token::LBRACE {
4325             self.span_fatal(*self.span,
4326                             fmt!("expected `{` or `mod` but found `%s`",
4327                                  self.this_token_to_str()));
4328         }
4329
4330         let (sort, maybe_path, ident) = match *self.token {
4331             token::IDENT(*) => {
4332                 let the_ident = self.parse_ident();
4333                 let path = if *self.token == token::EQ {
4334                     self.bump();
4335                     Some(self.parse_str())
4336                 }
4337                 else { None };
4338                 (ast::named, path, the_ident)
4339             }
4340             _ => {
4341                 if must_be_named_mod {
4342                     self.span_fatal(*self.span,
4343                                     fmt!("expected foreign module name but \
4344                                           found `%s`",
4345                                          self.this_token_to_str()));
4346                 }
4347
4348                 (ast::anonymous, None,
4349                  special_idents::clownshoes_foreign_mod)
4350             }
4351         };
4352
4353         // extern mod foo { ... } or extern { ... }
4354         if items_allowed && self.eat(&token::LBRACE) {
4355             // `extern mod foo { ... }` is obsolete.
4356             if sort == ast::named {
4357                 self.obsolete(*self.last_span, ObsoleteNamedExternModule);
4358             }
4359
4360             let abis = opt_abis.unwrap_or(AbiSet::C());
4361
4362             let (inner, next) = self.parse_inner_attrs_and_next();
4363             let m = self.parse_foreign_mod_items(sort, abis, next);
4364             self.expect(&token::RBRACE);
4365
4366             return iovi_item(self.mk_item(lo,
4367                                           self.last_span.hi,
4368                                           ident,
4369                                           item_foreign_mod(m),
4370                                           visibility,
4371                                           maybe_append(attrs, Some(inner))));
4372         }
4373
4374         if opt_abis.is_some() {
4375             self.span_err(*self.span, "an ABI may not be specified here");
4376         }
4377
4378         // extern mod foo;
4379         let metadata = self.parse_optional_meta();
4380         self.expect(&token::SEMI);
4381         iovi_view_item(ast::view_item {
4382             node: view_item_extern_mod(ident, maybe_path, metadata, ast::DUMMY_NODE_ID),
4383             attrs: attrs,
4384             vis: visibility,
4385             span: mk_sp(lo, self.last_span.hi)
4386         })
4387     }
4388
4389     // parse type Foo = Bar;
4390     fn parse_item_type(&self) -> item_info {
4391         let ident = self.parse_ident();
4392         self.parse_region_param();
4393         let tps = self.parse_generics();
4394         self.expect(&token::EQ);
4395         let ty = self.parse_ty(false);
4396         self.expect(&token::SEMI);
4397         (ident, item_ty(ty, tps), None)
4398     }
4399
4400     // parse obsolete region parameter
4401     fn parse_region_param(&self) {
4402         if self.eat(&token::BINOP(token::SLASH)) {
4403             self.obsolete(*self.last_span, ObsoleteLifetimeNotation);
4404             self.expect(&token::BINOP(token::AND));
4405         }
4406     }
4407
4408     // parse a structure-like enum variant definition
4409     // this should probably be renamed or refactored...
4410     fn parse_struct_def(&self) -> @struct_def {
4411         let mut fields: ~[@struct_field] = ~[];
4412         while *self.token != token::RBRACE {
4413             let r = self.parse_struct_decl_field();
4414             for struct_field in r.iter() {
4415                 fields.push(*struct_field);
4416             }
4417         }
4418         self.bump();
4419
4420         return @ast::struct_def {
4421             fields: fields,
4422             ctor_id: None
4423         };
4424     }
4425
4426     // parse the part of an "enum" decl following the '{'
4427     fn parse_enum_def(&self, _generics: &ast::Generics) -> enum_def {
4428         let mut variants = ~[];
4429         let mut all_nullary = true;
4430         let mut have_disr = false;
4431         while *self.token != token::RBRACE {
4432             let variant_attrs = self.parse_outer_attributes();
4433             let vlo = self.span.lo;
4434
4435             let vis = self.parse_visibility();
4436
4437             let ident;
4438             let kind;
4439             let mut args = ~[];
4440             let mut disr_expr = None;
4441             ident = self.parse_ident();
4442             if self.eat(&token::LBRACE) {
4443                 // Parse a struct variant.
4444                 all_nullary = false;
4445                 kind = struct_variant_kind(self.parse_struct_def());
4446             } else if *self.token == token::LPAREN {
4447                 all_nullary = false;
4448                 let arg_tys = self.parse_unspanned_seq(
4449                     &token::LPAREN,
4450                     &token::RPAREN,
4451                     seq_sep_trailing_disallowed(token::COMMA),
4452                     |p| p.parse_ty(false)
4453                 );
4454                 for ty in arg_tys.move_iter() {
4455                     args.push(ast::variant_arg {
4456                         ty: ty,
4457                         id: ast::DUMMY_NODE_ID,
4458                     });
4459                 }
4460                 kind = tuple_variant_kind(args);
4461             } else if self.eat(&token::EQ) {
4462                 have_disr = true;
4463                 disr_expr = Some(self.parse_expr());
4464                 kind = tuple_variant_kind(args);
4465             } else {
4466                 kind = tuple_variant_kind(~[]);
4467             }
4468
4469             let vr = ast::variant_ {
4470                 name: ident,
4471                 attrs: variant_attrs,
4472                 kind: kind,
4473                 id: ast::DUMMY_NODE_ID,
4474                 disr_expr: disr_expr,
4475                 vis: vis,
4476             };
4477             variants.push(spanned(vlo, self.last_span.hi, vr));
4478
4479             if !self.eat(&token::COMMA) { break; }
4480         }
4481         self.expect(&token::RBRACE);
4482         if (have_disr && !all_nullary) {
4483             self.fatal("discriminator values can only be used with a c-like \
4484                         enum");
4485         }
4486
4487         ast::enum_def { variants: variants }
4488     }
4489
4490     // parse an "enum" declaration
4491     fn parse_item_enum(&self) -> item_info {
4492         let id = self.parse_ident();
4493         self.parse_region_param();
4494         let generics = self.parse_generics();
4495         // Newtype syntax
4496         if *self.token == token::EQ {
4497             // enum x = ty;
4498             self.bump();
4499             let ty = self.parse_ty(false);
4500             self.expect(&token::SEMI);
4501             let variant = spanned(ty.span.lo, ty.span.hi, ast::variant_ {
4502                 name: id,
4503                 attrs: ~[],
4504                 kind: tuple_variant_kind(
4505                     ~[ast::variant_arg {ty: ty, id: ast::DUMMY_NODE_ID}]
4506                 ),
4507                 id: ast::DUMMY_NODE_ID,
4508                 disr_expr: None,
4509                 vis: public,
4510             });
4511
4512             self.obsolete(*self.last_span, ObsoleteNewtypeEnum);
4513
4514             return (
4515                 id,
4516                 item_enum(
4517                     ast::enum_def { variants: ~[variant] },
4518                     generics),
4519                 None
4520             );
4521         }
4522         // enum X { ... }
4523         self.expect(&token::LBRACE);
4524
4525         let enum_definition = self.parse_enum_def(&generics);
4526         (id, item_enum(enum_definition, generics), None)
4527     }
4528
4529     fn parse_fn_ty_sigil(&self) -> Option<Sigil> {
4530         match *self.token {
4531             token::AT => {
4532                 self.bump();
4533                 Some(ManagedSigil)
4534             }
4535             token::TILDE => {
4536                 self.bump();
4537                 Some(OwnedSigil)
4538             }
4539             token::BINOP(token::AND) => {
4540                 self.bump();
4541                 Some(BorrowedSigil)
4542             }
4543             _ => {
4544                 None
4545             }
4546         }
4547     }
4548
4549     fn fn_expr_lookahead(&self, tok: &token::Token) -> bool {
4550         match *tok {
4551           token::LPAREN | token::AT | token::TILDE | token::BINOP(_) => true,
4552           _ => false
4553         }
4554     }
4555
4556     // parse a string as an ABI spec on an extern type or module
4557     fn parse_opt_abis(&self) -> Option<AbiSet> {
4558         match *self.token {
4559             token::LIT_STR(s) => {
4560                 self.bump();
4561                 let the_string = ident_to_str(&s);
4562                 let mut abis = AbiSet::empty();
4563                 for word in the_string.word_iter() {
4564                     match abi::lookup(word) {
4565                         Some(abi) => {
4566                             if abis.contains(abi) {
4567                                 self.span_err(
4568                                     *self.span,
4569                                     fmt!("ABI `%s` appears twice",
4570                                          word));
4571                             } else {
4572                                 abis.add(abi);
4573                             }
4574                         }
4575
4576                         None => {
4577                             self.span_err(
4578                                 *self.span,
4579                                 fmt!("illegal ABI: \
4580                                       expected one of [%s], \
4581                                       found `%s`",
4582                                      abi::all_names().connect(", "),
4583                                      word));
4584                         }
4585                     }
4586                 }
4587                 Some(abis)
4588             }
4589
4590             _ => {
4591                 None
4592             }
4593         }
4594     }
4595
4596     // parse one of the items or view items allowed by the
4597     // flags; on failure, return iovi_none.
4598     // NB: this function no longer parses the items inside an
4599     // extern mod.
4600     fn parse_item_or_view_item(&self,
4601                                attrs: ~[Attribute],
4602                                macros_allowed: bool)
4603                                -> item_or_view_item {
4604         match *self.token {
4605             INTERPOLATED(token::nt_item(item)) => {
4606                 self.bump();
4607                 let new_attrs = vec::append(attrs, item.attrs);
4608                 return iovi_item(@ast::item {
4609                         attrs: new_attrs,
4610                         ..(*item).clone()});
4611             }
4612             _ => {}
4613         }
4614
4615         let lo = self.span.lo;
4616
4617         let visibility = self.parse_visibility();
4618
4619         // must be a view item:
4620         if self.eat_keyword(keywords::Use) {
4621             // USE ITEM (iovi_view_item)
4622             let view_item = self.parse_use();
4623             self.expect(&token::SEMI);
4624             return iovi_view_item(ast::view_item {
4625                 node: view_item,
4626                 attrs: attrs,
4627                 vis: visibility,
4628                 span: mk_sp(lo, self.last_span.hi)
4629             });
4630         }
4631         // either a view item or an item:
4632         if self.eat_keyword(keywords::Extern) {
4633             let opt_abis = self.parse_opt_abis();
4634
4635             if self.eat_keyword(keywords::Fn) {
4636                 // EXTERN FUNCTION ITEM
4637                 let abis = opt_abis.unwrap_or(AbiSet::C());
4638                 let (ident, item_, extra_attrs) =
4639                     self.parse_item_fn(extern_fn, abis);
4640                 return iovi_item(self.mk_item(lo, self.last_span.hi, ident,
4641                                               item_, visibility,
4642                                               maybe_append(attrs,
4643                                                            extra_attrs)));
4644             } else  {
4645                 // EXTERN MODULE ITEM (iovi_view_item)
4646                 return self.parse_item_foreign_mod(lo, opt_abis, visibility, attrs,
4647                                                    true);
4648             }
4649         }
4650         // the rest are all guaranteed to be items:
4651         if (self.is_keyword(keywords::Const) ||
4652             (self.is_keyword(keywords::Static) &&
4653              self.look_ahead(1, |t| !token::is_keyword(keywords::Fn, t)))) {
4654             // CONST / STATIC ITEM
4655             if self.is_keyword(keywords::Const) {
4656                 self.obsolete(*self.span, ObsoleteConstItem);
4657             }
4658             self.bump();
4659             let (ident, item_, extra_attrs) = self.parse_item_const();
4660             return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
4661                                           visibility,
4662                                           maybe_append(attrs, extra_attrs)));
4663         }
4664         if self.is_keyword(keywords::Fn) &&
4665                 self.look_ahead(1, |f| !self.fn_expr_lookahead(f)) {
4666             // FUNCTION ITEM
4667             self.bump();
4668             let (ident, item_, extra_attrs) =
4669                 self.parse_item_fn(impure_fn, AbiSet::Rust());
4670             return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
4671                                           visibility,
4672                                           maybe_append(attrs, extra_attrs)));
4673         }
4674         if self.eat_keyword(keywords::Pure) {
4675             // PURE FUNCTION ITEM (obsolete)
4676             self.obsolete(*self.last_span, ObsoletePurity);
4677             self.expect_keyword(keywords::Fn);
4678             let (ident, item_, extra_attrs) =
4679                 self.parse_item_fn(impure_fn, AbiSet::Rust());
4680             return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
4681                                           visibility,
4682                                           maybe_append(attrs, extra_attrs)));
4683         }
4684         if self.is_keyword(keywords::Unsafe)
4685             && self.look_ahead(1u, |t| *t != token::LBRACE) {
4686             // UNSAFE FUNCTION ITEM
4687             self.bump();
4688             self.expect_keyword(keywords::Fn);
4689             let (ident, item_, extra_attrs) =
4690                 self.parse_item_fn(unsafe_fn, AbiSet::Rust());
4691             return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
4692                                           visibility,
4693                                           maybe_append(attrs, extra_attrs)));
4694         }
4695         if self.eat_keyword(keywords::Mod) {
4696             // MODULE ITEM
4697             let (ident, item_, extra_attrs) = self.parse_item_mod(attrs);
4698             return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
4699                                           visibility,
4700                                           maybe_append(attrs, extra_attrs)));
4701         }
4702         if self.eat_keyword(keywords::Type) {
4703             // TYPE ITEM
4704             let (ident, item_, extra_attrs) = self.parse_item_type();
4705             return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
4706                                           visibility,
4707                                           maybe_append(attrs, extra_attrs)));
4708         }
4709         if self.eat_keyword(keywords::Enum) {
4710             // ENUM ITEM
4711             let (ident, item_, extra_attrs) = self.parse_item_enum();
4712             return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
4713                                           visibility,
4714                                           maybe_append(attrs, extra_attrs)));
4715         }
4716         if self.eat_keyword(keywords::Trait) {
4717             // TRAIT ITEM
4718             let (ident, item_, extra_attrs) = self.parse_item_trait();
4719             return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
4720                                           visibility,
4721                                           maybe_append(attrs, extra_attrs)));
4722         }
4723         if self.eat_keyword(keywords::Impl) {
4724             // IMPL ITEM
4725             let (ident, item_, extra_attrs) = self.parse_item_impl();
4726             return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
4727                                           visibility,
4728                                           maybe_append(attrs, extra_attrs)));
4729         }
4730         if self.eat_keyword(keywords::Struct) {
4731             // STRUCT ITEM
4732             let (ident, item_, extra_attrs) = self.parse_item_struct();
4733             return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
4734                                           visibility,
4735                                           maybe_append(attrs, extra_attrs)));
4736         }
4737         self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
4738     }
4739
4740     // parse a foreign item; on failure, return iovi_none.
4741     fn parse_foreign_item(&self,
4742                           attrs: ~[Attribute],
4743                           macros_allowed: bool)
4744                           -> item_or_view_item {
4745         maybe_whole!(iovi self, nt_item);
4746         let lo = self.span.lo;
4747
4748         let visibility = self.parse_visibility();
4749
4750         if (self.is_keyword(keywords::Const) || self.is_keyword(keywords::Static)) {
4751             // FOREIGN CONST ITEM
4752             let item = self.parse_item_foreign_const(visibility, attrs);
4753             return iovi_foreign_item(item);
4754         }
4755         if (self.is_keyword(keywords::Fn) || self.is_keyword(keywords::Pure) ||
4756                 self.is_keyword(keywords::Unsafe)) {
4757             // FOREIGN FUNCTION ITEM
4758             let item = self.parse_item_foreign_fn(attrs);
4759             return iovi_foreign_item(item);
4760         }
4761         self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
4762     }
4763
4764     // this is the fall-through for parsing items.
4765     fn parse_macro_use_or_failure(
4766         &self,
4767         attrs: ~[Attribute],
4768         macros_allowed: bool,
4769         lo : BytePos,
4770         visibility : visibility
4771     ) -> item_or_view_item {
4772         if macros_allowed && !token::is_any_keyword(self.token)
4773                 && self.look_ahead(1, |t| *t == token::NOT)
4774                 && (self.look_ahead(2, |t| is_plain_ident(t))
4775                     || self.look_ahead(2, |t| *t == token::LPAREN)
4776                     || self.look_ahead(2, |t| *t == token::LBRACE)) {
4777             // MACRO INVOCATION ITEM
4778             if attrs.len() > 0 {
4779                 self.fatal("attrs on macros are not yet supported");
4780             }
4781
4782             // item macro.
4783             let pth = self.parse_path(NoTypesAllowed).path;
4784             self.expect(&token::NOT);
4785
4786             // a 'special' identifier (like what `macro_rules!` uses)
4787             // is optional. We should eventually unify invoc syntax
4788             // and remove this.
4789             let id = if is_plain_ident(&*self.token) {
4790                 self.parse_ident()
4791             } else {
4792                 token::special_idents::invalid // no special identifier
4793             };
4794             // eat a matched-delimiter token tree:
4795             let tts = match *self.token {
4796                 token::LPAREN | token::LBRACE => {
4797                     let ket = token::flip_delimiter(&*self.token);
4798                     self.bump();
4799                     self.parse_seq_to_end(&ket,
4800                                           seq_sep_none(),
4801                                           |p| p.parse_token_tree())
4802                 }
4803                 _ => self.fatal("expected open delimiter")
4804             };
4805             // single-variant-enum... :
4806             let m = ast::mac_invoc_tt(pth, tts, EMPTY_CTXT);
4807             let m: ast::mac = codemap::Spanned { node: m,
4808                                              span: mk_sp(self.span.lo,
4809                                                          self.span.hi) };
4810             let item_ = item_mac(m);
4811             return iovi_item(self.mk_item(lo, self.last_span.hi, id, item_,
4812                                           visibility, attrs));
4813         }
4814
4815         // FAILURE TO PARSE ITEM
4816         if visibility != inherited {
4817             let mut s = ~"unmatched visibility `";
4818             if visibility == public {
4819                 s.push_str("pub")
4820             } else {
4821                 s.push_str("priv")
4822             }
4823             s.push_char('`');
4824             self.span_fatal(*self.last_span, s);
4825         }
4826         return iovi_none(attrs);
4827     }
4828
4829     pub fn parse_item(&self, attrs: ~[Attribute]) -> Option<@ast::item> {
4830         match self.parse_item_or_view_item(attrs, true) {
4831             iovi_none(_) => None,
4832             iovi_view_item(_) =>
4833                 self.fatal("view items are not allowed here"),
4834             iovi_foreign_item(_) =>
4835                 self.fatal("foreign items are not allowed here"),
4836             iovi_item(item) => Some(item)
4837         }
4838     }
4839
4840     // parse, e.g., "use a::b::{z,y}"
4841     fn parse_use(&self) -> view_item_ {
4842         return view_item_use(self.parse_view_paths());
4843     }
4844
4845
4846     // matches view_path : MOD? IDENT EQ non_global_path
4847     // | MOD? non_global_path MOD_SEP LBRACE RBRACE
4848     // | MOD? non_global_path MOD_SEP LBRACE ident_seq RBRACE
4849     // | MOD? non_global_path MOD_SEP STAR
4850     // | MOD? non_global_path
4851     fn parse_view_path(&self) -> @view_path {
4852         let lo = self.span.lo;
4853
4854         let first_ident = self.parse_ident();
4855         let mut path = ~[first_ident];
4856         debug!("parsed view_path: %s", self.id_to_str(first_ident));
4857         match *self.token {
4858           token::EQ => {
4859             // x = foo::bar
4860             self.bump();
4861             path = ~[self.parse_ident()];
4862             while *self.token == token::MOD_SEP {
4863                 self.bump();
4864                 let id = self.parse_ident();
4865                 path.push(id);
4866             }
4867             let path = ast::Path {
4868                 span: mk_sp(lo, self.span.hi),
4869                 global: false,
4870                 segments: path.move_iter().map(|identifier| {
4871                     ast::PathSegment {
4872                         identifier: identifier,
4873                         lifetime: None,
4874                         types: opt_vec::Empty,
4875                     }
4876                 }).collect()
4877             };
4878             return @spanned(lo, self.span.hi,
4879                             view_path_simple(first_ident,
4880                                              path,
4881                                              ast::DUMMY_NODE_ID));
4882           }
4883
4884           token::MOD_SEP => {
4885             // foo::bar or foo::{a,b,c} or foo::*
4886             while *self.token == token::MOD_SEP {
4887                 self.bump();
4888
4889                 match *self.token {
4890                   token::IDENT(i, _) => {
4891                     self.bump();
4892                     path.push(i);
4893                   }
4894
4895                   // foo::bar::{a,b,c}
4896                   token::LBRACE => {
4897                     let idents = self.parse_unspanned_seq(
4898                         &token::LBRACE,
4899                         &token::RBRACE,
4900                         seq_sep_trailing_allowed(token::COMMA),
4901                         |p| p.parse_path_list_ident()
4902                     );
4903                     let path = ast::Path {
4904                         span: mk_sp(lo, self.span.hi),
4905                         global: false,
4906                         segments: path.move_iter().map(|identifier| {
4907                             ast::PathSegment {
4908                                 identifier: identifier,
4909                                 lifetime: None,
4910                                 types: opt_vec::Empty,
4911                             }
4912                         }).collect()
4913                     };
4914                     return @spanned(lo, self.span.hi,
4915                                  view_path_list(path, idents, ast::DUMMY_NODE_ID));
4916                   }
4917
4918                   // foo::bar::*
4919                   token::BINOP(token::STAR) => {
4920                     self.bump();
4921                     let path = ast::Path {
4922                         span: mk_sp(lo, self.span.hi),
4923                         global: false,
4924                         segments: path.move_iter().map(|identifier| {
4925                             ast::PathSegment {
4926                                 identifier: identifier,
4927                                 lifetime: None,
4928                                 types: opt_vec::Empty,
4929                             }
4930                         }).collect()
4931                     };
4932                     return @spanned(lo, self.span.hi,
4933                                     view_path_glob(path, ast::DUMMY_NODE_ID));
4934                   }
4935
4936                   _ => break
4937                 }
4938             }
4939           }
4940           _ => ()
4941         }
4942         let last = path[path.len() - 1u];
4943         let path = ast::Path {
4944             span: mk_sp(lo, self.span.hi),
4945             global: false,
4946             segments: path.move_iter().map(|identifier| {
4947                 ast::PathSegment {
4948                     identifier: identifier,
4949                     lifetime: None,
4950                     types: opt_vec::Empty,
4951                 }
4952             }).collect()
4953         };
4954         return @spanned(lo,
4955                         self.last_span.hi,
4956                         view_path_simple(last, path, ast::DUMMY_NODE_ID));
4957     }
4958
4959     // matches view_paths = view_path | view_path , view_paths
4960     fn parse_view_paths(&self) -> ~[@view_path] {
4961         let mut vp = ~[self.parse_view_path()];
4962         while *self.token == token::COMMA {
4963             self.bump();
4964             vp.push(self.parse_view_path());
4965         }
4966         return vp;
4967     }
4968
4969     fn is_view_item(&self) -> bool {
4970         if !self.is_keyword(keywords::Pub) && !self.is_keyword(keywords::Priv) {
4971             token::is_keyword(keywords::Use, self.token)
4972                 || (token::is_keyword(keywords::Extern, self.token) &&
4973                     self.look_ahead(1,
4974                                     |t| token::is_keyword(keywords::Mod, t)))
4975         } else {
4976             self.look_ahead(1, |t| token::is_keyword(keywords::Use, t))
4977                 || (self.look_ahead(1,
4978                                     |t| token::is_keyword(keywords::Extern,
4979                                                           t)) &&
4980                     self.look_ahead(2,
4981                                     |t| token::is_keyword(keywords::Mod, t)))
4982         }
4983     }
4984
4985     // parse a view item.
4986     fn parse_view_item(
4987         &self,
4988         attrs: ~[Attribute],
4989         vis: visibility
4990     ) -> view_item {
4991         let lo = self.span.lo;
4992         let node = if self.eat_keyword(keywords::Use) {
4993             self.parse_use()
4994         } else if self.eat_keyword(keywords::Extern) {
4995             self.expect_keyword(keywords::Mod);
4996             let ident = self.parse_ident();
4997             let path = if *self.token == token::EQ {
4998                 self.bump();
4999                 Some(self.parse_str())
5000             }
5001             else { None };
5002             let metadata = self.parse_optional_meta();
5003             view_item_extern_mod(ident, path, metadata, ast::DUMMY_NODE_ID)
5004         } else {
5005             self.bug("expected view item");
5006         };
5007         self.expect(&token::SEMI);
5008         ast::view_item { node: node,
5009                           attrs: attrs,
5010                           vis: vis,
5011                           span: mk_sp(lo, self.last_span.hi) }
5012     }
5013
5014     // Parses a sequence of items. Stops when it finds program
5015     // text that can't be parsed as an item
5016     // - mod_items uses extern_mod_allowed = true
5017     // - block_tail_ uses extern_mod_allowed = false
5018     fn parse_items_and_view_items(&self,
5019                                   first_item_attrs: ~[Attribute],
5020                                   mut extern_mod_allowed: bool,
5021                                   macros_allowed: bool)
5022                                   -> ParsedItemsAndViewItems {
5023         let mut attrs = vec::append(first_item_attrs,
5024                                     self.parse_outer_attributes());
5025         // First, parse view items.
5026         let mut view_items : ~[ast::view_item] = ~[];
5027         let mut items = ~[];
5028
5029         // I think this code would probably read better as a single
5030         // loop with a mutable three-state-variable (for extern mods,
5031         // view items, and regular items) ... except that because
5032         // of macros, I'd like to delay that entire check until later.
5033         loop {
5034             match self.parse_item_or_view_item(attrs, macros_allowed) {
5035                 iovi_none(attrs) => {
5036                     return ParsedItemsAndViewItems {
5037                         attrs_remaining: attrs,
5038                         view_items: view_items,
5039                         items: items,
5040                         foreign_items: ~[]
5041                     }
5042                 }
5043                 iovi_view_item(view_item) => {
5044                     match view_item.node {
5045                         view_item_use(*) => {
5046                             // `extern mod` must precede `use`.
5047                             extern_mod_allowed = false;
5048                         }
5049                         view_item_extern_mod(*)
5050                         if !extern_mod_allowed => {
5051                             self.span_err(view_item.span,
5052                                           "\"extern mod\" declarations are not allowed here");
5053                         }
5054                         view_item_extern_mod(*) => {}
5055                     }
5056                     view_items.push(view_item);
5057                 }
5058                 iovi_item(item) => {
5059                     items.push(item);
5060                     attrs = self.parse_outer_attributes();
5061                     break;
5062                 }
5063                 iovi_foreign_item(_) => {
5064                     fail!();
5065                 }
5066             }
5067             attrs = self.parse_outer_attributes();
5068         }
5069
5070         // Next, parse items.
5071         loop {
5072             match self.parse_item_or_view_item(attrs, macros_allowed) {
5073                 iovi_none(returned_attrs) => {
5074                     attrs = returned_attrs;
5075                     break
5076                 }
5077                 iovi_view_item(view_item) => {
5078                     attrs = self.parse_outer_attributes();
5079                     self.span_err(view_item.span,
5080                                   "`use` and `extern mod` declarations must precede items");
5081                 }
5082                 iovi_item(item) => {
5083                     attrs = self.parse_outer_attributes();
5084                     items.push(item)
5085                 }
5086                 iovi_foreign_item(_) => {
5087                     fail!();
5088                 }
5089             }
5090         }
5091
5092         ParsedItemsAndViewItems {
5093             attrs_remaining: attrs,
5094             view_items: view_items,
5095             items: items,
5096             foreign_items: ~[]
5097         }
5098     }
5099
5100     // Parses a sequence of foreign items. Stops when it finds program
5101     // text that can't be parsed as an item
5102     fn parse_foreign_items(&self, first_item_attrs: ~[Attribute],
5103                            macros_allowed: bool)
5104         -> ParsedItemsAndViewItems {
5105         let mut attrs = vec::append(first_item_attrs,
5106                                     self.parse_outer_attributes());
5107         let mut foreign_items = ~[];
5108         loop {
5109             match self.parse_foreign_item(attrs, macros_allowed) {
5110                 iovi_none(returned_attrs) => {
5111                     if *self.token == token::RBRACE {
5112                         attrs = returned_attrs;
5113                         break
5114                     }
5115                     self.unexpected();
5116                 },
5117                 iovi_view_item(view_item) => {
5118                     // I think this can't occur:
5119                     self.span_err(view_item.span,
5120                                   "`use` and `extern mod` declarations must precede items");
5121                 }
5122                 iovi_item(item) => {
5123                     // FIXME #5668: this will occur for a macro invocation:
5124                     self.span_fatal(item.span, "macros cannot expand to foreign items");
5125                 }
5126                 iovi_foreign_item(foreign_item) => {
5127                     foreign_items.push(foreign_item);
5128                 }
5129             }
5130             attrs = self.parse_outer_attributes();
5131         }
5132
5133         ParsedItemsAndViewItems {
5134             attrs_remaining: attrs,
5135             view_items: ~[],
5136             items: ~[],
5137             foreign_items: foreign_items
5138         }
5139     }
5140
5141     // Parses a source module as a crate. This is the main
5142     // entry point for the parser.
5143     pub fn parse_crate_mod(&self) -> @Crate {
5144         let lo = self.span.lo;
5145         // parse the crate's inner attrs, maybe (oops) one
5146         // of the attrs of an item:
5147         let (inner, next) = self.parse_inner_attrs_and_next();
5148         let first_item_outer_attrs = next;
5149         // parse the items inside the crate:
5150         let m = self.parse_mod_items(token::EOF, first_item_outer_attrs);
5151
5152         @ast::Crate {
5153             module: m,
5154             attrs: inner,
5155             config: self.cfg.clone(),
5156             span: mk_sp(lo, self.span.lo)
5157         }
5158     }
5159
5160     pub fn parse_optional_str(&self) -> Option<@str> {
5161         match *self.token {
5162             token::LIT_STR(s) => {
5163                 self.bump();
5164                 Some(ident_to_str(&s))
5165             }
5166             _ => None
5167         }
5168     }
5169
5170     pub fn parse_str(&self) -> @str {
5171         match self.parse_optional_str() {
5172             Some(s) => { s }
5173             _ =>  self.fatal("expected string literal")
5174         }
5175     }
5176 }