(index<- )        ./libsyntax/parse/parser.rs

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


libsyntax/parse/parser.rs:2099:8-2099:8 -fn- definition:
        fn parse_any_tt_tok(p: &mut Parser) -> TokenTree {
            TTTok(p.span, p.bump_and_get())
        }
references:- 3
2115:                 self.open_braces.push(self.span);
2116:                 let mut result = vec!(parse_any_tt_tok(self));
--
2124:                 // Parse the close delimiter.
2125:                 result.push(parse_any_tt_tok(self));
2126:                 self.open_braces.pop().unwrap();


libsyntax/parse/parser.rs:113:45-113:45 -struct- definition:
/// A path paired with optional type bounds.
pub struct PathAndBounds {
    pub path: ast::Path,
references:- 4
1541:         // Assemble the result.
1542:         PathAndBounds {
1543:             path: ast::Path {


libsyntax/parse/parser.rs:258:1-258:1 -fn- definition:
fn maybe_append(lhs: Vec<Attribute> , rhs: Option<Vec<Attribute> >)
             -> Vec<Attribute> {
    match rhs {
references:- 11
4623:                                     visibility,
4624:                                     maybe_append(attrs, extra_attrs));
4625:             return IoviItem(item);
--
4699:                                     visibility,
4700:                                     maybe_append(attrs, extra_attrs));
4701:             return IoviItem(item);
--
4710:                                     visibility,
4711:                                     maybe_append(attrs, extra_attrs));
4712:             return IoviItem(item);


libsyntax/parse/parser.rs:275:1-275:1 -fn- definition:
pub fn Parser<'a>(
              sess: &'a ParseSess,
              cfg: ast::CrateConfig,
references:- 4
libsyntax/ext/tt/macro_rules.rs:
168:                                            rhs);
169:                 let p = Parser(cx.parse_sess(), cx.cfg(), box trncbr);
170:                 // Let the context choose how to interpret the result.
libsyntax/parse/mod.rs:
258:     let trdr = lexer::new_tt_reader(&sess.span_diagnostic, None, tts);
259:     Parser(sess, cfg, box trdr)
260: }
libsyntax/ext/tt/macro_parser.rs:
402:             } else /* bb_eis.len() == 1 */ {
403:                 let mut rust_parser = Parser(sess, cfg.clone(), box rdr.clone());


libsyntax/parse/parser.rs:85:16-85:16 -enum- definition:
pub enum restriction {
    UNRESTRICTED,
    RESTRICT_STMT_EXPR,
references:- 6
86: pub enum restriction {
--
2610:     // parse an expression, subject to the given restriction
2611:     fn parse_expr_res(&mut self, r: restriction) -> @Expr {
2612:         let old = self.restriction;


libsyntax/parse/parser.rs:267:1-267:1 -struct- definition:
struct ParsedItemsAndViewItems {
    attrs_remaining: Vec<Attribute> ,
    view_items: Vec<ViewItem> ,
references:- 8
4981:                 IoviNone(attrs) => {
4982:                     return ParsedItemsAndViewItems {
4983:                         attrs_remaining: attrs,
--
5037:         ParsedItemsAndViewItems {
5038:             attrs_remaining: attrs,
--
5077:         ParsedItemsAndViewItems {
5078:             attrs_remaining: attrs,


libsyntax/parse/parser.rs:92:1-92:1 -NK_AS_STR_TODO- definition:
type ItemInfo = (Ident, Item_, Option<Vec<Attribute> >);
/// How to parse a path. There are four different kinds of paths, all of which
/// are parsed somewhat differently.
references:- 8
3924:     // parse struct Foo { ... }
3925:     fn parse_item_struct(&mut self, is_virtual: bool) -> ItemInfo {
3926:         let class_name = self.parse_ident();
--
4125:     // parse a `mod <foo> { ... }` or `mod <foo>;` item
4126:     fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> ItemInfo {
4127:         let id_span = self.span;
--
4477:     // parse an "enum" declaration
4478:     fn parse_item_enum(&mut self) -> ItemInfo {
4479:         let id = self.parse_ident();


libsyntax/parse/parser.rs:118:1-118:1 -enum- definition:
enum ItemOrViewItem {
    // Indicates a failure to parse any kind of item. The attributes are
    // returned.
references:- 5
4366:                               attrs: Vec<Attribute> )
4367:                               -> ItemOrViewItem {
--
4720:                           macros_allowed: bool)
4721:                           -> ItemOrViewItem {
4722:         maybe_whole!(iovi self, NtItem);
--
4746:         visibility: Visibility
4747:     ) -> ItemOrViewItem {
4748:         if macros_allowed && !token::is_any_keyword(&self.token)


libsyntax/parse/parser.rs:97:16-97:16 -enum- definition:
pub enum PathParsingMode {
    /// A path with no type parameters; e.g. `foo::bar::Baz`
    NoTypesAllowed,
references:- 4
1462:     /// groups.
1463:     pub fn parse_path(&mut self, mode: PathParsingMode) -> PathAndBounds {
1464:         // Check for a whole path...


libsyntax/parse/parser.rs:313:1-313:1 -struct- definition:
pub struct Parser<'a> {
    pub sess: &'a ParseSess,
    // the current token:
references:- 30
libsyntax/parse/attr.rs:
libsyntax/parse/obsolete.rs:
libsyntax/ext/tt/macro_parser.rs:
libsyntax/ext/tt/macro_rules.rs:
libsyntax/parse/mod.rs:


libsyntax/parse/parser.rs:2019:8-2019:8 -fn- definition:
        fn parse_zerok(parser: &mut Parser) -> Option<bool> {
            match parser.token {
                token::BINOP(token::STAR) | token::BINOP(token::PLUS) => {
references:- 2
2035:         let separator = self.bump_and_get();
2036:         match parse_zerok(self) {
2037:             Some(zerok) => (Some(separator), zerok),


libsyntax/parse/parser.rs:341:1-341:1 -fn- definition:
fn is_plain_ident_or_underscore(t: &token::Token) -> bool {
    is_plain_ident(t) || *t == token::UNDERSCORE
}
references:- 2
1334:         } else {
1335:             self.look_ahead(offset, |t| is_plain_ident_or_underscore(t))
1336:                 && self.look_ahead(offset + 1, |t| *t == token::COLON)


libsyntax/parse/parser.rs:3095:8-3095:8 -fn- definition:
        fn check_expected_item(p: &mut Parser, found_attrs: bool) {
            // If we have attributes then we should have an item
            if found_attrs {
references:- 3
3103:         if self.is_keyword(keywords::Let) {
3104:             check_expected_item(self, !item_attrs.is_empty());
3105:             self.expect_keyword(keywords::Let);
--
3124:             check_expected_item(self, !item_attrs.is_empty());
--
3196:             check_expected_item(self, found_attrs);