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.
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.
14 use ast::{AssociatedType, BareFnTy, ClosureTy};
15 use ast::{RegionTyParamBound, TraitTyParamBound};
16 use ast::{ProvidedMethod, Public, FnStyle};
17 use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue};
18 use ast::{BiBitAnd, BiBitOr, BiBitXor, BiRem, Block};
19 use ast::{BlockCheckMode, CaptureByRef, CaptureByValue, CaptureClause};
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, ExprTupField, ExprFnBlock, ExprIf, ExprIfLet, ExprIndex, ExprSlice};
26 use ast::{ExprLit, ExprLoop, ExprMac};
27 use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc};
28 use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary, ExprUnboxedFn};
29 use ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl};
30 use ast::{Once, Many};
31 use ast::{FnUnboxedClosureKind, FnMutUnboxedClosureKind};
32 use ast::{FnOnceUnboxedClosureKind};
33 use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod};
34 use ast::{Ident, NormalFn, Inherited, ImplItem, Item, Item_, ItemStatic};
35 use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl, ItemConst};
36 use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy};
37 use ast::{LifetimeDef, Lit, Lit_};
38 use ast::{LitBool, LitChar, LitByte, LitBinary};
39 use ast::{LitNil, LitStr, LitInt, Local, LocalLet};
40 use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, Matcher, MatchNonterminal, MatchNormal};
41 use ast::{MatchSeq, MatchTok, Method, MutTy, BiMul, Mutability};
42 use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, UnNot};
43 use ast::{Pat, PatEnum, PatIdent, PatLit, PatRange, PatRegion, PatStruct};
44 use ast::{PatTup, PatBox, PatWild, PatWildMulti, PatWildSingle};
45 use ast::{QPath, RequiredMethod};
46 use ast::{RetStyle, Return, BiShl, BiShr, Stmt, StmtDecl};
47 use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField};
48 use ast::{StructVariantKind, BiSub};
50 use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue};
51 use ast::{TokenTree, TraitItem, TraitRef, TTDelim, TTSeq, TTTok};
52 use ast::{TTNonterminal, TupleVariantKind, Ty, Ty_, TyBot};
53 use ast::{TypeField, TyFixedLengthVec, TyClosure, TyProc, TyBareFn};
54 use ast::{TyTypeof, TyInfer, TypeMethod};
55 use ast::{TyNil, TyParam, TyParamBound, TyParen, TyPath, TyPtr, TyQPath};
56 use ast::{TyRptr, TyTup, TyU32, TyUnboxedFn, TyUniq, TyVec, UnUniq};
57 use ast::{TypeImplItem, TypeTraitItem, Typedef, UnboxedClosureKind};
58 use ast::{UnboxedFnBound, UnboxedFnTy, UnboxedFnTyParamBound};
59 use ast::{UnnamedField, UnsafeBlock};
60 use ast::{UnsafeFn, ViewItem, ViewItem_, ViewItemExternCrate, ViewItemUse};
61 use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
62 use ast::{Visibility, WhereClause, WherePredicate};
64 use ast_util::{as_prec, ident_to_path, operator_prec};
67 use codemap::{Span, BytePos, Spanned, spanned, mk_sp};
70 use parse::attr::ParserAttr;
72 use parse::common::{SeqSep, seq_sep_none};
73 use parse::common::{seq_sep_trailing_allowed};
74 use parse::lexer::Reader;
75 use parse::lexer::TokenAndSpan;
76 use parse::obsolete::*;
77 use parse::token::{INTERPOLATED, InternedString, can_begin_expr};
78 use parse::token::{is_ident, is_ident_or_path, is_plain_ident};
79 use parse::token::{keywords, special_idents, token_to_binop};
81 use parse::{new_sub_parser_from_file, ParseSess};
83 use owned_slice::OwnedSlice;
85 use std::collections::HashSet;
86 use std::io::fs::PathExtensions;
87 use std::mem::replace;
93 flags Restrictions: u8 {
94 const UNRESTRICTED = 0b0000,
95 const RESTRICTION_STMT_EXPR = 0b0001,
96 const RESTRICTION_NO_BAR_OP = 0b0010,
97 const RESTRICTION_NO_STRUCT_LITERAL = 0b0100
101 type ItemInfo = (Ident, Item_, Option<Vec<Attribute> >);
103 /// How to parse a path. There are four different kinds of paths, all of which
104 /// are parsed somewhat differently.
105 #[deriving(PartialEq)]
106 pub enum PathParsingMode {
107 /// A path with no type parameters; e.g. `foo::bar::Baz`
109 /// A path with a lifetime and type parameters, with no double colons
110 /// before the type parameters; e.g. `foo::bar<'a>::Baz<T>`
111 LifetimeAndTypesWithoutColons,
112 /// A path with a lifetime and type parameters with double colons before
113 /// the type parameters; e.g. `foo::bar::<'a>::Baz::<T>`
114 LifetimeAndTypesWithColons,
115 /// A path with a lifetime and type parameters with bounds before the last
116 /// set of type parameters only; e.g. `foo::bar<'a>::Baz+X+Y<T>` This
117 /// form does not use extra double colons.
118 LifetimeAndTypesAndBounds,
121 /// A path paired with optional type bounds.
122 pub struct PathAndBounds {
124 pub bounds: Option<ast::TyParamBounds>,
127 enum ItemOrViewItem {
128 /// Indicates a failure to parse any kind of item. The attributes are
130 IoviNone(Vec<Attribute>),
132 IoviForeignItem(P<ForeignItem>),
133 IoviViewItem(ViewItem)
137 /// Possibly accept an `INTERPOLATED` expression (a pre-parsed expression
138 /// dropped into the token stream, which happens while parsing the
139 /// result of macro expansion)
140 /// Placement of these is not as complex as I feared it would be.
141 /// The important thing is to make sure that lookahead doesn't balk
142 /// at INTERPOLATED tokens
143 macro_rules! maybe_whole_expr (
146 let found = match $p.token {
147 INTERPOLATED(token::NtExpr(ref e)) => {
150 INTERPOLATED(token::NtPath(_)) => {
151 // FIXME: The following avoids an issue with lexical borrowck scopes,
152 // but the clone is unfortunate.
153 let pt = match $p.token {
154 INTERPOLATED(token::NtPath(ref pt)) => (**pt).clone(),
158 Some($p.mk_expr(span.lo, span.hi, ExprPath(pt)))
160 INTERPOLATED(token::NtBlock(_)) => {
161 // FIXME: The following avoids an issue with lexical borrowck scopes,
162 // but the clone is unfortunate.
163 let b = match $p.token {
164 INTERPOLATED(token::NtBlock(ref b)) => (*b).clone(),
168 Some($p.mk_expr(span.lo, span.hi, ExprBlock(b)))
183 /// As maybe_whole_expr, but for things other than expressions
184 macro_rules! maybe_whole (
185 ($p:expr, $constructor:ident) => (
187 let found = match ($p).token {
188 INTERPOLATED(token::$constructor(_)) => {
189 Some(($p).bump_and_get())
194 Some(INTERPOLATED(token::$constructor(x))) => {
201 (no_clone $p:expr, $constructor:ident) => (
203 let found = match ($p).token {
204 INTERPOLATED(token::$constructor(_)) => {
205 Some(($p).bump_and_get())
210 Some(INTERPOLATED(token::$constructor(x))) => {
217 (deref $p:expr, $constructor:ident) => (
219 let found = match ($p).token {
220 INTERPOLATED(token::$constructor(_)) => {
221 Some(($p).bump_and_get())
226 Some(INTERPOLATED(token::$constructor(x))) => {
233 (Some $p:expr, $constructor:ident) => (
235 let found = match ($p).token {
236 INTERPOLATED(token::$constructor(_)) => {
237 Some(($p).bump_and_get())
242 Some(INTERPOLATED(token::$constructor(x))) => {
243 return Some(x.clone()),
249 (iovi $p:expr, $constructor:ident) => (
251 let found = match ($p).token {
252 INTERPOLATED(token::$constructor(_)) => {
253 Some(($p).bump_and_get())
258 Some(INTERPOLATED(token::$constructor(x))) => {
259 return IoviItem(x.clone())
265 (pair_empty $p:expr, $constructor:ident) => (
267 let found = match ($p).token {
268 INTERPOLATED(token::$constructor(_)) => {
269 Some(($p).bump_and_get())
274 Some(INTERPOLATED(token::$constructor(x))) => {
275 return (Vec::new(), x)
284 fn maybe_append(mut lhs: Vec<Attribute>, rhs: Option<Vec<Attribute>>)
287 Some(ref attrs) => lhs.extend(attrs.iter().map(|a| a.clone())),
294 struct ParsedItemsAndViewItems {
295 attrs_remaining: Vec<Attribute>,
296 view_items: Vec<ViewItem>,
297 items: Vec<P<Item>> ,
298 foreign_items: Vec<P<ForeignItem>>
301 /* ident is handled by common.rs */
303 pub struct Parser<'a> {
304 pub sess: &'a ParseSess,
305 /// the current token:
306 pub token: token::Token,
307 /// the span of the current token:
309 /// the span of the prior token:
311 pub cfg: CrateConfig,
312 /// the previous token or None (only stashed sometimes).
313 pub last_token: Option<Box<token::Token>>,
314 pub buffer: [TokenAndSpan, ..4],
315 pub buffer_start: int,
317 pub tokens_consumed: uint,
318 pub restrictions: Restrictions,
319 pub quote_depth: uint, // not (yet) related to the quasiquoter
320 pub reader: Box<Reader+'a>,
321 pub interner: Rc<token::IdentInterner>,
322 /// The set of seen errors about obsolete syntax. Used to suppress
323 /// extra detail when the same error is seen twice
324 pub obsolete_set: HashSet<ObsoleteSyntax>,
325 /// Used to determine the path to externally loaded source files
326 pub mod_path_stack: Vec<InternedString>,
327 /// Stack of spans of open delimiters. Used for error message.
328 pub open_braces: Vec<Span>,
329 /// Flag if this parser "owns" the directory that it is currently parsing
330 /// in. This will affect how nested files are looked up.
331 pub owns_directory: bool,
332 /// Name of the root module this parser originated from. If `None`, then the
333 /// name is not known. This does not change while the parser is descending
334 /// into modules, and sub-parsers have new values for this name.
335 pub root_module_name: Option<String>,
338 fn is_plain_ident_or_underscore(t: &token::Token) -> bool {
339 is_plain_ident(t) || *t == token::UNDERSCORE
342 /// Get a token the parser cares about
343 fn real_token(rdr: &mut Reader) -> TokenAndSpan {
344 let mut t = rdr.next_token();
347 token::WS | token::COMMENT | token::SHEBANG(_) => {
348 t = rdr.next_token();
356 impl<'a> Parser<'a> {
357 pub fn new(sess: &'a ParseSess,
358 cfg: ast::CrateConfig,
359 mut rdr: Box<Reader+'a>)
362 let tok0 = real_token(&mut *rdr);
364 let placeholder = TokenAndSpan {
365 tok: token::UNDERSCORE,
371 interner: token::get_ident_interner(),
387 restrictions: UNRESTRICTED,
389 obsolete_set: HashSet::new(),
390 mod_path_stack: Vec::new(),
391 open_braces: Vec::new(),
392 owns_directory: true,
393 root_module_name: None,
397 /// Convert a token to a string using self's reader
398 pub fn token_to_string(token: &token::Token) -> String {
399 token::to_string(token)
402 /// Convert the current token to a string using self's reader
403 pub fn this_token_to_string(&mut self) -> String {
404 Parser::token_to_string(&self.token)
407 pub fn unexpected_last(&mut self, t: &token::Token) -> ! {
408 let token_str = Parser::token_to_string(t);
409 let last_span = self.last_span;
410 self.span_fatal(last_span, format!("unexpected token: `{}`",
411 token_str).as_slice());
414 pub fn unexpected(&mut self) -> ! {
415 let this_token = self.this_token_to_string();
416 self.fatal(format!("unexpected token: `{}`", this_token).as_slice());
419 /// Expect and consume the token t. Signal an error if
420 /// the next token is not t.
421 pub fn expect(&mut self, t: &token::Token) {
422 if self.token == *t {
425 let token_str = Parser::token_to_string(t);
426 let this_token_str = self.this_token_to_string();
427 self.fatal(format!("expected `{}`, found `{}`",
429 this_token_str).as_slice())
433 /// Expect next token to be edible or inedible token. If edible,
434 /// then consume it; if inedible, then return without consuming
435 /// anything. Signal a fatal error if next token is unexpected.
436 pub fn expect_one_of(&mut self,
437 edible: &[token::Token],
438 inedible: &[token::Token]) {
439 fn tokens_to_string(tokens: &[token::Token]) -> String {
440 let mut i = tokens.iter();
441 // This might be a sign we need a connect method on Iterator.
443 .map_or("".to_string(), |t| Parser::token_to_string(t));
447 b.push_str(Parser::token_to_string(a).as_slice());
451 if edible.contains(&self.token) {
453 } else if inedible.contains(&self.token) {
454 // leave it in the input
456 let mut expected = edible.iter().map(|x| x.clone()).collect::<Vec<_>>();
457 expected.push_all(inedible);
458 let expect = tokens_to_string(expected.as_slice());
459 let actual = self.this_token_to_string();
461 (if expected.len() != 1 {
462 (format!("expected one of `{}`, found `{}`",
466 (format!("expected `{}`, found `{}`",
474 /// Check for erroneous `ident { }`; if matches, signal error and
475 /// recover (without consuming any expected input token). Returns
476 /// true if and only if input was consumed for recovery.
477 pub fn check_for_erroneous_unit_struct_expecting(&mut self, expected: &[token::Token]) -> bool {
478 if self.token == token::LBRACE
479 && expected.iter().all(|t| *t != token::LBRACE)
480 && self.look_ahead(1, |t| *t == token::RBRACE) {
481 // matched; signal non-fatal error and recover.
482 let span = self.span;
484 "unit-like struct construction is written with no trailing `{ }`");
485 self.eat(&token::LBRACE);
486 self.eat(&token::RBRACE);
493 /// Commit to parsing a complete expression `e` expected to be
494 /// followed by some token from the set edible + inedible. Recover
495 /// from anticipated input errors, discarding erroneous characters.
496 pub fn commit_expr(&mut self, e: &Expr, edible: &[token::Token], inedible: &[token::Token]) {
497 debug!("commit_expr {}", e);
500 // might be unit-struct construction; check for recoverableinput error.
501 let mut expected = edible.iter().map(|x| x.clone()).collect::<Vec<_>>();
502 expected.push_all(inedible);
503 self.check_for_erroneous_unit_struct_expecting(
504 expected.as_slice());
508 self.expect_one_of(edible, inedible)
511 pub fn commit_expr_expecting(&mut self, e: &Expr, edible: token::Token) {
512 self.commit_expr(e, &[edible], &[])
515 /// Commit to parsing a complete statement `s`, which expects to be
516 /// followed by some token from the set edible + inedible. Check
517 /// for recoverable input errors, discarding erroneous characters.
518 pub fn commit_stmt(&mut self, edible: &[token::Token], inedible: &[token::Token]) {
521 .map_or(false, |t| is_ident_or_path(&**t)) {
522 let mut expected = edible.iter().map(|x| x.clone()).collect::<Vec<_>>();
523 expected.push_all(inedible.as_slice());
524 self.check_for_erroneous_unit_struct_expecting(
525 expected.as_slice());
527 self.expect_one_of(edible, inedible)
530 pub fn commit_stmt_expecting(&mut self, edible: token::Token) {
531 self.commit_stmt(&[edible], &[])
534 pub fn parse_ident(&mut self) -> ast::Ident {
535 self.check_strict_keywords();
536 self.check_reserved_keywords();
538 token::IDENT(i, _) => {
542 token::INTERPOLATED(token::NtIdent(..)) => {
543 self.bug("ident interpolation not converted to real token");
546 let token_str = self.this_token_to_string();
547 self.fatal((format!("expected ident, found `{}`",
548 token_str)).as_slice())
553 pub fn parse_path_list_item(&mut self) -> ast::PathListItem {
554 let lo = self.span.lo;
555 let node = if self.eat_keyword(keywords::Mod) {
556 ast::PathListMod { id: ast::DUMMY_NODE_ID }
558 let ident = self.parse_ident();
559 ast::PathListIdent { name: ident, id: ast::DUMMY_NODE_ID }
561 let hi = self.last_span.hi;
562 spanned(lo, hi, node)
565 /// Consume token 'tok' if it exists. Returns true if the given
566 /// token was present, false otherwise.
567 pub fn eat(&mut self, tok: &token::Token) -> bool {
568 let is_present = self.token == *tok;
569 if is_present { self.bump() }
573 pub fn is_keyword(&mut self, kw: keywords::Keyword) -> bool {
574 token::is_keyword(kw, &self.token)
577 /// If the next token is the given keyword, eat it and return
578 /// true. Otherwise, return false.
579 pub fn eat_keyword(&mut self, kw: keywords::Keyword) -> bool {
580 if self.is_keyword(kw) {
588 /// If the given word is not a keyword, signal an error.
589 /// If the next token is not the given word, signal an error.
590 /// Otherwise, eat it.
591 pub fn expect_keyword(&mut self, kw: keywords::Keyword) {
592 if !self.eat_keyword(kw) {
593 let id_interned_str = token::get_name(kw.to_name());
594 let token_str = self.this_token_to_string();
595 self.fatal(format!("expected `{}`, found `{}`",
596 id_interned_str, token_str).as_slice())
600 /// Signal an error if the given string is a strict keyword
601 pub fn check_strict_keywords(&mut self) {
602 if token::is_strict_keyword(&self.token) {
603 let token_str = self.this_token_to_string();
604 let span = self.span;
606 format!("expected identifier, found keyword `{}`",
607 token_str).as_slice());
611 /// Signal an error if the current token is a reserved keyword
612 pub fn check_reserved_keywords(&mut self) {
613 if token::is_reserved_keyword(&self.token) {
614 let token_str = self.this_token_to_string();
615 self.fatal(format!("`{}` is a reserved keyword",
616 token_str).as_slice())
620 /// Expect and consume an `&`. If `&&` is seen, replace it with a single
621 /// `&` and continue. If an `&` is not seen, signal an error.
622 fn expect_and(&mut self) {
624 token::BINOP(token::AND) => self.bump(),
626 let span = self.span;
627 let lo = span.lo + BytePos(1);
628 self.replace_token(token::BINOP(token::AND), lo, span.hi)
631 let token_str = self.this_token_to_string();
633 Parser::token_to_string(&token::BINOP(token::AND));
634 self.fatal(format!("expected `{}`, found `{}`",
636 token_str).as_slice())
641 /// Expect and consume a `|`. If `||` is seen, replace it with a single
642 /// `|` and continue. If a `|` is not seen, signal an error.
643 fn expect_or(&mut self) {
645 token::BINOP(token::OR) => self.bump(),
647 let span = self.span;
648 let lo = span.lo + BytePos(1);
649 self.replace_token(token::BINOP(token::OR), lo, span.hi)
652 let found_token = self.this_token_to_string();
654 Parser::token_to_string(&token::BINOP(token::OR));
655 self.fatal(format!("expected `{}`, found `{}`",
657 found_token).as_slice())
662 /// Attempt to consume a `<`. If `<<` is seen, replace it with a single
663 /// `<` and continue. If a `<` is not seen, return false.
665 /// This is meant to be used when parsing generics on a path to get the
666 /// starting token. The `force` parameter is used to forcefully break up a
667 /// `<<` token. If `force` is false, then `<<` is only broken when a lifetime
668 /// shows up next. For example, consider the expression:
670 /// foo as bar << test
672 /// The parser needs to know if `bar <<` is the start of a generic path or if
673 /// it's a left-shift token. If `test` were a lifetime, then it's impossible
674 /// for the token to be a left-shift, but if it's not a lifetime, then it's
675 /// considered a left-shift.
677 /// The reason for this is that the only current ambiguity with `<<` is when
678 /// parsing closure types:
680 /// foo::<<'a> ||>();
681 /// impl Foo<<'a> ||>() { ... }
682 fn eat_lt(&mut self, force: bool) -> bool {
684 token::LT => { self.bump(); true }
685 token::BINOP(token::SHL) => {
686 let next_lifetime = self.look_ahead(1, |t| match *t {
687 token::LIFETIME(..) => true,
690 if force || next_lifetime {
691 let span = self.span;
692 let lo = span.lo + BytePos(1);
693 self.replace_token(token::LT, lo, span.hi);
703 fn expect_lt(&mut self) {
704 if !self.eat_lt(true) {
705 let found_token = self.this_token_to_string();
706 let token_str = Parser::token_to_string(&token::LT);
707 self.fatal(format!("expected `{}`, found `{}`",
709 found_token).as_slice())
713 /// Parse a sequence bracketed by `|` and `|`, stopping before the `|`.
714 fn parse_seq_to_before_or<T>(
717 f: |&mut Parser| -> T)
719 let mut first = true;
720 let mut vector = Vec::new();
721 while self.token != token::BINOP(token::OR) &&
722 self.token != token::OROR {
734 /// Expect and consume a GT. if a >> is seen, replace it
735 /// with a single > and continue. If a GT is not seen,
737 pub fn expect_gt(&mut self) {
739 token::GT => self.bump(),
740 token::BINOP(token::SHR) => {
741 let span = self.span;
742 let lo = span.lo + BytePos(1);
743 self.replace_token(token::GT, lo, span.hi)
745 token::BINOPEQ(token::SHR) => {
746 let span = self.span;
747 let lo = span.lo + BytePos(1);
748 self.replace_token(token::GE, lo, span.hi)
751 let span = self.span;
752 let lo = span.lo + BytePos(1);
753 self.replace_token(token::EQ, lo, span.hi)
756 let gt_str = Parser::token_to_string(&token::GT);
757 let this_token_str = self.this_token_to_string();
758 self.fatal(format!("expected `{}`, found `{}`",
760 this_token_str).as_slice())
765 /// Parse a sequence bracketed by '<' and '>', stopping
767 pub fn parse_seq_to_before_gt<T>(
769 sep: Option<token::Token>,
770 f: |&mut Parser| -> T)
772 let mut v = Vec::new();
773 // This loop works by alternating back and forth between parsing types
774 // and commas. For example, given a string `A, B,>`, the parser would
775 // first parse `A`, then a comma, then `B`, then a comma. After that it
776 // would encounter a `>` and stop. This lets the parser handle trailing
777 // commas in generic parameters, because it can stop either after
778 // parsing a type or after parsing a comma.
779 for i in iter::count(0u, 1) {
780 if self.token == token::GT
781 || self.token == token::BINOP(token::SHR)
782 || self.token == token::GE
783 || self.token == token::BINOPEQ(token::SHR) {
790 sep.as_ref().map(|t| self.expect(t));
793 return OwnedSlice::from_vec(v);
796 pub fn parse_seq_to_gt<T>(
798 sep: Option<token::Token>,
799 f: |&mut Parser| -> T)
801 let v = self.parse_seq_to_before_gt(sep, f);
806 /// Parse a sequence, including the closing delimiter. The function
807 /// f must consume tokens until reaching the next separator or
809 pub fn parse_seq_to_end<T>(
813 f: |&mut Parser| -> T)
815 let val = self.parse_seq_to_before_end(ket, sep, f);
820 /// Parse a sequence, not including the closing delimiter. The function
821 /// f must consume tokens until reaching the next separator or
823 pub fn parse_seq_to_before_end<T>(
827 f: |&mut Parser| -> T)
829 let mut first: bool = true;
831 while self.token != *ket {
834 if first { first = false; }
835 else { self.expect(t); }
839 if sep.trailing_sep_allowed && self.token == *ket { break; }
845 /// Parse a sequence, including the closing delimiter. The function
846 /// f must consume tokens until reaching the next separator or
848 pub fn parse_unspanned_seq<T>(
853 f: |&mut Parser| -> T)
856 let result = self.parse_seq_to_before_end(ket, sep, f);
861 /// Parse a sequence parameter of enum variant. For consistency purposes,
862 /// these should not be empty.
863 pub fn parse_enum_variant_seq<T>(
868 f: |&mut Parser| -> T)
870 let result = self.parse_unspanned_seq(bra, ket, sep, f);
871 if result.is_empty() {
872 let last_span = self.last_span;
873 self.span_err(last_span,
874 "nullary enum variants are written with no trailing `( )`");
879 // NB: Do not use this function unless you actually plan to place the
880 // spanned list in the AST.
886 f: |&mut Parser| -> T)
887 -> Spanned<Vec<T> > {
888 let lo = self.span.lo;
890 let result = self.parse_seq_to_before_end(ket, sep, f);
891 let hi = self.span.hi;
893 spanned(lo, hi, result)
896 /// Advance the parser by one token
897 pub fn bump(&mut self) {
898 self.last_span = self.span;
899 // Stash token for error recovery (sometimes; clone is not necessarily cheap).
900 self.last_token = if is_ident_or_path(&self.token) {
901 Some(box self.token.clone())
905 let next = if self.buffer_start == self.buffer_end {
906 real_token(&mut *self.reader)
908 // Avoid token copies with `replace`.
909 let buffer_start = self.buffer_start as uint;
910 let next_index = (buffer_start + 1) & 3 as uint;
911 self.buffer_start = next_index as int;
913 let placeholder = TokenAndSpan {
914 tok: token::UNDERSCORE,
917 replace(&mut self.buffer[buffer_start], placeholder)
920 self.token = next.tok;
921 self.tokens_consumed += 1u;
924 /// Advance the parser by one token and return the bumped token.
925 pub fn bump_and_get(&mut self) -> token::Token {
926 let old_token = replace(&mut self.token, token::UNDERSCORE);
931 /// EFFECT: replace the current token and span with the given one
932 pub fn replace_token(&mut self,
936 self.last_span = mk_sp(self.span.lo, lo);
938 self.span = mk_sp(lo, hi);
940 pub fn buffer_length(&mut self) -> int {
941 if self.buffer_start <= self.buffer_end {
942 return self.buffer_end - self.buffer_start;
944 return (4 - self.buffer_start) + self.buffer_end;
946 pub fn look_ahead<R>(&mut self, distance: uint, f: |&token::Token| -> R)
948 let dist = distance as int;
949 while self.buffer_length() < dist {
950 self.buffer[self.buffer_end as uint] = real_token(&mut *self.reader);
951 self.buffer_end = (self.buffer_end + 1) & 3;
953 f(&self.buffer[((self.buffer_start + dist - 1) & 3) as uint].tok)
955 pub fn fatal(&mut self, m: &str) -> ! {
956 self.sess.span_diagnostic.span_fatal(self.span, m)
958 pub fn span_fatal(&mut self, sp: Span, m: &str) -> ! {
959 self.sess.span_diagnostic.span_fatal(sp, m)
961 pub fn span_note(&mut self, sp: Span, m: &str) {
962 self.sess.span_diagnostic.span_note(sp, m)
964 pub fn span_help(&mut self, sp: Span, m: &str) {
965 self.sess.span_diagnostic.span_help(sp, m)
967 pub fn bug(&mut self, m: &str) -> ! {
968 self.sess.span_diagnostic.span_bug(self.span, m)
970 pub fn warn(&mut self, m: &str) {
971 self.sess.span_diagnostic.span_warn(self.span, m)
973 pub fn span_warn(&mut self, sp: Span, m: &str) {
974 self.sess.span_diagnostic.span_warn(sp, m)
976 pub fn span_err(&mut self, sp: Span, m: &str) {
977 self.sess.span_diagnostic.span_err(sp, m)
979 pub fn abort_if_errors(&mut self) {
980 self.sess.span_diagnostic.handler().abort_if_errors();
983 pub fn id_to_interned_str(&mut self, id: Ident) -> InternedString {
987 /// Is the current token one of the keywords that signals a bare function
989 pub fn token_is_bare_fn_keyword(&mut self) -> bool {
990 if token::is_keyword(keywords::Fn, &self.token) {
994 if token::is_keyword(keywords::Unsafe, &self.token) ||
995 token::is_keyword(keywords::Once, &self.token) {
996 return self.look_ahead(1, |t| token::is_keyword(keywords::Fn, t))
1002 /// Is the current token one of the keywords that signals a closure type?
1003 pub fn token_is_closure_keyword(&mut self) -> bool {
1004 token::is_keyword(keywords::Unsafe, &self.token) ||
1005 token::is_keyword(keywords::Once, &self.token)
1008 /// Is the current token one of the keywords that signals an old-style
1009 /// closure type (with explicit sigil)?
1010 pub fn token_is_old_style_closure_keyword(&mut self) -> bool {
1011 token::is_keyword(keywords::Unsafe, &self.token) ||
1012 token::is_keyword(keywords::Once, &self.token) ||
1013 token::is_keyword(keywords::Fn, &self.token)
1016 pub fn token_is_lifetime(tok: &token::Token) -> bool {
1018 token::LIFETIME(..) => true,
1023 pub fn get_lifetime(&mut self) -> ast::Ident {
1025 token::LIFETIME(ref ident) => *ident,
1026 _ => self.bug("not a lifetime"),
1030 /// parse a TyBareFn type:
1031 pub fn parse_ty_bare_fn(&mut self) -> Ty_ {
1034 [unsafe] [extern "ABI"] fn <'lt> (S) -> T
1035 ^~~~^ ^~~~^ ^~~~^ ^~^ ^
1038 | | | Argument types
1044 let fn_style = self.parse_unsafety();
1045 let abi = if self.eat_keyword(keywords::Extern) {
1046 self.parse_opt_abi().unwrap_or(abi::C)
1051 self.expect_keyword(keywords::Fn);
1052 let (decl, lifetimes) = self.parse_ty_fn_decl(true);
1053 TyBareFn(P(BareFnTy {
1056 lifetimes: lifetimes,
1061 /// Parses a procedure type (`proc`). The initial `proc` keyword must
1062 /// already have been parsed.
1063 pub fn parse_proc_type(&mut self) -> Ty_ {
1066 proc <'lt> (S) [:Bounds] -> T
1067 ^~~^ ^~~~^ ^ ^~~~~~~~^ ^
1077 let lifetime_defs = if self.eat(&token::LT) {
1078 let lifetime_defs = self.parse_lifetime_defs();
1085 let (inputs, variadic) = self.parse_fn_args(false, false);
1086 let bounds = self.parse_colon_then_ty_param_bounds();
1087 let (ret_style, ret_ty) = self.parse_ret_ty();
1088 let decl = P(FnDecl {
1094 TyProc(P(ClosureTy {
1099 lifetimes: lifetime_defs,
1103 /// Parses an optional unboxed closure kind (`&:`, `&mut:`, or `:`).
1104 pub fn parse_optional_unboxed_closure_kind(&mut self)
1105 -> Option<UnboxedClosureKind> {
1106 if self.token == token::BINOP(token::AND) &&
1107 self.look_ahead(1, |t| {
1108 token::is_keyword(keywords::Mut, t)
1110 self.look_ahead(2, |t| *t == token::COLON) {
1114 return Some(FnMutUnboxedClosureKind)
1117 if self.token == token::BINOP(token::AND) &&
1118 self.look_ahead(1, |t| *t == token::COLON) {
1121 return Some(FnUnboxedClosureKind)
1124 if self.eat(&token::COLON) {
1125 return Some(FnOnceUnboxedClosureKind)
1131 /// Parse a TyClosure type
1132 pub fn parse_ty_closure(&mut self) -> Ty_ {
1135 [unsafe] [once] <'lt> |S| [:Bounds] -> T
1136 ^~~~~~~^ ^~~~~^ ^~~~^ ^ ^~~~~~~~^ ^
1138 | | | | | Return type
1139 | | | | Closure bounds
1140 | | | Argument types
1142 | Once-ness (a.k.a., affine)
1147 let fn_style = self.parse_unsafety();
1148 let onceness = if self.eat_keyword(keywords::Once) {Once} else {Many};
1150 let lifetime_defs = if self.eat(&token::LT) {
1151 let lifetime_defs = self.parse_lifetime_defs();
1159 let (optional_unboxed_closure_kind, inputs) = if self.eat(&token::OROR) {
1164 let optional_unboxed_closure_kind =
1165 self.parse_optional_unboxed_closure_kind();
1167 let inputs = self.parse_seq_to_before_or(
1169 |p| p.parse_arg_general(false));
1171 (optional_unboxed_closure_kind, inputs)
1174 let bounds = self.parse_colon_then_ty_param_bounds();
1176 let (return_style, output) = self.parse_ret_ty();
1177 let decl = P(FnDecl {
1184 match optional_unboxed_closure_kind {
1185 Some(unboxed_closure_kind) => {
1186 TyUnboxedFn(P(UnboxedFnTy {
1187 kind: unboxed_closure_kind,
1192 TyClosure(P(ClosureTy {
1197 lifetimes: lifetime_defs,
1203 pub fn parse_unsafety(&mut self) -> FnStyle {
1204 if self.eat_keyword(keywords::Unsafe) {
1211 /// Parse a function type (following the 'fn')
1212 pub fn parse_ty_fn_decl(&mut self, allow_variadic: bool)
1213 -> (P<FnDecl>, Vec<ast::LifetimeDef>) {
1224 let lifetime_defs = if self.eat(&token::LT) {
1225 let lifetime_defs = self.parse_lifetime_defs();
1232 let (inputs, variadic) = self.parse_fn_args(false, allow_variadic);
1233 let (ret_style, ret_ty) = self.parse_ret_ty();
1234 let decl = P(FnDecl {
1240 (decl, lifetime_defs)
1243 /// Parses `type Foo;` in a trait declaration only. The `type` keyword has
1244 /// already been parsed.
1245 fn parse_associated_type(&mut self, attrs: Vec<Attribute>)
1247 let lo = self.span.lo;
1248 let ident = self.parse_ident();
1249 let hi = self.span.hi;
1250 self.expect(&token::SEMI);
1252 id: ast::DUMMY_NODE_ID,
1253 span: mk_sp(lo, hi),
1259 /// Parses `type Foo = TYPE;` in an implementation declaration only. The
1260 /// `type` keyword has already been parsed.
1261 fn parse_typedef(&mut self, attrs: Vec<Attribute>, vis: Visibility)
1263 let lo = self.span.lo;
1264 let ident = self.parse_ident();
1265 self.expect(&token::EQ);
1266 let typ = self.parse_ty(true);
1267 let hi = self.span.hi;
1268 self.expect(&token::SEMI);
1270 id: ast::DUMMY_NODE_ID,
1271 span: mk_sp(lo, hi),
1279 /// Parse the items in a trait declaration
1280 pub fn parse_trait_items(&mut self) -> Vec<TraitItem> {
1281 self.parse_unspanned_seq(
1286 let attrs = p.parse_outer_attributes();
1288 if p.eat_keyword(keywords::Type) {
1289 TypeTraitItem(P(p.parse_associated_type(attrs)))
1293 let vis = p.parse_visibility();
1294 let abi = if p.eat_keyword(keywords::Extern) {
1295 p.parse_opt_abi().unwrap_or(abi::C)
1296 } else if attr::contains_name(attrs.as_slice(),
1297 "rust_call_abi_hack") {
1298 // FIXME(stage0, pcwalton): Remove this awful hack after a
1299 // snapshot, and change to `extern "rust-call" fn`.
1305 let style = p.parse_fn_style();
1306 let ident = p.parse_ident();
1307 let mut generics = p.parse_generics();
1309 let (explicit_self, d) = p.parse_fn_decl_with_self(|p| {
1310 // This is somewhat dubious; We don't want to allow
1311 // argument names to be left off if there is a
1313 p.parse_arg_general(false)
1316 p.parse_where_clause(&mut generics);
1318 let hi = p.last_span.hi;
1322 debug!("parse_trait_methods(): parsing required method");
1323 RequiredMethod(TypeMethod {
1330 explicit_self: explicit_self,
1331 id: ast::DUMMY_NODE_ID,
1332 span: mk_sp(lo, hi),
1337 debug!("parse_trait_methods(): parsing provided method");
1338 let (inner_attrs, body) =
1339 p.parse_inner_attrs_and_block();
1340 let mut attrs = attrs;
1341 attrs.push_all(inner_attrs.as_slice());
1342 ProvidedMethod(P(ast::Method {
1344 id: ast::DUMMY_NODE_ID,
1345 span: mk_sp(lo, hi),
1346 node: ast::MethDecl(ident,
1358 let token_str = p.this_token_to_string();
1359 p.fatal((format!("expected `;` or `{{`, found `{}`",
1360 token_str)).as_slice())
1367 /// Parse a possibly mutable type
1368 pub fn parse_mt(&mut self) -> MutTy {
1369 let mutbl = self.parse_mutability();
1370 let t = self.parse_ty(true);
1371 MutTy { ty: t, mutbl: mutbl }
1374 /// Parse [mut/const/imm] ID : TY
1375 /// now used only by obsolete record syntax parser...
1376 pub fn parse_ty_field(&mut self) -> TypeField {
1377 let lo = self.span.lo;
1378 let mutbl = self.parse_mutability();
1379 let id = self.parse_ident();
1380 self.expect(&token::COLON);
1381 let ty = self.parse_ty(true);
1382 let hi = ty.span.hi;
1385 mt: MutTy { ty: ty, mutbl: mutbl },
1386 span: mk_sp(lo, hi),
1390 /// Parse optional return type [ -> TY ] in function decl
1391 pub fn parse_ret_ty(&mut self) -> (RetStyle, P<Ty>) {
1392 return if self.eat(&token::RARROW) {
1393 let lo = self.span.lo;
1394 if self.eat(&token::NOT) {
1398 id: ast::DUMMY_NODE_ID,
1400 span: mk_sp(lo, self.last_span.hi)
1404 (Return, self.parse_ty(true))
1407 let pos = self.span.lo;
1411 id: ast::DUMMY_NODE_ID,
1413 span: mk_sp(pos, pos),
1421 /// The second parameter specifies whether the `+` binary operator is
1422 /// allowed in the type grammar.
1423 pub fn parse_ty(&mut self, plus_allowed: bool) -> P<Ty> {
1424 maybe_whole!(no_clone self, NtTy);
1426 let lo = self.span.lo;
1428 let t = if self.token == token::LPAREN {
1430 if self.token == token::RPAREN {
1434 // (t) is a parenthesized ty
1435 // (t,) is the type of a tuple with only one field,
1437 let mut ts = vec!(self.parse_ty(true));
1438 let mut one_tuple = false;
1439 while self.token == token::COMMA {
1441 if self.token != token::RPAREN {
1442 ts.push(self.parse_ty(true));
1449 if ts.len() == 1 && !one_tuple {
1450 self.expect(&token::RPAREN);
1451 TyParen(ts.into_iter().nth(0).unwrap())
1454 self.expect(&token::RPAREN);
1458 } else if self.token == token::TILDE {
1461 let last_span = self.last_span;
1463 token::LBRACKET => self.obsolete(last_span, ObsoleteOwnedVector),
1464 _ => self.obsolete(last_span, ObsoleteOwnedType)
1466 TyUniq(self.parse_ty(false))
1467 } else if self.token == token::BINOP(token::STAR) {
1468 // STAR POINTER (bare pointer?)
1470 TyPtr(self.parse_ptr())
1471 } else if self.token == token::LBRACKET {
1473 self.expect(&token::LBRACKET);
1474 let t = self.parse_ty(true);
1476 // Parse the `, ..e` in `[ int, ..e ]`
1477 // where `e` is a const expression
1478 let t = match self.maybe_parse_fixed_vstore() {
1480 Some(suffix) => TyFixedLengthVec(t, suffix)
1482 self.expect(&token::RBRACKET);
1484 } else if self.token == token::BINOP(token::AND) ||
1485 self.token == token::ANDAND {
1488 self.parse_borrowed_pointee()
1489 } else if self.is_keyword(keywords::Extern) ||
1490 self.is_keyword(keywords::Unsafe) ||
1491 self.token_is_bare_fn_keyword() {
1493 self.parse_ty_bare_fn()
1494 } else if self.token_is_closure_keyword() ||
1495 self.token == token::BINOP(token::OR) ||
1496 self.token == token::OROR ||
1497 (self.token == token::LT &&
1498 self.look_ahead(1, |t| {
1499 *t == token::GT || Parser::token_is_lifetime(t)
1503 self.parse_ty_closure()
1504 } else if self.eat_keyword(keywords::Typeof) {
1506 // In order to not be ambiguous, the type must be surrounded by parens.
1507 self.expect(&token::LPAREN);
1508 let e = self.parse_expr();
1509 self.expect(&token::RPAREN);
1511 } else if self.eat_keyword(keywords::Proc) {
1512 self.parse_proc_type()
1513 } else if self.token == token::LT {
1516 let for_type = self.parse_ty(true);
1517 self.expect_keyword(keywords::As);
1518 let trait_name = self.parse_path(LifetimeAndTypesWithoutColons);
1519 self.expect(&token::GT);
1520 self.expect(&token::MOD_SEP);
1521 let item_name = self.parse_ident();
1524 trait_name: trait_name.path,
1525 item_name: item_name,
1527 } else if self.token == token::MOD_SEP
1528 || is_ident_or_path(&self.token) {
1530 let mode = if plus_allowed {
1531 LifetimeAndTypesAndBounds
1533 LifetimeAndTypesWithoutColons
1538 } = self.parse_path(mode);
1539 TyPath(path, bounds, ast::DUMMY_NODE_ID)
1540 } else if self.eat(&token::UNDERSCORE) {
1541 // TYPE TO BE INFERRED
1544 let msg = format!("expected type, found token {}", self.token);
1545 self.fatal(msg.as_slice());
1548 let sp = mk_sp(lo, self.last_span.hi);
1549 P(Ty {id: ast::DUMMY_NODE_ID, node: t, span: sp})
1552 pub fn parse_borrowed_pointee(&mut self) -> Ty_ {
1553 // look for `&'lt` or `&'foo ` and interpret `foo` as the region name:
1554 let opt_lifetime = self.parse_opt_lifetime();
1556 let mt = self.parse_mt();
1557 return TyRptr(opt_lifetime, mt);
1560 pub fn parse_ptr(&mut self) -> MutTy {
1561 let mutbl = if self.eat_keyword(keywords::Mut) {
1563 } else if self.eat_keyword(keywords::Const) {
1566 let span = self.last_span;
1568 "bare raw pointers are no longer allowed, you should \
1569 likely use `*mut T`, but otherwise `*T` is now \
1570 known as `*const T`");
1573 let t = self.parse_ty(true);
1574 MutTy { ty: t, mutbl: mutbl }
1577 pub fn is_named_argument(&mut self) -> bool {
1578 let offset = match self.token {
1579 token::BINOP(token::AND) => 1,
1581 _ if token::is_keyword(keywords::Mut, &self.token) => 1,
1585 debug!("parser is_named_argument offset:{}", offset);
1588 is_plain_ident_or_underscore(&self.token)
1589 && self.look_ahead(1, |t| *t == token::COLON)
1591 self.look_ahead(offset, |t| is_plain_ident_or_underscore(t))
1592 && self.look_ahead(offset + 1, |t| *t == token::COLON)
1596 /// This version of parse arg doesn't necessarily require
1597 /// identifier names.
1598 pub fn parse_arg_general(&mut self, require_name: bool) -> Arg {
1599 let pat = if require_name || self.is_named_argument() {
1600 debug!("parse_arg_general parse_pat (require_name:{})",
1602 let pat = self.parse_pat();
1604 self.expect(&token::COLON);
1607 debug!("parse_arg_general ident_to_pat");
1608 ast_util::ident_to_pat(ast::DUMMY_NODE_ID,
1610 special_idents::invalid)
1613 let t = self.parse_ty(true);
1618 id: ast::DUMMY_NODE_ID,
1622 /// Parse a single function argument
1623 pub fn parse_arg(&mut self) -> Arg {
1624 self.parse_arg_general(true)
1627 /// Parse an argument in a lambda header e.g. |arg, arg|
1628 pub fn parse_fn_block_arg(&mut self) -> Arg {
1629 let pat = self.parse_pat();
1630 let t = if self.eat(&token::COLON) {
1634 id: ast::DUMMY_NODE_ID,
1636 span: mk_sp(self.span.lo, self.span.hi),
1642 id: ast::DUMMY_NODE_ID
1646 pub fn maybe_parse_fixed_vstore(&mut self) -> Option<P<ast::Expr>> {
1647 if self.token == token::COMMA &&
1648 self.look_ahead(1, |t| *t == token::DOTDOT) {
1651 Some(self.parse_expr())
1657 /// Matches token_lit = LIT_INTEGER | ...
1658 pub fn lit_from_token(&mut self, tok: &token::Token) -> Lit_ {
1660 token::LIT_BYTE(i) => LitByte(parse::byte_lit(i.as_str()).val0()),
1661 token::LIT_CHAR(i) => LitChar(parse::char_lit(i.as_str()).val0()),
1662 token::LIT_INTEGER(s) => parse::integer_lit(s.as_str(),
1663 &self.sess.span_diagnostic, self.span),
1664 token::LIT_FLOAT(s) => parse::float_lit(s.as_str()),
1665 token::LIT_STR(s) => {
1666 LitStr(token::intern_and_get_ident(parse::str_lit(s.as_str()).as_slice()),
1669 token::LIT_STR_RAW(s, n) => {
1670 LitStr(token::intern_and_get_ident(parse::raw_str_lit(s.as_str()).as_slice()),
1673 token::LIT_BINARY(i) =>
1674 LitBinary(parse::binary_lit(i.as_str())),
1675 token::LIT_BINARY_RAW(i, _) =>
1676 LitBinary(Rc::new(i.as_str().as_bytes().iter().map(|&x| x).collect())),
1677 token::LPAREN => { self.expect(&token::RPAREN); LitNil },
1678 _ => { self.unexpected_last(tok); }
1682 /// Matches lit = true | false | token_lit
1683 pub fn parse_lit(&mut self) -> Lit {
1684 let lo = self.span.lo;
1685 let lit = if self.eat_keyword(keywords::True) {
1687 } else if self.eat_keyword(keywords::False) {
1690 let token = self.bump_and_get();
1691 let lit = self.lit_from_token(&token);
1694 codemap::Spanned { node: lit, span: mk_sp(lo, self.last_span.hi) }
1697 /// matches '-' lit | lit
1698 pub fn parse_literal_maybe_minus(&mut self) -> P<Expr> {
1699 let minus_lo = self.span.lo;
1700 let minus_present = self.eat(&token::BINOP(token::MINUS));
1702 let lo = self.span.lo;
1703 let literal = P(self.parse_lit());
1704 let hi = self.span.hi;
1705 let expr = self.mk_expr(lo, hi, ExprLit(literal));
1708 let minus_hi = self.span.hi;
1709 let unary = self.mk_unary(UnNeg, expr);
1710 self.mk_expr(minus_lo, minus_hi, unary)
1716 /// Parses a path and optional type parameter bounds, depending on the
1717 /// mode. The `mode` parameter determines whether lifetimes, types, and/or
1718 /// bounds are permitted and whether `::` must precede type parameter
1720 pub fn parse_path(&mut self, mode: PathParsingMode) -> PathAndBounds {
1721 // Check for a whole path...
1722 let found = match self.token {
1723 INTERPOLATED(token::NtPath(_)) => Some(self.bump_and_get()),
1727 Some(INTERPOLATED(token::NtPath(box path))) => {
1728 return PathAndBounds {
1736 let lo = self.span.lo;
1737 let is_global = self.eat(&token::MOD_SEP);
1739 // Parse any number of segments and bound sets. A segment is an
1740 // identifier followed by an optional lifetime and a set of types.
1741 // A bound set is a set of type parameter bounds.
1742 let mut segments = Vec::new();
1744 // First, parse an identifier.
1745 let identifier = self.parse_ident();
1747 // Parse the '::' before type parameters if it's required. If
1748 // it is required and wasn't present, then we're done.
1749 if mode == LifetimeAndTypesWithColons &&
1750 !self.eat(&token::MOD_SEP) {
1751 segments.push(ast::PathSegment {
1752 identifier: identifier,
1753 lifetimes: Vec::new(),
1754 types: OwnedSlice::empty(),
1759 // Parse the `<` before the lifetime and types, if applicable.
1760 let (any_lifetime_or_types, lifetimes, types) = {
1761 if mode != NoTypesAllowed && self.eat_lt(false) {
1762 let (lifetimes, types) =
1763 self.parse_generic_values_after_lt();
1764 (true, lifetimes, OwnedSlice::from_vec(types))
1766 (false, Vec::new(), OwnedSlice::empty())
1770 // Assemble and push the result.
1771 segments.push(ast::PathSegment {
1772 identifier: identifier,
1773 lifetimes: lifetimes,
1777 // We're done if we don't see a '::', unless the mode required
1778 // a double colon to get here in the first place.
1779 if !(mode == LifetimeAndTypesWithColons &&
1780 !any_lifetime_or_types) {
1781 if !self.eat(&token::MOD_SEP) {
1787 // Next, parse a plus and bounded type parameters, if
1788 // applicable. We need to remember whether the separate was
1789 // present for later, because in some contexts it's a parse
1792 if mode == LifetimeAndTypesAndBounds &&
1793 self.eat(&token::BINOP(token::PLUS))
1795 let bounds = self.parse_ty_param_bounds();
1797 // For some reason that I do not fully understand, we
1798 // do not permit an empty list in the case where it is
1799 // introduced by a `+`, but we do for `:` and other
1800 // separators. -nmatsakis
1801 if bounds.len() == 0 {
1802 let last_span = self.last_span;
1803 self.span_err(last_span,
1804 "at least one type parameter bound \
1805 must be specified");
1814 // Assemble the span.
1815 let span = mk_sp(lo, self.last_span.hi);
1817 // Assemble the result.
1828 /// parses 0 or 1 lifetime
1829 pub fn parse_opt_lifetime(&mut self) -> Option<ast::Lifetime> {
1831 token::LIFETIME(..) => {
1832 Some(self.parse_lifetime())
1840 /// Parses a single lifetime
1841 /// Matches lifetime = LIFETIME
1842 pub fn parse_lifetime(&mut self) -> ast::Lifetime {
1844 token::LIFETIME(i) => {
1845 let span = self.span;
1847 return ast::Lifetime {
1848 id: ast::DUMMY_NODE_ID,
1854 self.fatal(format!("expected a lifetime name").as_slice());
1859 pub fn parse_lifetime_defs(&mut self) -> Vec<ast::LifetimeDef> {
1861 * Parses `lifetime_defs = [ lifetime_defs { ',' lifetime_defs } ]`
1862 * where `lifetime_def = lifetime [':' lifetimes]`
1865 let mut res = Vec::new();
1868 token::LIFETIME(_) => {
1869 let lifetime = self.parse_lifetime();
1871 if self.eat(&token::COLON) {
1872 self.parse_lifetimes(token::BINOP(token::PLUS))
1876 res.push(ast::LifetimeDef { lifetime: lifetime,
1886 token::COMMA => { self.bump(); }
1887 token::GT => { return res; }
1888 token::BINOP(token::SHR) => { return res; }
1890 let msg = format!("expected `,` or `>` after lifetime \
1893 self.fatal(msg.as_slice());
1899 // matches lifetimes = ( lifetime ) | ( lifetime , lifetimes )
1900 // actually, it matches the empty one too, but putting that in there
1901 // messes up the grammar....
1902 pub fn parse_lifetimes(&mut self, sep: token::Token) -> Vec<ast::Lifetime> {
1904 * Parses zero or more comma separated lifetimes.
1905 * Expects each lifetime to be followed by either
1906 * a comma or `>`. Used when parsing type parameter
1907 * lists, where we expect something like `<'a, 'b, T>`.
1910 let mut res = Vec::new();
1913 token::LIFETIME(_) => {
1914 res.push(self.parse_lifetime());
1921 if self.token != sep {
1929 pub fn token_is_mutability(tok: &token::Token) -> bool {
1930 token::is_keyword(keywords::Mut, tok) ||
1931 token::is_keyword(keywords::Const, tok)
1934 /// Parse mutability declaration (mut/const/imm)
1935 pub fn parse_mutability(&mut self) -> Mutability {
1936 if self.eat_keyword(keywords::Mut) {
1943 /// Parse ident COLON expr
1944 pub fn parse_field(&mut self) -> Field {
1945 let lo = self.span.lo;
1946 let i = self.parse_ident();
1947 let hi = self.last_span.hi;
1948 self.expect(&token::COLON);
1949 let e = self.parse_expr();
1951 ident: spanned(lo, hi, i),
1952 span: mk_sp(lo, e.span.hi),
1957 pub fn mk_expr(&mut self, lo: BytePos, hi: BytePos, node: Expr_) -> P<Expr> {
1959 id: ast::DUMMY_NODE_ID,
1961 span: mk_sp(lo, hi),
1965 pub fn mk_unary(&mut self, unop: ast::UnOp, expr: P<Expr>) -> ast::Expr_ {
1966 ExprUnary(unop, expr)
1969 pub fn mk_binary(&mut self, binop: ast::BinOp, lhs: P<Expr>, rhs: P<Expr>) -> ast::Expr_ {
1970 ExprBinary(binop, lhs, rhs)
1973 pub fn mk_call(&mut self, f: P<Expr>, args: Vec<P<Expr>>) -> ast::Expr_ {
1977 fn mk_method_call(&mut self,
1978 ident: ast::SpannedIdent,
1982 ExprMethodCall(ident, tps, args)
1985 pub fn mk_index(&mut self, expr: P<Expr>, idx: P<Expr>) -> ast::Expr_ {
1986 ExprIndex(expr, idx)
1989 pub fn mk_slice(&mut self, expr: P<Expr>,
1990 start: Option<P<Expr>>,
1991 end: Option<P<Expr>>,
1994 ExprSlice(expr, start, end, mutbl)
1997 pub fn mk_field(&mut self, expr: P<Expr>, ident: ast::SpannedIdent,
1998 tys: Vec<P<Ty>>) -> ast::Expr_ {
1999 ExprField(expr, ident, tys)
2002 pub fn mk_tup_field(&mut self, expr: P<Expr>, idx: codemap::Spanned<uint>,
2003 tys: Vec<P<Ty>>) -> ast::Expr_ {
2004 ExprTupField(expr, idx, tys)
2007 pub fn mk_assign_op(&mut self, binop: ast::BinOp,
2008 lhs: P<Expr>, rhs: P<Expr>) -> ast::Expr_ {
2009 ExprAssignOp(binop, lhs, rhs)
2012 pub fn mk_mac_expr(&mut self, lo: BytePos, hi: BytePos, m: Mac_) -> P<Expr> {
2014 id: ast::DUMMY_NODE_ID,
2015 node: ExprMac(codemap::Spanned {node: m, span: mk_sp(lo, hi)}),
2016 span: mk_sp(lo, hi),
2020 pub fn mk_lit_u32(&mut self, i: u32) -> P<Expr> {
2021 let span = &self.span;
2022 let lv_lit = P(codemap::Spanned {
2023 node: LitInt(i as u64, ast::UnsignedIntLit(TyU32)),
2028 id: ast::DUMMY_NODE_ID,
2029 node: ExprLit(lv_lit),
2034 /// At the bottom (top?) of the precedence hierarchy,
2035 /// parse things like parenthesized exprs,
2036 /// macros, return, etc.
2037 pub fn parse_bottom_expr(&mut self) -> P<Expr> {
2038 maybe_whole_expr!(self);
2040 let lo = self.span.lo;
2041 let mut hi = self.span.hi;
2048 // (e) is parenthesized e
2049 // (e,) is a tuple with only one field, e
2050 let mut trailing_comma = false;
2051 if self.token == token::RPAREN {
2054 let lit = P(spanned(lo, hi, LitNil));
2055 return self.mk_expr(lo, hi, ExprLit(lit));
2057 let mut es = vec!(self.parse_expr());
2058 self.commit_expr(&**es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]);
2059 while self.token == token::COMMA {
2061 if self.token != token::RPAREN {
2062 es.push(self.parse_expr());
2063 self.commit_expr(&**es.last().unwrap(), &[],
2064 &[token::COMMA, token::RPAREN]);
2066 trailing_comma = true;
2070 self.commit_expr_expecting(&**es.last().unwrap(), token::RPAREN);
2072 return if es.len() == 1 && !trailing_comma {
2073 self.mk_expr(lo, hi, ExprParen(es.into_iter().nth(0).unwrap()))
2075 self.mk_expr(lo, hi, ExprTup(es))
2080 let blk = self.parse_block_tail(lo, DefaultBlock);
2081 return self.mk_expr(blk.span.lo, blk.span.hi,
2084 token::BINOP(token::OR) | token::OROR => {
2085 return self.parse_lambda_expr(CaptureByRef);
2087 // FIXME #13626: Should be able to stick in
2088 // token::SELF_KEYWORD_NAME
2089 token::IDENT(id @ ast::Ident{
2090 name: ast::Name(token::SELF_KEYWORD_NAME_NUM),
2094 let path = ast_util::ident_to_path(mk_sp(lo, hi), id);
2095 ex = ExprPath(path);
2096 hi = self.last_span.hi;
2098 token::LBRACKET => {
2101 if self.token == token::RBRACKET {
2104 ex = ExprVec(Vec::new());
2107 let first_expr = self.parse_expr();
2108 if self.token == token::COMMA &&
2109 self.look_ahead(1, |t| *t == token::DOTDOT) {
2110 // Repeating vector syntax: [ 0, ..512 ]
2113 let count = self.parse_expr();
2114 self.expect(&token::RBRACKET);
2115 ex = ExprRepeat(first_expr, count);
2116 } else if self.token == token::COMMA {
2117 // Vector with two or more elements.
2119 let remaining_exprs = self.parse_seq_to_end(
2121 seq_sep_trailing_allowed(token::COMMA),
2124 let mut exprs = vec!(first_expr);
2125 exprs.extend(remaining_exprs.into_iter());
2126 ex = ExprVec(exprs);
2128 // Vector with one element.
2129 self.expect(&token::RBRACKET);
2130 ex = ExprVec(vec!(first_expr));
2133 hi = self.last_span.hi;
2136 if self.eat_keyword(keywords::Move) {
2137 return self.parse_lambda_expr(CaptureByValue);
2139 if self.eat_keyword(keywords::Proc) {
2140 let decl = self.parse_proc_decl();
2141 let body = self.parse_expr();
2142 let fakeblock = P(ast::Block {
2143 id: ast::DUMMY_NODE_ID,
2144 view_items: Vec::new(),
2146 rules: DefaultBlock,
2150 return self.mk_expr(lo, fakeblock.span.hi, ExprProc(decl, fakeblock));
2152 if self.eat_keyword(keywords::If) {
2153 return self.parse_if_expr();
2155 if self.eat_keyword(keywords::For) {
2156 return self.parse_for_expr(None);
2158 if self.eat_keyword(keywords::While) {
2159 return self.parse_while_expr(None);
2161 if Parser::token_is_lifetime(&self.token) {
2162 let lifetime = self.get_lifetime();
2164 self.expect(&token::COLON);
2165 if self.eat_keyword(keywords::While) {
2166 return self.parse_while_expr(Some(lifetime))
2168 if self.eat_keyword(keywords::For) {
2169 return self.parse_for_expr(Some(lifetime))
2171 if self.eat_keyword(keywords::Loop) {
2172 return self.parse_loop_expr(Some(lifetime))
2174 self.fatal("expected `while`, `for`, or `loop` after a label")
2176 if self.eat_keyword(keywords::Loop) {
2177 return self.parse_loop_expr(None);
2179 if self.eat_keyword(keywords::Continue) {
2180 let lo = self.span.lo;
2181 let ex = if Parser::token_is_lifetime(&self.token) {
2182 let lifetime = self.get_lifetime();
2184 ExprAgain(Some(lifetime))
2188 let hi = self.span.hi;
2189 return self.mk_expr(lo, hi, ex);
2191 if self.eat_keyword(keywords::Match) {
2192 return self.parse_match_expr();
2194 if self.eat_keyword(keywords::Unsafe) {
2195 return self.parse_block_expr(
2197 UnsafeBlock(ast::UserProvided));
2199 if self.eat_keyword(keywords::Return) {
2200 // RETURN expression
2201 if can_begin_expr(&self.token) {
2202 let e = self.parse_expr();
2204 ex = ExprRet(Some(e));
2208 } else if self.eat_keyword(keywords::Break) {
2210 if Parser::token_is_lifetime(&self.token) {
2211 let lifetime = self.get_lifetime();
2213 ex = ExprBreak(Some(lifetime));
2215 ex = ExprBreak(None);
2218 } else if self.token == token::MOD_SEP ||
2219 is_ident(&self.token) &&
2220 !self.is_keyword(keywords::True) &&
2221 !self.is_keyword(keywords::False) {
2223 self.parse_path(LifetimeAndTypesWithColons).path;
2225 // `!`, as an operator, is prefix, so we know this isn't that
2226 if self.token == token::NOT {
2227 // MACRO INVOCATION expression
2230 let ket = token::close_delimiter_for(&self.token)
2231 .unwrap_or_else(|| {
2232 self.fatal("expected open delimiter")
2236 let tts = self.parse_seq_to_end(
2239 |p| p.parse_token_tree());
2240 let hi = self.span.hi;
2242 return self.mk_mac_expr(lo,
2248 if self.token == token::LBRACE {
2249 // This is a struct literal, unless we're prohibited
2250 // from parsing struct literals here.
2251 if !self.restrictions.contains(RESTRICTION_NO_STRUCT_LITERAL) {
2252 // It's a struct literal.
2254 let mut fields = Vec::new();
2255 let mut base = None;
2257 while self.token != token::RBRACE {
2258 if self.eat(&token::DOTDOT) {
2259 base = Some(self.parse_expr());
2263 fields.push(self.parse_field());
2264 self.commit_expr(&*fields.last().unwrap().expr,
2269 if fields.len() == 0 && base.is_none() {
2270 let last_span = self.last_span;
2271 self.span_err(last_span,
2272 "structure literal must either \
2273 have at least one field or use \
2274 functional structure update \
2279 self.expect(&token::RBRACE);
2280 ex = ExprStruct(pth, fields, base);
2281 return self.mk_expr(lo, hi, ex);
2288 // other literal expression
2289 let lit = self.parse_lit();
2291 ex = ExprLit(P(lit));
2296 return self.mk_expr(lo, hi, ex);
2299 /// Parse a block or unsafe block
2300 pub fn parse_block_expr(&mut self, lo: BytePos, blk_mode: BlockCheckMode)
2302 self.expect(&token::LBRACE);
2303 let blk = self.parse_block_tail(lo, blk_mode);
2304 return self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk));
2307 /// parse a.b or a(13) or a[4] or just a
2308 pub fn parse_dot_or_call_expr(&mut self) -> P<Expr> {
2309 let b = self.parse_bottom_expr();
2310 self.parse_dot_or_call_expr_with(b)
2313 pub fn parse_dot_or_call_expr_with(&mut self, e0: P<Expr>) -> P<Expr> {
2319 if self.eat(&token::DOT) {
2321 token::IDENT(i, _) => {
2322 let dot = self.last_span.hi;
2325 let (_, tys) = if self.eat(&token::MOD_SEP) {
2327 self.parse_generic_values_after_lt()
2329 (Vec::new(), Vec::new())
2332 // expr.f() method call
2335 let mut es = self.parse_unspanned_seq(
2338 seq_sep_trailing_allowed(token::COMMA),
2341 hi = self.last_span.hi;
2344 let id = spanned(dot, hi, i);
2345 let nd = self.mk_method_call(id, tys, es);
2346 e = self.mk_expr(lo, hi, nd);
2349 let id = spanned(dot, hi, i);
2350 let field = self.mk_field(e, id, tys);
2351 e = self.mk_expr(lo, hi, field)
2355 token::LIT_INTEGER(n) => {
2356 let index = n.as_str();
2357 let dot = self.last_span.hi;
2360 let (_, tys) = if self.eat(&token::MOD_SEP) {
2362 self.parse_generic_values_after_lt()
2364 (Vec::new(), Vec::new())
2367 let num = from_str::<uint>(index);
2370 let id = spanned(dot, hi, n);
2371 let field = self.mk_tup_field(e, id, tys);
2372 e = self.mk_expr(lo, hi, field);
2375 let last_span = self.last_span;
2376 self.span_err(last_span, "invalid tuple or tuple struct index");
2380 token::LIT_FLOAT(n) => {
2382 let last_span = self.last_span;
2383 self.span_err(last_span,
2384 format!("unexpected token: `{}`", n.as_str()).as_slice());
2385 self.span_note(last_span,
2386 "try parenthesizing the first index; e.g., `(foo.0).1`");
2387 self.abort_if_errors();
2390 _ => self.unexpected()
2394 if self.expr_is_complete(&*e) { break; }
2398 let es = self.parse_unspanned_seq(
2401 seq_sep_trailing_allowed(token::COMMA),
2404 hi = self.last_span.hi;
2406 let nd = self.mk_call(e, es);
2407 e = self.mk_expr(lo, hi, nd);
2411 // Could be either an index expression or a slicing expression.
2412 // Any slicing non-terminal can have a mutable version with `mut`
2413 // after the opening square bracket.
2414 token::LBRACKET => {
2416 let mutbl = if self.eat_keyword(keywords::Mut) {
2423 token::RBRACKET => {
2426 let slice = self.mk_slice(e, None, None, mutbl);
2427 e = self.mk_expr(lo, hi, slice)
2434 token::RBRACKET => {
2437 let slice = self.mk_slice(e, None, None, mutbl);
2438 e = self.mk_expr(lo, hi, slice);
2440 self.span_err(e.span, "incorrect slicing expression: `[..]`");
2441 self.span_note(e.span,
2442 "use `expr[]` to construct a slice of the whole of expr");
2447 let e2 = self.parse_expr();
2448 self.commit_expr_expecting(&*e2, token::RBRACKET);
2449 let slice = self.mk_slice(e, None, Some(e2), mutbl);
2450 e = self.mk_expr(lo, hi, slice)
2454 // e[e] | e[e..] | e[e..e]
2456 let ix = self.parse_expr();
2461 let e2 = match self.token {
2463 token::RBRACKET => {
2469 let e2 = self.parse_expr();
2470 self.commit_expr_expecting(&*e2, token::RBRACKET);
2475 let slice = self.mk_slice(e, Some(ix), e2, mutbl);
2476 e = self.mk_expr(lo, hi, slice)
2480 if mutbl == ast::MutMutable {
2481 self.span_err(e.span,
2482 "`mut` keyword is invalid in index expressions");
2485 self.commit_expr_expecting(&*ix, token::RBRACKET);
2486 let index = self.mk_index(e, ix);
2487 e = self.mk_expr(lo, hi, index)
2500 /// Parse an optional separator followed by a kleene-style
2501 /// repetition token (+ or *).
2502 pub fn parse_sep_and_zerok(&mut self) -> (Option<token::Token>, bool) {
2503 fn parse_zerok(parser: &mut Parser) -> Option<bool> {
2504 match parser.token {
2505 token::BINOP(token::STAR) | token::BINOP(token::PLUS) => {
2506 let zerok = parser.token == token::BINOP(token::STAR);
2514 match parse_zerok(self) {
2515 Some(zerok) => return (None, zerok),
2519 let separator = self.bump_and_get();
2520 match parse_zerok(self) {
2521 Some(zerok) => (Some(separator), zerok),
2522 None => self.fatal("expected `*` or `+`")
2526 /// parse a single token tree from the input.
2527 pub fn parse_token_tree(&mut self) -> TokenTree {
2528 // FIXME #6994: currently, this is too eager. It
2529 // parses token trees but also identifies TTSeq's
2530 // and TTNonterminal's; it's too early to know yet
2531 // whether something will be a nonterminal or a seq
2533 maybe_whole!(deref self, NtTT);
2535 // this is the fall-through for the 'match' below.
2536 // invariants: the current token is not a left-delimiter,
2537 // not an EOF, and not the desired right-delimiter (if
2538 // it were, parse_seq_to_before_end would have prevented
2539 // reaching this point.
2540 fn parse_non_delim_tt_tok(p: &mut Parser) -> TokenTree {
2541 maybe_whole!(deref p, NtTT);
2543 token::RPAREN | token::RBRACE | token::RBRACKET => {
2544 // This is a conservative error: only report the last unclosed delimiter. The
2545 // previous unclosed delimiters could actually be closed! The parser just hasn't
2546 // gotten to them yet.
2547 match p.open_braces.last() {
2549 Some(&sp) => p.span_note(sp, "unclosed delimiter"),
2551 let token_str = p.this_token_to_string();
2552 p.fatal(format!("incorrect close delimiter: `{}`",
2553 token_str).as_slice())
2555 /* we ought to allow different depths of unquotation */
2556 token::DOLLAR if p.quote_depth > 0u => {
2560 if p.token == token::LPAREN {
2561 let seq = p.parse_seq(
2565 |p| p.parse_token_tree()
2567 let (s, z) = p.parse_sep_and_zerok();
2568 let seq = match seq {
2569 Spanned { node, .. } => node,
2571 TTSeq(mk_sp(sp.lo, p.span.hi), Rc::new(seq), s, z)
2573 TTNonterminal(sp, p.parse_ident())
2582 // turn the next token into a TTTok:
2583 fn parse_any_tt_tok(p: &mut Parser) -> TokenTree {
2584 TTTok(p.span, p.bump_and_get())
2587 match (&self.token, token::close_delimiter_for(&self.token)) {
2588 (&token::EOF, _) => {
2589 let open_braces = self.open_braces.clone();
2590 for sp in open_braces.iter() {
2591 self.span_note(*sp, "Did you mean to close this delimiter?");
2593 // There shouldn't really be a span, but it's easier for the test runner
2594 // if we give it one
2595 self.fatal("this file contains an un-closed delimiter ");
2597 (_, Some(close_delim)) => {
2598 // Parse the open delimiter.
2599 self.open_braces.push(self.span);
2600 let mut result = vec!(parse_any_tt_tok(self));
2603 self.parse_seq_to_before_end(&close_delim,
2605 |p| p.parse_token_tree());
2606 result.extend(trees.into_iter());
2608 // Parse the close delimiter.
2609 result.push(parse_any_tt_tok(self));
2610 self.open_braces.pop().unwrap();
2612 TTDelim(Rc::new(result))
2614 _ => parse_non_delim_tt_tok(self)
2618 // parse a stream of tokens into a list of TokenTree's,
2620 pub fn parse_all_token_trees(&mut self) -> Vec<TokenTree> {
2621 let mut tts = Vec::new();
2622 while self.token != token::EOF {
2623 tts.push(self.parse_token_tree());
2628 pub fn parse_matchers(&mut self) -> Vec<Matcher> {
2629 // unification of Matcher's and TokenTree's would vastly improve
2630 // the interpolation of Matcher's
2631 maybe_whole!(self, NtMatchers);
2632 let mut name_idx = 0u;
2633 match token::close_delimiter_for(&self.token) {
2634 Some(other_delimiter) => {
2636 self.parse_matcher_subseq_upto(&mut name_idx, &other_delimiter)
2638 None => self.fatal("expected open delimiter")
2642 /// This goofy function is necessary to correctly match parens in Matcher's.
2643 /// Otherwise, `$( ( )` would be a valid Matcher, and `$( () )` would be
2644 /// invalid. It's similar to common::parse_seq.
2645 pub fn parse_matcher_subseq_upto(&mut self,
2646 name_idx: &mut uint,
2649 let mut ret_val = Vec::new();
2650 let mut lparens = 0u;
2652 while self.token != *ket || lparens > 0u {
2653 if self.token == token::LPAREN { lparens += 1u; }
2654 if self.token == token::RPAREN { lparens -= 1u; }
2655 ret_val.push(self.parse_matcher(name_idx));
2663 pub fn parse_matcher(&mut self, name_idx: &mut uint) -> Matcher {
2664 let lo = self.span.lo;
2666 let m = if self.token == token::DOLLAR {
2668 if self.token == token::LPAREN {
2669 let name_idx_lo = *name_idx;
2671 let ms = self.parse_matcher_subseq_upto(name_idx,
2674 self.fatal("repetition body must be nonempty");
2676 let (sep, zerok) = self.parse_sep_and_zerok();
2677 MatchSeq(ms, sep, zerok, name_idx_lo, *name_idx)
2679 let bound_to = self.parse_ident();
2680 self.expect(&token::COLON);
2681 let nt_name = self.parse_ident();
2682 let m = MatchNonterminal(bound_to, nt_name, *name_idx);
2687 MatchTok(self.bump_and_get())
2690 return spanned(lo, self.span.hi, m);
2693 /// Parse a prefix-operator expr
2694 pub fn parse_prefix_expr(&mut self) -> P<Expr> {
2695 let lo = self.span.lo;
2702 let e = self.parse_prefix_expr();
2704 ex = self.mk_unary(UnNot, e);
2706 token::BINOP(token::MINUS) => {
2708 let e = self.parse_prefix_expr();
2710 ex = self.mk_unary(UnNeg, e);
2712 token::BINOP(token::STAR) => {
2714 let e = self.parse_prefix_expr();
2716 ex = self.mk_unary(UnDeref, e);
2718 token::BINOP(token::AND) | token::ANDAND => {
2720 let m = self.parse_mutability();
2721 let e = self.parse_prefix_expr();
2723 ex = ExprAddrOf(m, e);
2727 let last_span = self.last_span;
2729 token::LBRACKET => self.obsolete(last_span, ObsoleteOwnedVector),
2730 _ => self.obsolete(last_span, ObsoleteOwnedExpr)
2733 let e = self.parse_prefix_expr();
2735 ex = self.mk_unary(UnUniq, e);
2737 token::IDENT(_, _) => {
2738 if !self.is_keyword(keywords::Box) {
2739 return self.parse_dot_or_call_expr();
2744 // Check for a place: `box(PLACE) EXPR`.
2745 if self.eat(&token::LPAREN) {
2746 // Support `box() EXPR` as the default.
2747 if !self.eat(&token::RPAREN) {
2748 let place = self.parse_expr();
2749 self.expect(&token::RPAREN);
2750 let subexpression = self.parse_prefix_expr();
2751 hi = subexpression.span.hi;
2752 ex = ExprBox(place, subexpression);
2753 return self.mk_expr(lo, hi, ex);
2757 // Otherwise, we use the unique pointer default.
2758 let subexpression = self.parse_prefix_expr();
2759 hi = subexpression.span.hi;
2760 ex = self.mk_unary(UnUniq, subexpression);
2762 _ => return self.parse_dot_or_call_expr()
2764 return self.mk_expr(lo, hi, ex);
2767 /// Parse an expression of binops
2768 pub fn parse_binops(&mut self) -> P<Expr> {
2769 let prefix_expr = self.parse_prefix_expr();
2770 self.parse_more_binops(prefix_expr, 0)
2773 /// Parse an expression of binops of at least min_prec precedence
2774 pub fn parse_more_binops(&mut self, lhs: P<Expr>, min_prec: uint) -> P<Expr> {
2775 if self.expr_is_complete(&*lhs) { return lhs; }
2777 // Prevent dynamic borrow errors later on by limiting the
2778 // scope of the borrows.
2779 if self.token == token::BINOP(token::OR) &&
2780 self.restrictions.contains(RESTRICTION_NO_BAR_OP) {
2784 let cur_opt = token_to_binop(&self.token);
2787 let cur_prec = operator_prec(cur_op);
2788 if cur_prec > min_prec {
2790 let expr = self.parse_prefix_expr();
2791 let rhs = self.parse_more_binops(expr, cur_prec);
2792 let lhs_span = lhs.span;
2793 let rhs_span = rhs.span;
2794 let binary = self.mk_binary(cur_op, lhs, rhs);
2795 let bin = self.mk_expr(lhs_span.lo, rhs_span.hi, binary);
2796 self.parse_more_binops(bin, min_prec)
2802 if as_prec > min_prec && self.eat_keyword(keywords::As) {
2803 let rhs = self.parse_ty(false);
2804 let _as = self.mk_expr(lhs.span.lo,
2806 ExprCast(lhs, rhs));
2807 self.parse_more_binops(_as, min_prec)
2815 /// Parse an assignment expression....
2816 /// actually, this seems to be the main entry point for
2817 /// parsing an arbitrary expression.
2818 pub fn parse_assign_expr(&mut self) -> P<Expr> {
2819 let lo = self.span.lo;
2820 let lhs = self.parse_binops();
2821 let restrictions = self.restrictions & RESTRICTION_NO_STRUCT_LITERAL;
2825 let rhs = self.parse_expr_res(restrictions);
2826 self.mk_expr(lo, rhs.span.hi, ExprAssign(lhs, rhs))
2828 token::BINOPEQ(op) => {
2830 let rhs = self.parse_expr_res(restrictions);
2831 let aop = match op {
2832 token::PLUS => BiAdd,
2833 token::MINUS => BiSub,
2834 token::STAR => BiMul,
2835 token::SLASH => BiDiv,
2836 token::PERCENT => BiRem,
2837 token::CARET => BiBitXor,
2838 token::AND => BiBitAnd,
2839 token::OR => BiBitOr,
2840 token::SHL => BiShl,
2843 let rhs_span = rhs.span;
2844 let assign_op = self.mk_assign_op(aop, lhs, rhs);
2845 self.mk_expr(lo, rhs_span.hi, assign_op)
2853 /// Parse an 'if' or 'if let' expression ('if' token already eaten)
2854 pub fn parse_if_expr(&mut self) -> P<Expr> {
2855 if self.is_keyword(keywords::Let) {
2856 return self.parse_if_let_expr();
2858 let lo = self.last_span.lo;
2859 let cond = self.parse_expr_res(RESTRICTION_NO_STRUCT_LITERAL);
2860 let thn = self.parse_block();
2861 let mut els: Option<P<Expr>> = None;
2862 let mut hi = thn.span.hi;
2863 if self.eat_keyword(keywords::Else) {
2864 let elexpr = self.parse_else_expr();
2865 hi = elexpr.span.hi;
2868 self.mk_expr(lo, hi, ExprIf(cond, thn, els))
2871 /// Parse an 'if let' expression ('if' token already eaten)
2872 pub fn parse_if_let_expr(&mut self) -> P<Expr> {
2873 let lo = self.last_span.lo;
2874 self.expect_keyword(keywords::Let);
2875 let pat = self.parse_pat();
2876 self.expect(&token::EQ);
2877 let expr = self.parse_expr_res(RESTRICTION_NO_STRUCT_LITERAL);
2878 let thn = self.parse_block();
2879 let (hi, els) = if self.eat_keyword(keywords::Else) {
2880 let expr = self.parse_else_expr();
2881 (expr.span.hi, Some(expr))
2885 self.mk_expr(lo, hi, ExprIfLet(pat, expr, thn, els))
2889 pub fn parse_lambda_expr(&mut self, capture_clause: CaptureClause)
2891 let lo = self.span.lo;
2892 let (decl, optional_unboxed_closure_kind) =
2893 self.parse_fn_block_decl();
2894 let body = self.parse_expr();
2895 let fakeblock = P(ast::Block {
2896 id: ast::DUMMY_NODE_ID,
2897 view_items: Vec::new(),
2901 rules: DefaultBlock,
2904 match optional_unboxed_closure_kind {
2905 Some(unboxed_closure_kind) => {
2908 ExprUnboxedFn(capture_clause,
2909 unboxed_closure_kind,
2916 ExprFnBlock(capture_clause, decl, fakeblock))
2921 pub fn parse_else_expr(&mut self) -> P<Expr> {
2922 if self.eat_keyword(keywords::If) {
2923 return self.parse_if_expr();
2925 let blk = self.parse_block();
2926 return self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk));
2930 /// Parse a 'for' .. 'in' expression ('for' token already eaten)
2931 pub fn parse_for_expr(&mut self, opt_ident: Option<ast::Ident>) -> P<Expr> {
2932 // Parse: `for <src_pat> in <src_expr> <src_loop_block>`
2934 let lo = self.last_span.lo;
2935 let pat = self.parse_pat();
2936 self.expect_keyword(keywords::In);
2937 let expr = self.parse_expr_res(RESTRICTION_NO_STRUCT_LITERAL);
2938 let loop_block = self.parse_block();
2939 let hi = self.span.hi;
2941 self.mk_expr(lo, hi, ExprForLoop(pat, expr, loop_block, opt_ident))
2944 /// Parse a 'while' or 'while let' expression ('while' token already eaten)
2945 pub fn parse_while_expr(&mut self, opt_ident: Option<ast::Ident>) -> P<Expr> {
2946 if self.is_keyword(keywords::Let) {
2947 return self.parse_while_let_expr(opt_ident);
2949 let lo = self.last_span.lo;
2950 let cond = self.parse_expr_res(RESTRICTION_NO_STRUCT_LITERAL);
2951 let body = self.parse_block();
2952 let hi = body.span.hi;
2953 return self.mk_expr(lo, hi, ExprWhile(cond, body, opt_ident));
2956 /// Parse a 'while let' expression ('while' token already eaten)
2957 pub fn parse_while_let_expr(&mut self, opt_ident: Option<ast::Ident>) -> P<Expr> {
2958 let lo = self.last_span.lo;
2959 self.expect_keyword(keywords::Let);
2960 let pat = self.parse_pat();
2961 self.expect(&token::EQ);
2962 let expr = self.parse_expr_res(RESTRICTION_NO_STRUCT_LITERAL);
2963 let body = self.parse_block();
2964 let hi = body.span.hi;
2965 return self.mk_expr(lo, hi, ExprWhileLet(pat, expr, body, opt_ident));
2968 pub fn parse_loop_expr(&mut self, opt_ident: Option<ast::Ident>) -> P<Expr> {
2969 let lo = self.last_span.lo;
2970 let body = self.parse_block();
2971 let hi = body.span.hi;
2972 self.mk_expr(lo, hi, ExprLoop(body, opt_ident))
2975 fn parse_match_expr(&mut self) -> P<Expr> {
2976 let lo = self.last_span.lo;
2977 let discriminant = self.parse_expr_res(RESTRICTION_NO_STRUCT_LITERAL);
2978 self.commit_expr_expecting(&*discriminant, token::LBRACE);
2979 let mut arms: Vec<Arm> = Vec::new();
2980 while self.token != token::RBRACE {
2981 arms.push(self.parse_arm());
2983 let hi = self.span.hi;
2985 return self.mk_expr(lo, hi, ExprMatch(discriminant, arms, MatchNormal));
2988 pub fn parse_arm(&mut self) -> Arm {
2989 let attrs = self.parse_outer_attributes();
2990 let pats = self.parse_pats();
2991 let mut guard = None;
2992 if self.eat_keyword(keywords::If) {
2993 guard = Some(self.parse_expr());
2995 self.expect(&token::FAT_ARROW);
2996 let expr = self.parse_expr_res(RESTRICTION_STMT_EXPR);
2999 !classify::expr_is_simple_block(&*expr)
3000 && self.token != token::RBRACE;
3003 self.commit_expr(&*expr, &[token::COMMA], &[token::RBRACE]);
3005 self.eat(&token::COMMA);
3016 /// Parse an expression
3017 pub fn parse_expr(&mut self) -> P<Expr> {
3018 return self.parse_expr_res(UNRESTRICTED);
3021 /// Parse an expression, subject to the given restrictions
3022 pub fn parse_expr_res(&mut self, r: Restrictions) -> P<Expr> {
3023 let old = self.restrictions;
3024 self.restrictions = r;
3025 let e = self.parse_assign_expr();
3026 self.restrictions = old;
3030 /// Parse the RHS of a local variable declaration (e.g. '= 14;')
3031 fn parse_initializer(&mut self) -> Option<P<Expr>> {
3032 if self.token == token::EQ {
3034 Some(self.parse_expr())
3040 /// Parse patterns, separated by '|' s
3041 fn parse_pats(&mut self) -> Vec<P<Pat>> {
3042 let mut pats = Vec::new();
3044 pats.push(self.parse_pat());
3045 if self.token == token::BINOP(token::OR) { self.bump(); }
3046 else { return pats; }
3050 fn parse_pat_vec_elements(
3052 ) -> (Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>) {
3053 let mut before = Vec::new();
3054 let mut slice = None;
3055 let mut after = Vec::new();
3056 let mut first = true;
3057 let mut before_slice = true;
3059 while self.token != token::RBRACKET {
3063 self.expect(&token::COMMA);
3067 if self.token == token::DOTDOT {
3070 if self.token == token::COMMA ||
3071 self.token == token::RBRACKET {
3072 slice = Some(P(ast::Pat {
3073 id: ast::DUMMY_NODE_ID,
3074 node: PatWild(PatWildMulti),
3077 before_slice = false;
3079 let _ = self.parse_pat();
3080 let span = self.span;
3081 self.obsolete(span, ObsoleteSubsliceMatch);
3087 let subpat = self.parse_pat();
3088 if before_slice && self.token == token::DOTDOT {
3090 slice = Some(subpat);
3091 before_slice = false;
3092 } else if before_slice {
3093 before.push(subpat);
3099 (before, slice, after)
3102 /// Parse the fields of a struct-like pattern
3103 fn parse_pat_fields(&mut self) -> (Vec<codemap::Spanned<ast::FieldPat>> , bool) {
3104 let mut fields = Vec::new();
3105 let mut etc = false;
3106 let mut first = true;
3107 while self.token != token::RBRACE {
3111 self.expect(&token::COMMA);
3112 // accept trailing commas
3113 if self.token == token::RBRACE { break }
3116 let lo = self.span.lo;
3119 if self.token == token::DOTDOT {
3121 if self.token != token::RBRACE {
3122 let token_str = self.this_token_to_string();
3123 self.fatal(format!("expected `{}`, found `{}`", "}",
3124 token_str).as_slice())
3130 let bind_type = if self.eat_keyword(keywords::Mut) {
3131 BindByValue(MutMutable)
3132 } else if self.eat_keyword(keywords::Ref) {
3133 BindByRef(self.parse_mutability())
3135 BindByValue(MutImmutable)
3138 let fieldname = self.parse_ident();
3140 let (subpat, is_shorthand) = if self.token == token::COLON {
3142 BindByRef(..) | BindByValue(MutMutable) => {
3143 let token_str = self.this_token_to_string();
3144 self.fatal(format!("unexpected `{}`",
3145 token_str).as_slice())
3151 let pat = self.parse_pat();
3155 hi = self.last_span.hi;
3156 let fieldpath = codemap::Spanned{span:self.last_span, node: fieldname};
3158 id: ast::DUMMY_NODE_ID,
3159 node: PatIdent(bind_type, fieldpath, None),
3160 span: self.last_span
3163 fields.push(codemap::Spanned { span: mk_sp(lo, hi),
3164 node: ast::FieldPat { ident: fieldname,
3166 is_shorthand: is_shorthand }});
3168 return (fields, etc);
3171 /// Parse a pattern.
3172 pub fn parse_pat(&mut self) -> P<Pat> {
3173 maybe_whole!(self, NtPat);
3175 let lo = self.span.lo;
3180 token::UNDERSCORE => {
3182 pat = PatWild(PatWildSingle);
3183 hi = self.last_span.hi;
3185 id: ast::DUMMY_NODE_ID,
3193 let sub = self.parse_pat();
3195 let last_span = self.last_span;
3197 self.obsolete(last_span, ObsoleteOwnedPattern);
3199 id: ast::DUMMY_NODE_ID,
3204 token::BINOP(token::AND) | token::ANDAND => {
3206 let lo = self.span.lo;
3208 let sub = self.parse_pat();
3209 pat = PatRegion(sub);
3210 hi = self.last_span.hi;
3212 id: ast::DUMMY_NODE_ID,
3218 // parse (pat,pat,pat,...) as tuple
3220 if self.token == token::RPAREN {
3223 let lit = P(codemap::Spanned {
3225 span: mk_sp(lo, hi)});
3226 let expr = self.mk_expr(lo, hi, ExprLit(lit));
3229 let mut fields = vec!(self.parse_pat());
3230 if self.look_ahead(1, |t| *t != token::RPAREN) {
3231 while self.token == token::COMMA {
3233 if self.token == token::RPAREN { break; }
3234 fields.push(self.parse_pat());
3237 if fields.len() == 1 { self.expect(&token::COMMA); }
3238 self.expect(&token::RPAREN);
3239 pat = PatTup(fields);
3241 hi = self.last_span.hi;
3243 id: ast::DUMMY_NODE_ID,
3248 token::LBRACKET => {
3249 // parse [pat,pat,...] as vector pattern
3251 let (before, slice, after) =
3252 self.parse_pat_vec_elements();
3254 self.expect(&token::RBRACKET);
3255 pat = ast::PatVec(before, slice, after);
3256 hi = self.last_span.hi;
3258 id: ast::DUMMY_NODE_ID,
3265 // at this point, token != _, ~, &, &&, (, [
3267 if (!is_ident_or_path(&self.token) && self.token != token::MOD_SEP)
3268 || self.is_keyword(keywords::True)
3269 || self.is_keyword(keywords::False) {
3270 // Parse an expression pattern or exp .. exp.
3272 // These expressions are limited to literals (possibly
3273 // preceded by unary-minus) or identifiers.
3274 let val = self.parse_literal_maybe_minus();
3275 if (self.token == token::DOTDOTDOT) &&
3276 self.look_ahead(1, |t| {
3277 *t != token::COMMA && *t != token::RBRACKET
3280 let end = if is_ident_or_path(&self.token) {
3281 let path = self.parse_path(LifetimeAndTypesWithColons)
3283 let hi = self.span.hi;
3284 self.mk_expr(lo, hi, ExprPath(path))
3286 self.parse_literal_maybe_minus()
3288 pat = PatRange(val, end);
3292 } else if self.eat_keyword(keywords::Mut) {
3293 pat = self.parse_pat_ident(BindByValue(MutMutable));
3294 } else if self.eat_keyword(keywords::Ref) {
3296 let mutbl = self.parse_mutability();
3297 pat = self.parse_pat_ident(BindByRef(mutbl));
3298 } else if self.eat_keyword(keywords::Box) {
3301 // FIXME(#13910): Rename to `PatBox` and extend to full DST
3303 let sub = self.parse_pat();
3305 hi = self.last_span.hi;
3307 id: ast::DUMMY_NODE_ID,
3312 let can_be_enum_or_struct = self.look_ahead(1, |t| {
3314 token::LPAREN | token::LBRACKET | token::LT |
3315 token::LBRACE | token::MOD_SEP => true,
3320 if self.look_ahead(1, |t| *t == token::DOTDOTDOT) &&
3321 self.look_ahead(2, |t| {
3322 *t != token::COMMA && *t != token::RBRACKET
3324 let start = self.parse_expr_res(RESTRICTION_NO_BAR_OP);
3325 self.eat(&token::DOTDOTDOT);
3326 let end = self.parse_expr_res(RESTRICTION_NO_BAR_OP);
3327 pat = PatRange(start, end);
3328 } else if is_plain_ident(&self.token) && !can_be_enum_or_struct {
3329 let id = self.parse_ident();
3330 let id_span = self.last_span;
3331 let pth1 = codemap::Spanned{span:id_span, node: id};
3332 if self.eat(&token::NOT) {
3334 let ket = token::close_delimiter_for(&self.token)
3335 .unwrap_or_else(|| self.fatal("expected open delimiter"));
3338 let tts = self.parse_seq_to_end(&ket,
3340 |p| p.parse_token_tree());
3342 let mac = MacInvocTT(ident_to_path(id_span,id), tts, EMPTY_CTXT);
3343 pat = ast::PatMac(codemap::Spanned {node: mac, span: self.span});
3345 let sub = if self.eat(&token::AT) {
3347 Some(self.parse_pat())
3352 pat = PatIdent(BindByValue(MutImmutable), pth1, sub);
3355 // parse an enum pat
3356 let enum_path = self.parse_path(LifetimeAndTypesWithColons)
3362 self.parse_pat_fields();
3364 pat = PatStruct(enum_path, fields, etc);
3367 let mut args: Vec<P<Pat>> = Vec::new();
3370 let is_dotdot = self.look_ahead(1, |t| {
3372 token::DOTDOT => true,
3377 // This is a "top constructor only" pat
3380 self.expect(&token::RPAREN);
3381 pat = PatEnum(enum_path, None);
3383 args = self.parse_enum_variant_seq(
3386 seq_sep_trailing_allowed(token::COMMA),
3389 pat = PatEnum(enum_path, Some(args));
3393 if !enum_path.global &&
3394 enum_path.segments.len() == 1 &&
3395 enum_path.segments[0]
3398 enum_path.segments[0]
3401 // it could still be either an enum
3402 // or an identifier pattern, resolve
3403 // will sort it out:
3404 pat = PatIdent(BindByValue(MutImmutable),
3406 span: enum_path.span,
3407 node: enum_path.segments[0]
3411 pat = PatEnum(enum_path, Some(args));
3419 hi = self.last_span.hi;
3421 id: ast::DUMMY_NODE_ID,
3423 span: mk_sp(lo, hi),
3427 /// Parse ident or ident @ pat
3428 /// used by the copy foo and ref foo patterns to give a good
3429 /// error message when parsing mistakes like ref foo(a,b)
3430 fn parse_pat_ident(&mut self,
3431 binding_mode: ast::BindingMode)
3433 if !is_plain_ident(&self.token) {
3434 let span = self.span;
3435 let tok_str = self.this_token_to_string();
3436 self.span_fatal(span,
3437 format!("expected identifier, found `{}`", tok_str).as_slice());
3439 let ident = self.parse_ident();
3440 let last_span = self.last_span;
3441 let name = codemap::Spanned{span: last_span, node: ident};
3442 let sub = if self.eat(&token::AT) {
3443 Some(self.parse_pat())
3448 // just to be friendly, if they write something like
3450 // we end up here with ( as the current token. This shortly
3451 // leads to a parse error. Note that if there is no explicit
3452 // binding mode then we do not end up here, because the lookahead
3453 // will direct us over to parse_enum_variant()
3454 if self.token == token::LPAREN {
3455 let last_span = self.last_span;
3458 "expected identifier, found enum pattern");
3461 PatIdent(binding_mode, name, sub)
3464 /// Parse a local variable declaration
3465 fn parse_local(&mut self) -> P<Local> {
3466 let lo = self.span.lo;
3467 let pat = self.parse_pat();
3470 id: ast::DUMMY_NODE_ID,
3472 span: mk_sp(lo, lo),
3474 if self.eat(&token::COLON) {
3475 ty = self.parse_ty(true);
3477 let init = self.parse_initializer();
3482 id: ast::DUMMY_NODE_ID,
3483 span: mk_sp(lo, self.last_span.hi),
3488 /// Parse a "let" stmt
3489 fn parse_let(&mut self) -> P<Decl> {
3490 let lo = self.span.lo;
3491 let local = self.parse_local();
3492 P(spanned(lo, self.last_span.hi, DeclLocal(local)))
3495 /// Parse a structure field
3496 fn parse_name_and_ty(&mut self, pr: Visibility,
3497 attrs: Vec<Attribute> ) -> StructField {
3498 let lo = self.span.lo;
3499 if !is_plain_ident(&self.token) {
3500 self.fatal("expected ident");
3502 let name = self.parse_ident();
3503 self.expect(&token::COLON);
3504 let ty = self.parse_ty(true);
3505 spanned(lo, self.last_span.hi, ast::StructField_ {
3506 kind: NamedField(name, pr),
3507 id: ast::DUMMY_NODE_ID,
3513 /// Get an expected item after attributes error message.
3514 fn expected_item_err(attrs: &[Attribute]) -> &'static str {
3515 match attrs.last() {
3516 Some(&Attribute { node: ast::Attribute_ { is_sugared_doc: true, .. }, .. }) => {
3517 "expected item after doc comment"
3519 _ => "expected item after attributes",
3523 /// Parse a statement. may include decl.
3524 /// Precondition: any attributes are parsed already
3525 pub fn parse_stmt(&mut self, item_attrs: Vec<Attribute>) -> P<Stmt> {
3526 maybe_whole!(self, NtStmt);
3528 fn check_expected_item(p: &mut Parser, attrs: &[Attribute]) {
3529 // If we have attributes then we should have an item
3530 if !attrs.is_empty() {
3531 let last_span = p.last_span;
3532 p.span_err(last_span, Parser::expected_item_err(attrs));
3536 let lo = self.span.lo;
3537 if self.is_keyword(keywords::Let) {
3538 check_expected_item(self, item_attrs.as_slice());
3539 self.expect_keyword(keywords::Let);
3540 let decl = self.parse_let();
3541 P(spanned(lo, decl.span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID)))
3542 } else if is_ident(&self.token)
3543 && !token::is_any_keyword(&self.token)
3544 && self.look_ahead(1, |t| *t == token::NOT) {
3545 // it's a macro invocation:
3547 check_expected_item(self, item_attrs.as_slice());
3549 // Potential trouble: if we allow macros with paths instead of
3550 // idents, we'd need to look ahead past the whole path here...
3551 let pth = self.parse_path(NoTypesAllowed).path;
3554 let id = if token::close_delimiter_for(&self.token).is_some() {
3555 token::special_idents::invalid // no special identifier
3560 // check that we're pointing at delimiters (need to check
3561 // again after the `if`, because of `parse_ident`
3562 // consuming more tokens).
3563 let (bra, ket) = match token::close_delimiter_for(&self.token) {
3564 Some(ket) => (self.token.clone(), ket),
3566 // we only expect an ident if we didn't parse one
3568 let ident_str = if id.name == token::special_idents::invalid.name {
3573 let tok_str = self.this_token_to_string();
3574 self.fatal(format!("expected {}`(` or `{{`, found `{}`",
3576 tok_str).as_slice())
3580 let tts = self.parse_unspanned_seq(
3584 |p| p.parse_token_tree()
3586 let hi = self.span.hi;
3588 if id.name == token::special_idents::invalid.name {
3589 P(spanned(lo, hi, StmtMac(
3590 spanned(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT)), false)))
3592 // if it has a special ident, it's definitely an item
3593 P(spanned(lo, hi, StmtDecl(
3594 P(spanned(lo, hi, DeclItem(
3596 lo, hi, id /*id is good here*/,
3597 ItemMac(spanned(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT))),
3598 Inherited, Vec::new(/*no attrs*/))))),
3599 ast::DUMMY_NODE_ID)))
3603 let found_attrs = !item_attrs.is_empty();
3604 let item_err = Parser::expected_item_err(item_attrs.as_slice());
3605 match self.parse_item_or_view_item(item_attrs, false) {
3608 let decl = P(spanned(lo, hi, DeclItem(i)));
3609 P(spanned(lo, hi, StmtDecl(decl, ast::DUMMY_NODE_ID)))
3611 IoviViewItem(vi) => {
3612 self.span_fatal(vi.span,
3613 "view items must be declared at the top of the block");
3615 IoviForeignItem(_) => {
3616 self.fatal("foreign items are not allowed here");
3620 let last_span = self.last_span;
3621 self.span_err(last_span, item_err);
3624 // Remainder are line-expr stmts.
3625 let e = self.parse_expr_res(RESTRICTION_STMT_EXPR);
3626 P(spanned(lo, e.span.hi, StmtExpr(e, ast::DUMMY_NODE_ID)))
3632 /// Is this expression a successfully-parsed statement?
3633 fn expr_is_complete(&mut self, e: &Expr) -> bool {
3634 self.restrictions.contains(RESTRICTION_STMT_EXPR) &&
3635 !classify::expr_requires_semi_to_be_stmt(e)
3638 /// Parse a block. No inner attrs are allowed.
3639 pub fn parse_block(&mut self) -> P<Block> {
3640 maybe_whole!(no_clone self, NtBlock);
3642 let lo = self.span.lo;
3643 self.expect(&token::LBRACE);
3645 return self.parse_block_tail_(lo, DefaultBlock, Vec::new());
3648 /// Parse a block. Inner attrs are allowed.
3649 fn parse_inner_attrs_and_block(&mut self)
3650 -> (Vec<Attribute> , P<Block>) {
3652 maybe_whole!(pair_empty self, NtBlock);
3654 let lo = self.span.lo;
3655 self.expect(&token::LBRACE);
3656 let (inner, next) = self.parse_inner_attrs_and_next();
3658 (inner, self.parse_block_tail_(lo, DefaultBlock, next))
3661 /// Precondition: already parsed the '{' or '#{'
3662 /// I guess that also means "already parsed the 'impure'" if
3663 /// necessary, and this should take a qualifier.
3664 /// Some blocks start with "#{"...
3665 fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> P<Block> {
3666 self.parse_block_tail_(lo, s, Vec::new())
3669 /// Parse the rest of a block expression or function body
3670 fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
3671 first_item_attrs: Vec<Attribute> ) -> P<Block> {
3672 let mut stmts = Vec::new();
3673 let mut expr = None;
3675 // wouldn't it be more uniform to parse view items only, here?
3676 let ParsedItemsAndViewItems {
3681 } = self.parse_items_and_view_items(first_item_attrs,
3684 for item in items.into_iter() {
3685 let span = item.span;
3686 let decl = P(spanned(span.lo, span.hi, DeclItem(item)));
3687 stmts.push(P(spanned(span.lo, span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID))));
3690 let mut attributes_box = attrs_remaining;
3692 while self.token != token::RBRACE {
3693 // parsing items even when they're not allowed lets us give
3694 // better error messages and recover more gracefully.
3695 attributes_box.push_all(self.parse_outer_attributes().as_slice());
3698 if !attributes_box.is_empty() {
3699 let last_span = self.last_span;
3700 self.span_err(last_span,
3701 Parser::expected_item_err(attributes_box.as_slice()));
3702 attributes_box = Vec::new();
3704 self.bump(); // empty
3707 // fall through and out.
3710 let stmt = self.parse_stmt(attributes_box);
3711 attributes_box = Vec::new();
3712 stmt.and_then(|Spanned {node, span}| match node {
3713 StmtExpr(e, stmt_id) => {
3714 // expression without semicolon
3715 if classify::expr_requires_semi_to_be_stmt(&*e) {
3716 // Just check for errors and recover; do not eat semicolon yet.
3717 self.commit_stmt(&[], &[token::SEMI, token::RBRACE]);
3723 let span_with_semi = Span {
3725 hi: self.last_span.hi,
3726 expn_id: span.expn_id,
3728 stmts.push(P(Spanned {
3729 node: StmtSemi(e, stmt_id),
3730 span: span_with_semi,
3737 stmts.push(P(Spanned {
3738 node: StmtExpr(e, stmt_id),
3744 StmtMac(m, semi) => {
3745 // statement macro; might be an expr
3748 stmts.push(P(Spanned {
3749 node: StmtMac(m, true),
3755 // if a block ends in `m!(arg)` without
3756 // a `;`, it must be an expr
3758 self.mk_mac_expr(span.lo,
3763 stmts.push(P(Spanned {
3764 node: StmtMac(m, semi),
3770 _ => { // all other kinds of statements:
3771 if classify::stmt_ends_with_semi(&node) {
3772 self.commit_stmt_expecting(token::SEMI);
3775 stmts.push(P(Spanned {
3785 if !attributes_box.is_empty() {
3786 let last_span = self.last_span;
3787 self.span_err(last_span,
3788 Parser::expected_item_err(attributes_box.as_slice()));
3791 let hi = self.span.hi;
3794 view_items: view_items,
3797 id: ast::DUMMY_NODE_ID,
3799 span: mk_sp(lo, hi),
3803 // Parses a sequence of bounds if a `:` is found,
3804 // otherwise returns empty list.
3805 fn parse_colon_then_ty_param_bounds(&mut self)
3806 -> OwnedSlice<TyParamBound>
3808 if !self.eat(&token::COLON) {
3811 self.parse_ty_param_bounds()
3815 // matches bounds = ( boundseq )?
3816 // where boundseq = ( bound + boundseq ) | bound
3817 // and bound = 'region | ty
3818 // NB: The None/Some distinction is important for issue #7264.
3819 fn parse_ty_param_bounds(&mut self)
3820 -> OwnedSlice<TyParamBound>
3822 let mut result = vec!();
3824 let lifetime_defs = if self.eat(&token::LT) {
3825 let lifetime_defs = self.parse_lifetime_defs();
3832 token::LIFETIME(lifetime) => {
3833 if lifetime_defs.len() > 0 {
3834 let span = self.last_span;
3835 self.span_err(span, "lifetime declarations are not \
3839 result.push(RegionTyParamBound(ast::Lifetime {
3840 id: ast::DUMMY_NODE_ID,
3846 token::MOD_SEP | token::IDENT(..) => {
3848 self.parse_path(LifetimeAndTypesWithoutColons).path;
3849 if self.token == token::LPAREN {
3851 let inputs = self.parse_seq_to_end(
3853 seq_sep_trailing_allowed(token::COMMA),
3854 |p| p.parse_arg_general(false));
3855 let (return_style, output) = self.parse_ret_ty();
3856 result.push(UnboxedFnTyParamBound(P(UnboxedFnBound {
3864 lifetimes: lifetime_defs,
3865 ref_id: ast::DUMMY_NODE_ID,
3868 result.push(TraitTyParamBound(ast::TraitRef {
3870 ref_id: ast::DUMMY_NODE_ID,
3871 lifetimes: lifetime_defs,
3878 if !self.eat(&token::BINOP(token::PLUS)) {
3883 return OwnedSlice::from_vec(result);
3886 fn trait_ref_from_ident(ident: Ident, span: Span) -> ast::TraitRef {
3887 let segment = ast::PathSegment {
3889 lifetimes: Vec::new(),
3890 types: OwnedSlice::empty(),
3892 let path = ast::Path {
3895 segments: vec![segment],
3899 ref_id: ast::DUMMY_NODE_ID,
3900 lifetimes: Vec::new(),
3904 /// Matches typaram = (unbound`?`)? IDENT optbounds ( EQ ty )?
3905 fn parse_ty_param(&mut self) -> TyParam {
3906 // This is a bit hacky. Currently we are only interested in a single
3907 // unbound, and it may only be `Sized`. To avoid backtracking and other
3908 // complications, we parse an ident, then check for `?`. If we find it,
3909 // we use the ident as the unbound, otherwise, we use it as the name of
3911 let mut span = self.span;
3912 let mut ident = self.parse_ident();
3913 let mut unbound = None;
3914 if self.eat(&token::QUESTION) {
3915 let tref = Parser::trait_ref_from_ident(ident, span);
3916 unbound = Some(TraitTyParamBound(tref));
3918 ident = self.parse_ident();
3921 let bounds = self.parse_colon_then_ty_param_bounds();
3923 let default = if self.token == token::EQ {
3925 Some(self.parse_ty(true))
3931 id: ast::DUMMY_NODE_ID,
3939 /// Parse a set of optional generic type parameter declarations. Where
3940 /// clauses are not parsed here, and must be added later via
3941 /// `parse_where_clause()`.
3943 /// matches generics = ( ) | ( < > ) | ( < typaramseq ( , )? > ) | ( < lifetimes ( , )? > )
3944 /// | ( < lifetimes , typaramseq ( , )? > )
3945 /// where typaramseq = ( typaram ) | ( typaram , typaramseq )
3946 pub fn parse_generics(&mut self) -> ast::Generics {
3947 if self.eat(&token::LT) {
3948 let lifetime_defs = self.parse_lifetime_defs();
3949 let mut seen_default = false;
3950 let ty_params = self.parse_seq_to_gt(Some(token::COMMA), |p| {
3951 p.forbid_lifetime();
3952 let ty_param = p.parse_ty_param();
3953 if ty_param.default.is_some() {
3954 seen_default = true;
3955 } else if seen_default {
3956 let last_span = p.last_span;
3957 p.span_err(last_span,
3958 "type parameters with a default must be trailing");
3963 lifetimes: lifetime_defs,
3964 ty_params: ty_params,
3965 where_clause: WhereClause {
3966 id: ast::DUMMY_NODE_ID,
3967 predicates: Vec::new(),
3971 ast_util::empty_generics()
3975 fn parse_generic_values_after_lt(&mut self) -> (Vec<ast::Lifetime>, Vec<P<Ty>> ) {
3976 let lifetimes = self.parse_lifetimes(token::COMMA);
3977 let result = self.parse_seq_to_gt(
3980 p.forbid_lifetime();
3984 (lifetimes, result.into_vec())
3987 fn forbid_lifetime(&mut self) {
3988 if Parser::token_is_lifetime(&self.token) {
3989 let span = self.span;
3990 self.span_fatal(span, "lifetime parameters must be declared \
3991 prior to type parameters");
3995 /// Parses an optional `where` clause and places it in `generics`.
3996 fn parse_where_clause(&mut self, generics: &mut ast::Generics) {
3997 if !self.eat_keyword(keywords::Where) {
4001 let mut parsed_something = false;
4003 let lo = self.span.lo;
4004 let ident = match self.token {
4005 token::IDENT(..) => self.parse_ident(),
4008 self.expect(&token::COLON);
4010 let bounds = self.parse_ty_param_bounds();
4011 let hi = self.span.hi;
4012 let span = mk_sp(lo, hi);
4014 if bounds.len() == 0 {
4016 "each predicate in a `where` clause must have \
4017 at least one bound in it");
4020 generics.where_clause.predicates.push(ast::WherePredicate {
4021 id: ast::DUMMY_NODE_ID,
4026 parsed_something = true;
4028 if !self.eat(&token::COMMA) {
4033 if !parsed_something {
4034 let last_span = self.last_span;
4035 self.span_err(last_span,
4036 "a `where` clause must have at least one predicate \
4041 fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool)
4042 -> (Vec<Arg> , bool) {
4044 let mut args: Vec<Option<Arg>> =
4045 self.parse_unspanned_seq(
4048 seq_sep_trailing_allowed(token::COMMA),
4050 if p.token == token::DOTDOTDOT {
4053 if p.token != token::RPAREN {
4056 "`...` must be last in argument list for variadic function");
4061 "only foreign functions are allowed to be variadic");
4065 Some(p.parse_arg_general(named_args))
4070 let variadic = match args.pop() {
4073 // Need to put back that last arg
4080 if variadic && args.is_empty() {
4082 "variadic function must be declared with at least one named argument");
4085 let args = args.into_iter().map(|x| x.unwrap()).collect();
4090 /// Parse the argument list and result type of a function declaration
4091 pub fn parse_fn_decl(&mut self, allow_variadic: bool) -> P<FnDecl> {
4093 let (args, variadic) = self.parse_fn_args(true, allow_variadic);
4094 let (ret_style, ret_ty) = self.parse_ret_ty();
4104 fn is_self_ident(&mut self) -> bool {
4106 token::IDENT(id, false) => id.name == special_idents::self_.name,
4111 fn expect_self_ident(&mut self) -> ast::Ident {
4113 token::IDENT(id, false) if id.name == special_idents::self_.name => {
4118 let token_str = self.this_token_to_string();
4119 self.fatal(format!("expected `self`, found `{}`",
4120 token_str).as_slice())
4125 /// Parse the argument list and result type of a function
4126 /// that may have a self type.
4127 fn parse_fn_decl_with_self(&mut self, parse_arg_fn: |&mut Parser| -> Arg)
4128 -> (ExplicitSelf, P<FnDecl>) {
4129 fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
4130 -> ast::ExplicitSelf_ {
4131 // The following things are possible to see here:
4136 // fn(&'lt mut self)
4138 // We already know that the current token is `&`.
4140 if this.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) {
4142 SelfRegion(None, MutImmutable, this.expect_self_ident())
4143 } else if this.look_ahead(1, |t| Parser::token_is_mutability(t)) &&
4145 |t| token::is_keyword(keywords::Self,
4148 let mutability = this.parse_mutability();
4149 SelfRegion(None, mutability, this.expect_self_ident())
4150 } else if this.look_ahead(1, |t| Parser::token_is_lifetime(t)) &&
4152 |t| token::is_keyword(keywords::Self,
4155 let lifetime = this.parse_lifetime();
4156 SelfRegion(Some(lifetime), MutImmutable, this.expect_self_ident())
4157 } else if this.look_ahead(1, |t| Parser::token_is_lifetime(t)) &&
4158 this.look_ahead(2, |t| {
4159 Parser::token_is_mutability(t)
4161 this.look_ahead(3, |t| token::is_keyword(keywords::Self,
4164 let lifetime = this.parse_lifetime();
4165 let mutability = this.parse_mutability();
4166 SelfRegion(Some(lifetime), mutability, this.expect_self_ident())
4172 self.expect(&token::LPAREN);
4174 // A bit of complexity and lookahead is needed here in order to be
4175 // backwards compatible.
4176 let lo = self.span.lo;
4177 let mut self_ident_lo = self.span.lo;
4178 let mut self_ident_hi = self.span.hi;
4180 let mut mutbl_self = MutImmutable;
4181 let explicit_self = match self.token {
4182 token::BINOP(token::AND) => {
4183 let eself = maybe_parse_borrowed_explicit_self(self);
4184 self_ident_lo = self.last_span.lo;
4185 self_ident_hi = self.last_span.hi;
4189 // We need to make sure it isn't a type
4190 if self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) {
4192 drop(self.expect_self_ident());
4193 let last_span = self.last_span;
4194 self.obsolete(last_span, ObsoleteOwnedSelf)
4198 token::BINOP(token::STAR) => {
4199 // Possibly "*self" or "*mut self" -- not supported. Try to avoid
4200 // emitting cryptic "unexpected token" errors.
4202 let _mutability = if Parser::token_is_mutability(&self.token) {
4203 self.parse_mutability()
4207 if self.is_self_ident() {
4208 let span = self.span;
4209 self.span_err(span, "cannot pass self by unsafe pointer");
4212 // error case, making bogus self ident:
4213 SelfValue(special_idents::self_)
4215 token::IDENT(..) => {
4216 if self.is_self_ident() {
4217 let self_ident = self.expect_self_ident();
4219 // Determine whether this is the fully explicit form, `self:
4221 if self.eat(&token::COLON) {
4222 SelfExplicit(self.parse_ty(false), self_ident)
4224 SelfValue(self_ident)
4226 } else if Parser::token_is_mutability(&self.token) &&
4227 self.look_ahead(1, |t| {
4228 token::is_keyword(keywords::Self, t)
4230 mutbl_self = self.parse_mutability();
4231 let self_ident = self.expect_self_ident();
4233 // Determine whether this is the fully explicit form,
4235 if self.eat(&token::COLON) {
4236 SelfExplicit(self.parse_ty(false), self_ident)
4238 SelfValue(self_ident)
4240 } else if Parser::token_is_mutability(&self.token) &&
4241 self.look_ahead(1, |t| *t == token::TILDE) &&
4242 self.look_ahead(2, |t| {
4243 token::is_keyword(keywords::Self, t)
4245 mutbl_self = self.parse_mutability();
4247 drop(self.expect_self_ident());
4248 let last_span = self.last_span;
4249 self.obsolete(last_span, ObsoleteOwnedSelf);
4258 let explicit_self_sp = mk_sp(self_ident_lo, self_ident_hi);
4260 // shared fall-through for the three cases below. borrowing prevents simply
4261 // writing this as a closure
4262 macro_rules! parse_remaining_arguments {
4265 // If we parsed a self type, expect a comma before the argument list.
4269 let sep = seq_sep_trailing_allowed(token::COMMA);
4270 let mut fn_inputs = self.parse_seq_to_before_end(
4275 fn_inputs.insert(0, Arg::new_self(explicit_self_sp, mutbl_self, $self_id));
4279 vec!(Arg::new_self(explicit_self_sp, mutbl_self, $self_id))
4282 let token_str = self.this_token_to_string();
4283 self.fatal(format!("expected `,` or `)`, found `{}`",
4284 token_str).as_slice())
4290 let fn_inputs = match explicit_self {
4292 let sep = seq_sep_trailing_allowed(token::COMMA);
4293 self.parse_seq_to_before_end(&token::RPAREN, sep, parse_arg_fn)
4295 SelfValue(id) => parse_remaining_arguments!(id),
4296 SelfRegion(_,_,id) => parse_remaining_arguments!(id),
4297 SelfExplicit(_,id) => parse_remaining_arguments!(id),
4301 self.expect(&token::RPAREN);
4303 let hi = self.span.hi;
4305 let (ret_style, ret_ty) = self.parse_ret_ty();
4307 let fn_decl = P(FnDecl {
4314 (spanned(lo, hi, explicit_self), fn_decl)
4317 // parse the |arg, arg| header on a lambda
4318 fn parse_fn_block_decl(&mut self)
4319 -> (P<FnDecl>, Option<UnboxedClosureKind>) {
4320 let (optional_unboxed_closure_kind, inputs_captures) = {
4321 if self.eat(&token::OROR) {
4324 self.expect(&token::BINOP(token::OR));
4325 let optional_unboxed_closure_kind =
4326 self.parse_optional_unboxed_closure_kind();
4327 let args = self.parse_seq_to_before_end(
4328 &token::BINOP(token::OR),
4329 seq_sep_trailing_allowed(token::COMMA),
4330 |p| p.parse_fn_block_arg()
4333 (optional_unboxed_closure_kind, args)
4336 let (style, output) = if self.token == token::RARROW {
4340 id: ast::DUMMY_NODE_ID,
4347 inputs: inputs_captures,
4351 }), optional_unboxed_closure_kind)
4354 /// Parses the `(arg, arg) -> return_type` header on a procedure.
4355 fn parse_proc_decl(&mut self) -> P<FnDecl> {
4357 self.parse_unspanned_seq(&token::LPAREN,
4359 seq_sep_trailing_allowed(token::COMMA),
4360 |p| p.parse_fn_block_arg());
4362 let (style, output) = if self.token == token::RARROW {
4366 id: ast::DUMMY_NODE_ID,
4380 /// Parse the name and optional generic types of a function header.
4381 fn parse_fn_header(&mut self) -> (Ident, ast::Generics) {
4382 let id = self.parse_ident();
4383 let generics = self.parse_generics();
4387 fn mk_item(&mut self, lo: BytePos, hi: BytePos, ident: Ident,
4388 node: Item_, vis: Visibility,
4389 attrs: Vec<Attribute>) -> P<Item> {
4393 id: ast::DUMMY_NODE_ID,
4400 /// Parse an item-position function declaration.
4401 fn parse_item_fn(&mut self, fn_style: FnStyle, abi: abi::Abi) -> ItemInfo {
4402 let (ident, mut generics) = self.parse_fn_header();
4403 let decl = self.parse_fn_decl(false);
4404 self.parse_where_clause(&mut generics);
4405 let (inner_attrs, body) = self.parse_inner_attrs_and_block();
4406 (ident, ItemFn(decl, fn_style, abi, generics, body), Some(inner_attrs))
4409 /// Parse a method in a trait impl
4410 pub fn parse_method_with_outer_attributes(&mut self) -> P<Method> {
4411 let attrs = self.parse_outer_attributes();
4412 let visa = self.parse_visibility();
4413 self.parse_method(attrs, visa)
4416 /// Parse a method in a trait impl, starting with `attrs` attributes.
4417 pub fn parse_method(&mut self,
4418 attrs: Vec<Attribute>,
4421 let lo = self.span.lo;
4423 // code copied from parse_macro_use_or_failure... abstraction!
4424 let (method_, hi, new_attrs) = {
4425 if !token::is_any_keyword(&self.token)
4426 && self.look_ahead(1, |t| *t == token::NOT)
4427 && (self.look_ahead(2, |t| *t == token::LPAREN)
4428 || self.look_ahead(2, |t| *t == token::LBRACE)) {
4430 let pth = self.parse_path(NoTypesAllowed).path;
4431 self.expect(&token::NOT);
4433 // eat a matched-delimiter token tree:
4434 let tts = match token::close_delimiter_for(&self.token) {
4437 self.parse_seq_to_end(&ket,
4439 |p| p.parse_token_tree())
4441 None => self.fatal("expected open delimiter")
4443 let m_ = ast::MacInvocTT(pth, tts, EMPTY_CTXT);
4444 let m: ast::Mac = codemap::Spanned { node: m_,
4445 span: mk_sp(self.span.lo,
4447 (ast::MethMac(m), self.span.hi, attrs)
4449 let abi = if self.eat_keyword(keywords::Extern) {
4450 self.parse_opt_abi().unwrap_or(abi::C)
4451 } else if attr::contains_name(attrs.as_slice(),
4452 "rust_call_abi_hack") {
4453 // FIXME(stage0, pcwalton): Remove this awful hack after a
4454 // snapshot, and change to `extern "rust-call" fn`.
4459 let fn_style = self.parse_fn_style();
4460 let ident = self.parse_ident();
4461 let mut generics = self.parse_generics();
4462 let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| {
4465 self.parse_where_clause(&mut generics);
4466 let (inner_attrs, body) = self.parse_inner_attrs_and_block();
4467 let body_span = body.span;
4468 let mut new_attrs = attrs;
4469 new_attrs.push_all(inner_attrs.as_slice());
4470 (ast::MethDecl(ident,
4478 body_span.hi, new_attrs)
4483 id: ast::DUMMY_NODE_ID,
4484 span: mk_sp(lo, hi),
4489 /// Parse trait Foo { ... }
4490 fn parse_item_trait(&mut self) -> ItemInfo {
4491 let ident = self.parse_ident();
4492 let mut tps = self.parse_generics();
4493 let sized = self.parse_for_sized();
4495 // Parse supertrait bounds.
4496 let bounds = self.parse_colon_then_ty_param_bounds();
4498 self.parse_where_clause(&mut tps);
4500 let meths = self.parse_trait_items();
4501 (ident, ItemTrait(tps, sized, bounds, meths), None)
4504 fn parse_impl_items(&mut self) -> (Vec<ImplItem>, Vec<Attribute>) {
4505 let mut impl_items = Vec::new();
4506 self.expect(&token::LBRACE);
4507 let (inner_attrs, mut method_attrs) =
4508 self.parse_inner_attrs_and_next();
4509 while !self.eat(&token::RBRACE) {
4510 method_attrs.extend(self.parse_outer_attributes().into_iter());
4511 let vis = self.parse_visibility();
4512 if self.eat_keyword(keywords::Type) {
4513 impl_items.push(TypeImplItem(P(self.parse_typedef(
4517 impl_items.push(MethodImplItem(self.parse_method(
4521 method_attrs = self.parse_outer_attributes();
4523 (impl_items, inner_attrs)
4526 /// Parses two variants (with the region/type params always optional):
4527 /// impl<T> Foo { ... }
4528 /// impl<T> ToString for ~[T] { ... }
4529 fn parse_item_impl(&mut self) -> ItemInfo {
4530 // First, parse type parameters if necessary.
4531 let mut generics = self.parse_generics();
4533 // Special case: if the next identifier that follows is '(', don't
4534 // allow this to be parsed as a trait.
4535 let could_be_trait = self.token != token::LPAREN;
4538 let mut ty = self.parse_ty(true);
4540 // Parse traits, if necessary.
4541 let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) {
4542 // New-style trait. Reinterpret the type as a trait.
4543 let opt_trait_ref = match ty.node {
4544 TyPath(ref path, None, node_id) => {
4546 path: (*path).clone(),
4548 lifetimes: Vec::new(),
4551 TyPath(_, Some(_), _) => {
4552 self.span_err(ty.span,
4553 "bounded traits are only valid in type position");
4557 self.span_err(ty.span, "not a trait");
4562 ty = self.parse_ty(true);
4568 self.parse_where_clause(&mut generics);
4569 let (impl_items, attrs) = self.parse_impl_items();
4571 let ident = ast_util::impl_pretty_name(&opt_trait, &*ty);
4574 ItemImpl(generics, opt_trait, ty, impl_items),
4578 /// Parse struct Foo { ... }
4579 fn parse_item_struct(&mut self) -> ItemInfo {
4580 let class_name = self.parse_ident();
4581 let mut generics = self.parse_generics();
4583 if self.eat(&token::COLON) {
4584 let ty = self.parse_ty(true);
4585 self.span_err(ty.span, "`virtual` structs have been removed from the language");
4588 self.parse_where_clause(&mut generics);
4590 let mut fields: Vec<StructField>;
4593 if self.eat(&token::LBRACE) {
4594 // It's a record-like struct.
4595 is_tuple_like = false;
4596 fields = Vec::new();
4597 while self.token != token::RBRACE {
4598 fields.push(self.parse_struct_decl_field());
4600 if fields.len() == 0 {
4601 self.fatal(format!("unit-like struct definition should be \
4602 written as `struct {};`",
4603 token::get_ident(class_name)).as_slice());
4606 } else if self.token == token::LPAREN {
4607 // It's a tuple-like struct.
4608 is_tuple_like = true;
4609 fields = self.parse_unspanned_seq(
4612 seq_sep_trailing_allowed(token::COMMA),
4614 let attrs = p.parse_outer_attributes();
4616 let struct_field_ = ast::StructField_ {
4617 kind: UnnamedField(p.parse_visibility()),
4618 id: ast::DUMMY_NODE_ID,
4619 ty: p.parse_ty(true),
4622 spanned(lo, p.span.hi, struct_field_)
4624 if fields.len() == 0 {
4625 self.fatal(format!("unit-like struct definition should be \
4626 written as `struct {};`",
4627 token::get_ident(class_name)).as_slice());
4629 self.expect(&token::SEMI);
4630 } else if self.eat(&token::SEMI) {
4631 // It's a unit-like struct.
4632 is_tuple_like = true;
4633 fields = Vec::new();
4635 let token_str = self.this_token_to_string();
4636 self.fatal(format!("expected `{}`, `(`, or `;` after struct \
4637 name, found `{}`", "{",
4638 token_str).as_slice())
4641 let _ = ast::DUMMY_NODE_ID; // FIXME: Workaround for crazy bug.
4642 let new_id = ast::DUMMY_NODE_ID;
4644 ItemStruct(P(ast::StructDef {
4646 ctor_id: if is_tuple_like { Some(new_id) } else { None },
4651 /// Parse a structure field declaration
4652 pub fn parse_single_struct_field(&mut self,
4654 attrs: Vec<Attribute> )
4656 let a_var = self.parse_name_and_ty(vis, attrs);
4663 let span = self.span;
4664 let token_str = self.this_token_to_string();
4665 self.span_fatal(span,
4666 format!("expected `,`, or `}}`, found `{}`",
4667 token_str).as_slice())
4673 /// Parse an element of a struct definition
4674 fn parse_struct_decl_field(&mut self) -> StructField {
4676 let attrs = self.parse_outer_attributes();
4678 if self.eat_keyword(keywords::Pub) {
4679 return self.parse_single_struct_field(Public, attrs);
4682 return self.parse_single_struct_field(Inherited, attrs);
4685 /// Parse visibility: PUB, PRIV, or nothing
4686 fn parse_visibility(&mut self) -> Visibility {
4687 if self.eat_keyword(keywords::Pub) { Public }
4691 fn parse_for_sized(&mut self) -> Option<ast::TyParamBound> {
4692 if self.eat_keyword(keywords::For) {
4693 let span = self.span;
4694 let ident = self.parse_ident();
4695 if !self.eat(&token::QUESTION) {
4697 "expected 'Sized?' after `for` in trait item");
4700 let tref = Parser::trait_ref_from_ident(ident, span);
4701 Some(TraitTyParamBound(tref))
4707 /// Given a termination token and a vector of already-parsed
4708 /// attributes (of length 0 or 1), parse all of the items in a module
4709 fn parse_mod_items(&mut self,
4711 first_item_attrs: Vec<Attribute>,
4714 // parse all of the items up to closing or an attribute.
4715 // view items are legal here.
4716 let ParsedItemsAndViewItems {
4719 items: starting_items,
4721 } = self.parse_items_and_view_items(first_item_attrs, true, true);
4722 let mut items: Vec<P<Item>> = starting_items;
4723 let attrs_remaining_len = attrs_remaining.len();
4725 // don't think this other loop is even necessary....
4727 let mut first = true;
4728 while self.token != term {
4729 let mut attrs = self.parse_outer_attributes();
4731 let mut tmp = attrs_remaining.clone();
4732 tmp.push_all(attrs.as_slice());
4736 debug!("parse_mod_items: parse_item_or_view_item(attrs={})",
4738 match self.parse_item_or_view_item(attrs,
4739 true /* macros allowed */) {
4740 IoviItem(item) => items.push(item),
4741 IoviViewItem(view_item) => {
4742 self.span_fatal(view_item.span,
4743 "view items must be declared at the top of \
4747 let token_str = self.this_token_to_string();
4748 self.fatal(format!("expected item, found `{}`",
4749 token_str).as_slice())
4754 if first && attrs_remaining_len > 0u {
4755 // We parsed attributes for the first item but didn't find it
4756 let last_span = self.last_span;
4757 self.span_err(last_span,
4758 Parser::expected_item_err(attrs_remaining.as_slice()));
4762 inner: mk_sp(inner_lo, self.span.lo),
4763 view_items: view_items,
4768 fn parse_item_const(&mut self, m: Option<Mutability>) -> ItemInfo {
4769 let id = self.parse_ident();
4770 self.expect(&token::COLON);
4771 let ty = self.parse_ty(true);
4772 self.expect(&token::EQ);
4773 let e = self.parse_expr();
4774 self.commit_expr_expecting(&*e, token::SEMI);
4775 let item = match m {
4776 Some(m) => ItemStatic(ty, m, e),
4777 None => ItemConst(ty, e),
4782 /// Parse a `mod <foo> { ... }` or `mod <foo>;` item
4783 fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> ItemInfo {
4784 let id_span = self.span;
4785 let id = self.parse_ident();
4786 if self.token == token::SEMI {
4788 // This mod is in an external file. Let's go get it!
4789 let (m, attrs) = self.eval_src_mod(id, outer_attrs, id_span);
4790 (id, m, Some(attrs))
4792 self.push_mod_path(id, outer_attrs);
4793 self.expect(&token::LBRACE);
4794 let mod_inner_lo = self.span.lo;
4795 let old_owns_directory = self.owns_directory;
4796 self.owns_directory = true;
4797 let (inner, next) = self.parse_inner_attrs_and_next();
4798 let m = self.parse_mod_items(token::RBRACE, next, mod_inner_lo);
4799 self.expect(&token::RBRACE);
4800 self.owns_directory = old_owns_directory;
4801 self.pop_mod_path();
4802 (id, ItemMod(m), Some(inner))
4806 fn push_mod_path(&mut self, id: Ident, attrs: &[Attribute]) {
4807 let default_path = self.id_to_interned_str(id);
4808 let file_path = match ::attr::first_attr_value_str_by_name(attrs,
4811 None => default_path,
4813 self.mod_path_stack.push(file_path)
4816 fn pop_mod_path(&mut self) {
4817 self.mod_path_stack.pop().unwrap();
4820 /// Read a module from a source file.
4821 fn eval_src_mod(&mut self,
4823 outer_attrs: &[ast::Attribute],
4825 -> (ast::Item_, Vec<ast::Attribute> ) {
4826 let mut prefix = Path::new(self.sess.span_diagnostic.cm.span_to_filename(self.span));
4828 let mod_path = Path::new(".").join_many(self.mod_path_stack.as_slice());
4829 let dir_path = prefix.join(&mod_path);
4830 let mod_string = token::get_ident(id);
4831 let (file_path, owns_directory) = match ::attr::first_attr_value_str_by_name(
4832 outer_attrs, "path") {
4833 Some(d) => (dir_path.join(d), true),
4835 let mod_name = mod_string.get().to_string();
4836 let default_path_str = format!("{}.rs", mod_name);
4837 let secondary_path_str = format!("{}/mod.rs", mod_name);
4838 let default_path = dir_path.join(default_path_str.as_slice());
4839 let secondary_path = dir_path.join(secondary_path_str.as_slice());
4840 let default_exists = default_path.exists();
4841 let secondary_exists = secondary_path.exists();
4843 if !self.owns_directory {
4844 self.span_err(id_sp,
4845 "cannot declare a new module at this location");
4846 let this_module = match self.mod_path_stack.last() {
4847 Some(name) => name.get().to_string(),
4848 None => self.root_module_name.as_ref().unwrap().clone(),
4850 self.span_note(id_sp,
4851 format!("maybe move this module `{0}` \
4852 to its own directory via \
4854 this_module).as_slice());
4855 if default_exists || secondary_exists {
4856 self.span_note(id_sp,
4857 format!("... or maybe `use` the module \
4858 `{}` instead of possibly \
4860 mod_name).as_slice());
4862 self.abort_if_errors();
4865 match (default_exists, secondary_exists) {
4866 (true, false) => (default_path, false),
4867 (false, true) => (secondary_path, true),
4869 self.span_fatal(id_sp,
4870 format!("file not found for module \
4872 mod_name).as_slice());
4877 format!("file for module `{}` found at both {} \
4881 secondary_path_str).as_slice());
4887 self.eval_src_mod_from_path(file_path, owns_directory,
4888 mod_string.get().to_string(), id_sp)
4891 fn eval_src_mod_from_path(&mut self,
4893 owns_directory: bool,
4895 id_sp: Span) -> (ast::Item_, Vec<ast::Attribute> ) {
4896 let mut included_mod_stack = self.sess.included_mod_stack.borrow_mut();
4897 match included_mod_stack.iter().position(|p| *p == path) {
4899 let mut err = String::from_str("circular modules: ");
4900 let len = included_mod_stack.len();
4901 for p in included_mod_stack.slice(i, len).iter() {
4902 err.push_str(p.display().as_maybe_owned().as_slice());
4903 err.push_str(" -> ");
4905 err.push_str(path.display().as_maybe_owned().as_slice());
4906 self.span_fatal(id_sp, err.as_slice());
4910 included_mod_stack.push(path.clone());
4911 drop(included_mod_stack);
4914 new_sub_parser_from_file(self.sess,
4920 let mod_inner_lo = p0.span.lo;
4921 let (mod_attrs, next) = p0.parse_inner_attrs_and_next();
4922 let first_item_outer_attrs = next;
4923 let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs, mod_inner_lo);
4924 self.sess.included_mod_stack.borrow_mut().pop();
4925 return (ast::ItemMod(m0), mod_attrs);
4928 /// Parse a function declaration from a foreign module
4929 fn parse_item_foreign_fn(&mut self, vis: ast::Visibility,
4930 attrs: Vec<Attribute>) -> P<ForeignItem> {
4931 let lo = self.span.lo;
4932 self.expect_keyword(keywords::Fn);
4934 let (ident, mut generics) = self.parse_fn_header();
4935 let decl = self.parse_fn_decl(true);
4936 self.parse_where_clause(&mut generics);
4937 let hi = self.span.hi;
4938 self.expect(&token::SEMI);
4939 P(ast::ForeignItem {
4942 node: ForeignItemFn(decl, generics),
4943 id: ast::DUMMY_NODE_ID,
4944 span: mk_sp(lo, hi),
4949 /// Parse a static item from a foreign module
4950 fn parse_item_foreign_static(&mut self, vis: ast::Visibility,
4951 attrs: Vec<Attribute>) -> P<ForeignItem> {
4952 let lo = self.span.lo;
4954 self.expect_keyword(keywords::Static);
4955 let mutbl = self.eat_keyword(keywords::Mut);
4957 let ident = self.parse_ident();
4958 self.expect(&token::COLON);
4959 let ty = self.parse_ty(true);
4960 let hi = self.span.hi;
4961 self.expect(&token::SEMI);
4965 node: ForeignItemStatic(ty, mutbl),
4966 id: ast::DUMMY_NODE_ID,
4967 span: mk_sp(lo, hi),
4972 /// Parse safe/unsafe and fn
4973 fn parse_fn_style(&mut self) -> FnStyle {
4974 if self.eat_keyword(keywords::Fn) { NormalFn }
4975 else if self.eat_keyword(keywords::Unsafe) {
4976 self.expect_keyword(keywords::Fn);
4979 else { self.unexpected(); }
4983 /// At this point, this is essentially a wrapper for
4984 /// parse_foreign_items.
4985 fn parse_foreign_mod_items(&mut self,
4987 first_item_attrs: Vec<Attribute> )
4989 let ParsedItemsAndViewItems {
4994 } = self.parse_foreign_items(first_item_attrs, true);
4995 if !attrs_remaining.is_empty() {
4996 let last_span = self.last_span;
4997 self.span_err(last_span,
4998 Parser::expected_item_err(attrs_remaining.as_slice()));
5000 assert!(self.token == token::RBRACE);
5003 view_items: view_items,
5004 items: foreign_items
5008 /// Parse extern crate links
5012 /// extern crate url;
5013 /// extern crate foo = "bar"; //deprecated
5014 /// extern crate "bar" as foo;
5015 fn parse_item_extern_crate(&mut self,
5017 visibility: Visibility,
5018 attrs: Vec<Attribute> )
5021 let span = self.span;
5022 let (maybe_path, ident) = match self.token {
5023 token::IDENT(..) => {
5024 let the_ident = self.parse_ident();
5025 let path = if self.eat(&token::EQ) {
5026 let path = self.parse_str();
5027 let span = self.span;
5028 self.obsolete(span, ObsoleteExternCrateRenaming);
5030 } else if self.eat_keyword(keywords::As) {
5031 // skip the ident if there is one
5032 if is_ident(&self.token) { self.bump(); }
5035 format!("expected `;`, found `as`; perhaps you meant \
5036 to enclose the crate name `{}` in a string?",
5037 the_ident.as_str()).as_slice());
5042 self.expect(&token::SEMI);
5045 token::LIT_STR(..) | token::LIT_STR_RAW(..) => {
5046 let path = self.parse_str();
5047 self.expect_keyword(keywords::As);
5048 let the_ident = self.parse_ident();
5049 self.expect(&token::SEMI);
5050 (Some(path), the_ident)
5053 let span = self.span;
5054 let token_str = self.this_token_to_string();
5055 self.span_fatal(span,
5056 format!("expected extern crate name but \
5058 token_str).as_slice());
5062 IoviViewItem(ast::ViewItem {
5063 node: ViewItemExternCrate(ident, maybe_path, ast::DUMMY_NODE_ID),
5066 span: mk_sp(lo, self.last_span.hi)
5070 /// Parse `extern` for foreign ABIs
5073 /// `extern` is expected to have been
5074 /// consumed before calling this method
5080 fn parse_item_foreign_mod(&mut self,
5082 opt_abi: Option<abi::Abi>,
5083 visibility: Visibility,
5084 attrs: Vec<Attribute> )
5087 self.expect(&token::LBRACE);
5089 let abi = opt_abi.unwrap_or(abi::C);
5091 let (inner, next) = self.parse_inner_attrs_and_next();
5092 let m = self.parse_foreign_mod_items(abi, next);
5093 self.expect(&token::RBRACE);
5095 let last_span = self.last_span;
5096 let item = self.mk_item(lo,
5098 special_idents::invalid,
5101 maybe_append(attrs, Some(inner)));
5102 return IoviItem(item);
5105 /// Parse type Foo = Bar;
5106 fn parse_item_type(&mut self) -> ItemInfo {
5107 let ident = self.parse_ident();
5108 let mut tps = self.parse_generics();
5109 self.parse_where_clause(&mut tps);
5110 self.expect(&token::EQ);
5111 let ty = self.parse_ty(true);
5112 self.expect(&token::SEMI);
5113 (ident, ItemTy(ty, tps), None)
5116 /// Parse a structure-like enum variant definition
5117 /// this should probably be renamed or refactored...
5118 fn parse_struct_def(&mut self) -> P<StructDef> {
5119 let mut fields: Vec<StructField> = Vec::new();
5120 while self.token != token::RBRACE {
5121 fields.push(self.parse_struct_decl_field());
5131 /// Parse the part of an "enum" decl following the '{'
5132 fn parse_enum_def(&mut self, _generics: &ast::Generics) -> EnumDef {
5133 let mut variants = Vec::new();
5134 let mut all_nullary = true;
5135 let mut any_disr = None;
5136 while self.token != token::RBRACE {
5137 let variant_attrs = self.parse_outer_attributes();
5138 let vlo = self.span.lo;
5140 let vis = self.parse_visibility();
5144 let mut args = Vec::new();
5145 let mut disr_expr = None;
5146 ident = self.parse_ident();
5147 if self.eat(&token::LBRACE) {
5148 // Parse a struct variant.
5149 all_nullary = false;
5150 kind = StructVariantKind(self.parse_struct_def());
5151 } else if self.token == token::LPAREN {
5152 all_nullary = false;
5153 let arg_tys = self.parse_enum_variant_seq(
5156 seq_sep_trailing_allowed(token::COMMA),
5157 |p| p.parse_ty(true)
5159 for ty in arg_tys.into_iter() {
5160 args.push(ast::VariantArg {
5162 id: ast::DUMMY_NODE_ID,
5165 kind = TupleVariantKind(args);
5166 } else if self.eat(&token::EQ) {
5167 disr_expr = Some(self.parse_expr());
5168 any_disr = disr_expr.as_ref().map(|expr| expr.span);
5169 kind = TupleVariantKind(args);
5171 kind = TupleVariantKind(Vec::new());
5174 let vr = ast::Variant_ {
5176 attrs: variant_attrs,
5178 id: ast::DUMMY_NODE_ID,
5179 disr_expr: disr_expr,
5182 variants.push(P(spanned(vlo, self.last_span.hi, vr)));
5184 if !self.eat(&token::COMMA) { break; }
5186 self.expect(&token::RBRACE);
5188 Some(disr_span) if !all_nullary =>
5189 self.span_err(disr_span,
5190 "discriminator values can only be used with a c-like enum"),
5194 ast::EnumDef { variants: variants }
5197 /// Parse an "enum" declaration
5198 fn parse_item_enum(&mut self) -> ItemInfo {
5199 let id = self.parse_ident();
5200 let mut generics = self.parse_generics();
5201 self.parse_where_clause(&mut generics);
5202 self.expect(&token::LBRACE);
5204 let enum_definition = self.parse_enum_def(&generics);
5205 (id, ItemEnum(enum_definition, generics), None)
5208 fn fn_expr_lookahead(tok: &token::Token) -> bool {
5210 token::LPAREN | token::AT | token::TILDE | token::BINOP(_) => true,
5215 /// Parses a string as an ABI spec on an extern type or module. Consumes
5216 /// the `extern` keyword, if one is found.
5217 fn parse_opt_abi(&mut self) -> Option<abi::Abi> {
5219 token::LIT_STR(s) | token::LIT_STR_RAW(s, _) => {
5221 let the_string = s.as_str();
5222 match abi::lookup(the_string) {
5223 Some(abi) => Some(abi),
5225 let last_span = self.last_span;
5228 format!("illegal ABI: expected one of [{}], \
5230 abi::all_names().connect(", "),
5231 the_string).as_slice());
5241 /// Parse one of the items or view items allowed by the
5242 /// flags; on failure, return IoviNone.
5243 /// NB: this function no longer parses the items inside an
5245 fn parse_item_or_view_item(&mut self,
5246 attrs: Vec<Attribute> ,
5247 macros_allowed: bool)
5249 let nt_item = match self.token {
5250 INTERPOLATED(token::NtItem(ref item)) => {
5251 Some((**item).clone())
5258 let mut attrs = attrs;
5259 mem::swap(&mut item.attrs, &mut attrs);
5260 item.attrs.extend(attrs.into_iter());
5261 return IoviItem(P(item));
5266 let lo = self.span.lo;
5268 let visibility = self.parse_visibility();
5270 // must be a view item:
5271 if self.eat_keyword(keywords::Use) {
5272 // USE ITEM (IoviViewItem)
5273 let view_item = self.parse_use();
5274 self.expect(&token::SEMI);
5275 return IoviViewItem(ast::ViewItem {
5279 span: mk_sp(lo, self.last_span.hi)
5282 // either a view item or an item:
5283 if self.eat_keyword(keywords::Extern) {
5284 let next_is_mod = self.eat_keyword(keywords::Mod);
5286 if next_is_mod || self.eat_keyword(keywords::Crate) {
5288 let last_span = self.last_span;
5289 self.span_err(mk_sp(lo, last_span.hi),
5290 format!("`extern mod` is obsolete, use \
5291 `extern crate` instead \
5292 to refer to external \
5293 crates.").as_slice())
5295 return self.parse_item_extern_crate(lo, visibility, attrs);
5298 let opt_abi = self.parse_opt_abi();
5300 if self.eat_keyword(keywords::Fn) {
5301 // EXTERN FUNCTION ITEM
5302 let abi = opt_abi.unwrap_or(abi::C);
5303 let (ident, item_, extra_attrs) =
5304 self.parse_item_fn(NormalFn, abi);
5305 let last_span = self.last_span;
5306 let item = self.mk_item(lo,
5311 maybe_append(attrs, extra_attrs));
5312 return IoviItem(item);
5313 } else if self.token == token::LBRACE {
5314 return self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs);
5317 let span = self.span;
5318 let token_str = self.this_token_to_string();
5319 self.span_fatal(span,
5320 format!("expected `{}` or `fn`, found `{}`", "{",
5321 token_str).as_slice());
5324 if self.eat_keyword(keywords::Virtual) {
5325 let span = self.span;
5326 self.span_err(span, "`virtual` structs have been removed from the language");
5329 // the rest are all guaranteed to be items:
5330 if self.is_keyword(keywords::Static) {
5333 let m = if self.eat_keyword(keywords::Mut) {MutMutable} else {MutImmutable};
5334 let (ident, item_, extra_attrs) = self.parse_item_const(Some(m));
5335 let last_span = self.last_span;
5336 let item = self.mk_item(lo,
5341 maybe_append(attrs, extra_attrs));
5342 return IoviItem(item);
5344 if self.is_keyword(keywords::Const) {
5347 if self.eat_keyword(keywords::Mut) {
5348 let last_span = self.last_span;
5349 self.span_err(last_span, "const globals cannot be mutable, \
5350 did you mean to declare a static?");
5352 let (ident, item_, extra_attrs) = self.parse_item_const(None);
5353 let last_span = self.last_span;
5354 let item = self.mk_item(lo,
5359 maybe_append(attrs, extra_attrs));
5360 return IoviItem(item);
5362 if self.is_keyword(keywords::Fn) &&
5363 self.look_ahead(1, |f| !Parser::fn_expr_lookahead(f)) {
5366 let (ident, item_, extra_attrs) =
5367 self.parse_item_fn(NormalFn, abi::Rust);
5368 let last_span = self.last_span;
5369 let item = self.mk_item(lo,
5374 maybe_append(attrs, extra_attrs));
5375 return IoviItem(item);
5377 if self.is_keyword(keywords::Unsafe)
5378 && self.look_ahead(1u, |t| *t != token::LBRACE) {
5379 // UNSAFE FUNCTION ITEM
5381 let abi = if self.eat_keyword(keywords::Extern) {
5382 self.parse_opt_abi().unwrap_or(abi::C)
5386 self.expect_keyword(keywords::Fn);
5387 let (ident, item_, extra_attrs) =
5388 self.parse_item_fn(UnsafeFn, abi);
5389 let last_span = self.last_span;
5390 let item = self.mk_item(lo,
5395 maybe_append(attrs, extra_attrs));
5396 return IoviItem(item);
5398 if self.eat_keyword(keywords::Mod) {
5400 let (ident, item_, extra_attrs) =
5401 self.parse_item_mod(attrs.as_slice());
5402 let last_span = self.last_span;
5403 let item = self.mk_item(lo,
5408 maybe_append(attrs, extra_attrs));
5409 return IoviItem(item);
5411 if self.eat_keyword(keywords::Type) {
5413 let (ident, item_, extra_attrs) = self.parse_item_type();
5414 let last_span = self.last_span;
5415 let item = self.mk_item(lo,
5420 maybe_append(attrs, extra_attrs));
5421 return IoviItem(item);
5423 if self.eat_keyword(keywords::Enum) {
5425 let (ident, item_, extra_attrs) = self.parse_item_enum();
5426 let last_span = self.last_span;
5427 let item = self.mk_item(lo,
5432 maybe_append(attrs, extra_attrs));
5433 return IoviItem(item);
5435 if self.eat_keyword(keywords::Trait) {
5437 let (ident, item_, extra_attrs) = self.parse_item_trait();
5438 let last_span = self.last_span;
5439 let item = self.mk_item(lo,
5444 maybe_append(attrs, extra_attrs));
5445 return IoviItem(item);
5447 if self.eat_keyword(keywords::Impl) {
5449 let (ident, item_, extra_attrs) = self.parse_item_impl();
5450 let last_span = self.last_span;
5451 let item = self.mk_item(lo,
5456 maybe_append(attrs, extra_attrs));
5457 return IoviItem(item);
5459 if self.eat_keyword(keywords::Struct) {
5461 let (ident, item_, extra_attrs) = self.parse_item_struct();
5462 let last_span = self.last_span;
5463 let item = self.mk_item(lo,
5468 maybe_append(attrs, extra_attrs));
5469 return IoviItem(item);
5471 self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
5474 /// Parse a foreign item; on failure, return IoviNone.
5475 fn parse_foreign_item(&mut self,
5476 attrs: Vec<Attribute> ,
5477 macros_allowed: bool)
5479 maybe_whole!(iovi self, NtItem);
5480 let lo = self.span.lo;
5482 let visibility = self.parse_visibility();
5484 if self.is_keyword(keywords::Static) {
5485 // FOREIGN STATIC ITEM
5486 let item = self.parse_item_foreign_static(visibility, attrs);
5487 return IoviForeignItem(item);
5489 if self.is_keyword(keywords::Fn) || self.is_keyword(keywords::Unsafe) {
5490 // FOREIGN FUNCTION ITEM
5491 let item = self.parse_item_foreign_fn(visibility, attrs);
5492 return IoviForeignItem(item);
5494 self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
5497 /// This is the fall-through for parsing items.
5498 fn parse_macro_use_or_failure(
5500 attrs: Vec<Attribute> ,
5501 macros_allowed: bool,
5503 visibility: Visibility
5504 ) -> ItemOrViewItem {
5505 if macros_allowed && !token::is_any_keyword(&self.token)
5506 && self.look_ahead(1, |t| *t == token::NOT)
5507 && (self.look_ahead(2, |t| is_plain_ident(t))
5508 || self.look_ahead(2, |t| *t == token::LPAREN)
5509 || self.look_ahead(2, |t| *t == token::LBRACE)) {
5510 // MACRO INVOCATION ITEM
5513 let pth = self.parse_path(NoTypesAllowed).path;
5514 self.expect(&token::NOT);
5516 // a 'special' identifier (like what `macro_rules!` uses)
5517 // is optional. We should eventually unify invoc syntax
5519 let id = if is_plain_ident(&self.token) {
5522 token::special_idents::invalid // no special identifier
5524 // eat a matched-delimiter token tree:
5525 let tts = match token::close_delimiter_for(&self.token) {
5528 self.parse_seq_to_end(&ket,
5530 |p| p.parse_token_tree())
5532 None => self.fatal("expected open delimiter")
5534 // single-variant-enum... :
5535 let m = ast::MacInvocTT(pth, tts, EMPTY_CTXT);
5536 let m: ast::Mac = codemap::Spanned { node: m,
5537 span: mk_sp(self.span.lo,
5539 let item_ = ItemMac(m);
5540 let last_span = self.last_span;
5541 let item = self.mk_item(lo,
5547 return IoviItem(item);
5550 // FAILURE TO PARSE ITEM
5551 if visibility != Inherited {
5552 let mut s = String::from_str("unmatched visibility `");
5553 if visibility == Public {
5559 let last_span = self.last_span;
5560 self.span_fatal(last_span, s.as_slice());
5562 return IoviNone(attrs);
5565 pub fn parse_item_with_outer_attributes(&mut self) -> Option<P<Item>> {
5566 let attrs = self.parse_outer_attributes();
5567 self.parse_item(attrs)
5570 pub fn parse_item(&mut self, attrs: Vec<Attribute>) -> Option<P<Item>> {
5571 match self.parse_item_or_view_item(attrs, true) {
5572 IoviNone(_) => None,
5574 self.fatal("view items are not allowed here"),
5575 IoviForeignItem(_) =>
5576 self.fatal("foreign items are not allowed here"),
5577 IoviItem(item) => Some(item)
5581 /// Parse, e.g., "use a::b::{z,y}"
5582 fn parse_use(&mut self) -> ViewItem_ {
5583 return ViewItemUse(self.parse_view_path());
5587 /// Matches view_path : MOD? IDENT EQ non_global_path
5588 /// | MOD? non_global_path MOD_SEP LBRACE RBRACE
5589 /// | MOD? non_global_path MOD_SEP LBRACE ident_seq RBRACE
5590 /// | MOD? non_global_path MOD_SEP STAR
5591 /// | MOD? non_global_path
5592 fn parse_view_path(&mut self) -> P<ViewPath> {
5593 let lo = self.span.lo;
5595 if self.token == token::LBRACE {
5597 let idents = self.parse_unspanned_seq(
5598 &token::LBRACE, &token::RBRACE,
5599 seq_sep_trailing_allowed(token::COMMA),
5600 |p| p.parse_path_list_item());
5601 let path = ast::Path {
5602 span: mk_sp(lo, self.span.hi),
5604 segments: Vec::new()
5606 return P(spanned(lo, self.span.hi,
5607 ViewPathList(path, idents, ast::DUMMY_NODE_ID)));
5610 let first_ident = self.parse_ident();
5611 let mut path = vec!(first_ident);
5616 let path_lo = self.span.lo;
5617 path = vec!(self.parse_ident());
5618 while self.token == token::MOD_SEP {
5620 let id = self.parse_ident();
5623 let span = mk_sp(path_lo, self.span.hi);
5624 self.obsolete(span, ObsoleteImportRenaming);
5625 let path = ast::Path {
5628 segments: path.into_iter().map(|identifier| {
5630 identifier: identifier,
5631 lifetimes: Vec::new(),
5632 types: OwnedSlice::empty(),
5636 return P(spanned(lo, self.span.hi,
5637 ViewPathSimple(first_ident, path,
5638 ast::DUMMY_NODE_ID)));
5642 // foo::bar or foo::{a,b,c} or foo::*
5643 while self.token == token::MOD_SEP {
5647 token::IDENT(i, _) => {
5652 // foo::bar::{a,b,c}
5654 let idents = self.parse_unspanned_seq(
5657 seq_sep_trailing_allowed(token::COMMA),
5658 |p| p.parse_path_list_item()
5660 let path = ast::Path {
5661 span: mk_sp(lo, self.span.hi),
5663 segments: path.into_iter().map(|identifier| {
5665 identifier: identifier,
5666 lifetimes: Vec::new(),
5667 types: OwnedSlice::empty(),
5671 return P(spanned(lo, self.span.hi,
5672 ViewPathList(path, idents, ast::DUMMY_NODE_ID)));
5676 token::BINOP(token::STAR) => {
5678 let path = ast::Path {
5679 span: mk_sp(lo, self.span.hi),
5681 segments: path.into_iter().map(|identifier| {
5683 identifier: identifier,
5684 lifetimes: Vec::new(),
5685 types: OwnedSlice::empty(),
5689 return P(spanned(lo, self.span.hi,
5690 ViewPathGlob(path, ast::DUMMY_NODE_ID)));
5699 let mut rename_to = path[path.len() - 1u];
5700 let path = ast::Path {
5701 span: mk_sp(lo, self.span.hi),
5703 segments: path.into_iter().map(|identifier| {
5705 identifier: identifier,
5706 lifetimes: Vec::new(),
5707 types: OwnedSlice::empty(),
5711 if self.eat_keyword(keywords::As) {
5712 rename_to = self.parse_ident()
5714 P(spanned(lo, self.last_span.hi,
5715 ViewPathSimple(rename_to, path, ast::DUMMY_NODE_ID)))
5718 /// Parses a sequence of items. Stops when it finds program
5719 /// text that can't be parsed as an item
5720 /// - mod_items uses extern_mod_allowed = true
5721 /// - block_tail_ uses extern_mod_allowed = false
5722 fn parse_items_and_view_items(&mut self,
5723 first_item_attrs: Vec<Attribute> ,
5724 mut extern_mod_allowed: bool,
5725 macros_allowed: bool)
5726 -> ParsedItemsAndViewItems {
5727 let mut attrs = first_item_attrs;
5728 attrs.push_all(self.parse_outer_attributes().as_slice());
5729 // First, parse view items.
5730 let mut view_items : Vec<ast::ViewItem> = Vec::new();
5731 let mut items = Vec::new();
5733 // I think this code would probably read better as a single
5734 // loop with a mutable three-state-variable (for extern crates,
5735 // view items, and regular items) ... except that because
5736 // of macros, I'd like to delay that entire check until later.
5738 match self.parse_item_or_view_item(attrs, macros_allowed) {
5739 IoviNone(attrs) => {
5740 return ParsedItemsAndViewItems {
5741 attrs_remaining: attrs,
5742 view_items: view_items,
5744 foreign_items: Vec::new()
5747 IoviViewItem(view_item) => {
5748 match view_item.node {
5749 ViewItemUse(..) => {
5750 // `extern crate` must precede `use`.
5751 extern_mod_allowed = false;
5753 ViewItemExternCrate(..) if !extern_mod_allowed => {
5754 self.span_err(view_item.span,
5755 "\"extern crate\" declarations are \
5758 ViewItemExternCrate(..) => {}
5760 view_items.push(view_item);
5764 attrs = self.parse_outer_attributes();
5767 IoviForeignItem(_) => {
5771 attrs = self.parse_outer_attributes();
5774 // Next, parse items.
5776 match self.parse_item_or_view_item(attrs, macros_allowed) {
5777 IoviNone(returned_attrs) => {
5778 attrs = returned_attrs;
5781 IoviViewItem(view_item) => {
5782 attrs = self.parse_outer_attributes();
5783 self.span_err(view_item.span,
5784 "`use` and `extern crate` declarations must precede items");
5787 attrs = self.parse_outer_attributes();
5790 IoviForeignItem(_) => {
5796 ParsedItemsAndViewItems {
5797 attrs_remaining: attrs,
5798 view_items: view_items,
5800 foreign_items: Vec::new()
5804 /// Parses a sequence of foreign items. Stops when it finds program
5805 /// text that can't be parsed as an item
5806 fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute> ,
5807 macros_allowed: bool)
5808 -> ParsedItemsAndViewItems {
5809 let mut attrs = first_item_attrs;
5810 attrs.push_all(self.parse_outer_attributes().as_slice());
5811 let mut foreign_items = Vec::new();
5813 match self.parse_foreign_item(attrs, macros_allowed) {
5814 IoviNone(returned_attrs) => {
5815 if self.token == token::RBRACE {
5816 attrs = returned_attrs;
5821 IoviViewItem(view_item) => {
5822 // I think this can't occur:
5823 self.span_err(view_item.span,
5824 "`use` and `extern crate` declarations must precede items");
5827 // FIXME #5668: this will occur for a macro invocation:
5828 self.span_fatal(item.span, "macros cannot expand to foreign items");
5830 IoviForeignItem(foreign_item) => {
5831 foreign_items.push(foreign_item);
5834 attrs = self.parse_outer_attributes();
5837 ParsedItemsAndViewItems {
5838 attrs_remaining: attrs,
5839 view_items: Vec::new(),
5841 foreign_items: foreign_items
5845 /// Parses a source module as a crate. This is the main
5846 /// entry point for the parser.
5847 pub fn parse_crate_mod(&mut self) -> Crate {
5848 let lo = self.span.lo;
5849 // parse the crate's inner attrs, maybe (oops) one
5850 // of the attrs of an item:
5851 let (inner, next) = self.parse_inner_attrs_and_next();
5852 let first_item_outer_attrs = next;
5853 // parse the items inside the crate:
5854 let m = self.parse_mod_items(token::EOF, first_item_outer_attrs, lo);
5859 config: self.cfg.clone(),
5860 span: mk_sp(lo, self.span.lo),
5861 exported_macros: Vec::new(),
5865 pub fn parse_optional_str(&mut self)
5866 -> Option<(InternedString, ast::StrStyle)> {
5867 let (s, style) = match self.token {
5868 token::LIT_STR(s) => (self.id_to_interned_str(s.ident()), ast::CookedStr),
5869 token::LIT_STR_RAW(s, n) => {
5870 (self.id_to_interned_str(s.ident()), ast::RawStr(n))
5878 pub fn parse_str(&mut self) -> (InternedString, StrStyle) {
5879 match self.parse_optional_str() {
5881 _ => self.fatal("expected string literal")