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