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