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