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::{BareFnTy, ClosureTy};
15 use ast::{StaticRegionTyParamBound, OtherRegionTyParamBound, TraitTyParamBound};
16 use ast::{Provided, Public, FnStyle};
17 use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue};
18 use ast::{BiBitAnd, BiBitOr, BiBitXor, Block};
19 use ast::{BlockCheckMode, UnBox};
20 use ast::{Crate, CrateConfig, Decl, DeclItem};
21 use ast::{DeclLocal, DefaultBlock, UnDeref, BiDiv, EMPTY_CTXT, EnumDef, ExplicitSelf};
22 use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain};
23 use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox};
24 use ast::{ExprBreak, ExprCall, ExprCast};
25 use ast::{ExprField, ExprFnBlock, ExprIf, ExprIndex};
26 use ast::{ExprLit, ExprLoop, ExprMac};
27 use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc};
28 use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary, ExprUnboxedFn};
29 use ast::{ExprVec, ExprVstore, ExprVstoreSlice};
30 use ast::{ExprVstoreMutSlice, ExprWhile, ExprForLoop, Field, FnDecl};
31 use ast::{ExprVstoreUniq, Once, Many};
32 use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod};
33 use ast::{Ident, NormalFn, Inherited, Item, Item_, ItemStatic};
34 use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl};
35 use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy, Lit, Lit_};
36 use ast::{LitBool, LitChar, LitByte, LitBinary};
37 use ast::{LitNil, LitStr, LitUint, Local, LocalLet};
38 use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, Matcher, MatchNonterminal};
39 use ast::{MatchSeq, MatchTok, Method, MutTy, BiMul, Mutability};
40 use ast::{NamedField, UnNeg, NoReturn, UnNot, P, Pat, PatEnum};
41 use ast::{PatIdent, PatLit, PatRange, PatRegion, PatStruct};
42 use ast::{PatTup, PatBox, PatWild, PatWildMulti};
43 use ast::{BiRem, Required};
44 use ast::{RetStyle, Return, BiShl, BiShr, Stmt, StmtDecl};
45 use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField};
46 use ast::{StructVariantKind, BiSub};
48 use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue};
49 use ast::{TokenTree, TraitMethod, TraitRef, TTDelim, TTSeq, TTTok};
50 use ast::{TTNonterminal, TupleVariantKind, Ty, Ty_, TyBot, TyBox};
51 use ast::{TypeField, TyFixedLengthVec, TyClosure, TyProc, TyBareFn};
52 use ast::{TyTypeof, TyInfer, TypeMethod};
53 use ast::{TyNil, TyParam, TyParamBound, TyParen, TyPath, TyPtr, TyRptr};
54 use ast::{TyTup, TyU32, TyUnboxedFn, TyUniq, TyVec, UnUniq};
55 use ast::{UnboxedFnTy, UnboxedFnTyParamBound, UnnamedField, UnsafeBlock};
56 use ast::{UnsafeFn, ViewItem, ViewItem_, ViewItemExternCrate, ViewItemUse};
57 use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
60 use ast_util::{as_prec, ident_to_path, lit_is_str, operator_prec};
63 use codemap::{Span, BytePos, Spanned, spanned, mk_sp};
66 use parse::attr::ParserAttr;
68 use parse::common::{SeqSep, seq_sep_none};
69 use parse::common::{seq_sep_trailing_disallowed, seq_sep_trailing_allowed};
70 use parse::lexer::Reader;
71 use parse::lexer::TokenAndSpan;
72 use parse::obsolete::*;
73 use parse::token::{INTERPOLATED, InternedString, can_begin_expr};
74 use parse::token::{is_ident, is_ident_or_path, is_plain_ident};
75 use parse::token::{keywords, special_idents, token_to_binop};
77 use parse::{new_sub_parser_from_file, ParseSess};
78 use owned_slice::OwnedSlice;
80 use std::collections::HashSet;
81 use std::mem::replace;
83 use std::gc::{Gc, GC};
85 #[allow(non_camel_case_types)]
86 #[deriving(PartialEq)]
87 pub enum restriction {
91 RESTRICT_NO_BAR_OR_DOUBLEBAR_OP,
92 RESTRICT_NO_STRUCT_LITERAL,
95 type ItemInfo = (Ident, Item_, Option<Vec<Attribute> >);
97 /// How to parse a path. There are four different kinds of paths, all of which
98 /// are parsed somewhat differently.
99 #[deriving(PartialEq)]
100 pub enum PathParsingMode {
101 /// A path with no type parameters; e.g. `foo::bar::Baz`
103 /// A path with a lifetime and type parameters, with no double colons
104 /// before the type parameters; e.g. `foo::bar<'a>::Baz<T>`
105 LifetimeAndTypesWithoutColons,
106 /// A path with a lifetime and type parameters with double colons before
107 /// the type parameters; e.g. `foo::bar::<'a>::Baz::<T>`
108 LifetimeAndTypesWithColons,
109 /// A path with a lifetime and type parameters with bounds before the last
110 /// set of type parameters only; e.g. `foo::bar<'a>::Baz+X+Y<T>` This
111 /// form does not use extra double colons.
112 LifetimeAndTypesAndBounds,
115 /// A path paired with optional type bounds.
116 pub struct PathAndBounds {
118 pub bounds: Option<OwnedSlice<TyParamBound>>,
121 enum ItemOrViewItem {
122 /// Indicates a failure to parse any kind of item. The attributes are
124 IoviNone(Vec<Attribute>),
126 IoviForeignItem(Gc<ForeignItem>),
127 IoviViewItem(ViewItem)
131 /// Possibly accept an `INTERPOLATED` expression (a pre-parsed expression
132 /// dropped into the token stream, which happens while parsing the
133 /// result of macro expansion)
134 /// Placement of these is not as complex as I feared it would be.
135 /// The important thing is to make sure that lookahead doesn't balk
136 /// at INTERPOLATED tokens
137 macro_rules! maybe_whole_expr (
140 let found = match $p.token {
141 INTERPOLATED(token::NtExpr(e)) => {
144 INTERPOLATED(token::NtPath(_)) => {
145 // FIXME: The following avoids an issue with lexical borrowck scopes,
146 // but the clone is unfortunate.
147 let pt = match $p.token {
148 INTERPOLATED(token::NtPath(ref pt)) => (**pt).clone(),
152 Some($p.mk_expr(span.lo, span.hi, ExprPath(pt)))
154 INTERPOLATED(token::NtBlock(b)) => {
156 Some($p.mk_expr(span.lo, span.hi, ExprBlock(b)))
171 /// As maybe_whole_expr, but for things other than expressions
172 macro_rules! maybe_whole (
173 ($p:expr, $constructor:ident) => (
175 let found = match ($p).token {
176 INTERPOLATED(token::$constructor(_)) => {
177 Some(($p).bump_and_get())
182 Some(INTERPOLATED(token::$constructor(x))) => {
189 (no_clone $p:expr, $constructor:ident) => (
191 let found = match ($p).token {
192 INTERPOLATED(token::$constructor(_)) => {
193 Some(($p).bump_and_get())
198 Some(INTERPOLATED(token::$constructor(x))) => {
205 (deref $p:expr, $constructor:ident) => (
207 let found = match ($p).token {
208 INTERPOLATED(token::$constructor(_)) => {
209 Some(($p).bump_and_get())
214 Some(INTERPOLATED(token::$constructor(x))) => {
221 (Some $p:expr, $constructor:ident) => (
223 let found = match ($p).token {
224 INTERPOLATED(token::$constructor(_)) => {
225 Some(($p).bump_and_get())
230 Some(INTERPOLATED(token::$constructor(x))) => {
231 return Some(x.clone()),
237 (iovi $p:expr, $constructor:ident) => (
239 let found = match ($p).token {
240 INTERPOLATED(token::$constructor(_)) => {
241 Some(($p).bump_and_get())
246 Some(INTERPOLATED(token::$constructor(x))) => {
247 return IoviItem(x.clone())
253 (pair_empty $p:expr, $constructor:ident) => (
255 let found = match ($p).token {
256 INTERPOLATED(token::$constructor(_)) => {
257 Some(($p).bump_and_get())
262 Some(INTERPOLATED(token::$constructor(x))) => {
263 return (Vec::new(), x)
272 fn maybe_append(lhs: Vec<Attribute> , rhs: Option<Vec<Attribute> >)
276 Some(ref attrs) => lhs.append(attrs.as_slice())
281 struct ParsedItemsAndViewItems {
282 attrs_remaining: Vec<Attribute>,
283 view_items: Vec<ViewItem>,
284 items: Vec<Gc<Item>>,
285 foreign_items: Vec<Gc<ForeignItem>>
288 /* ident is handled by common.rs */
290 pub struct Parser<'a> {
291 pub sess: &'a ParseSess,
292 /// the current token:
293 pub token: token::Token,
294 /// the span of the current token:
296 /// the span of the prior token:
298 pub cfg: CrateConfig,
299 /// the previous token or None (only stashed sometimes).
300 pub last_token: Option<Box<token::Token>>,
301 pub buffer: [TokenAndSpan, ..4],
302 pub buffer_start: int,
304 pub tokens_consumed: uint,
305 pub restriction: restriction,
306 pub quote_depth: uint, // not (yet) related to the quasiquoter
307 pub reader: Box<Reader>,
308 pub interner: Rc<token::IdentInterner>,
309 /// The set of seen errors about obsolete syntax. Used to suppress
310 /// extra detail when the same error is seen twice
311 pub obsolete_set: HashSet<ObsoleteSyntax>,
312 /// Used to determine the path to externally loaded source files
313 pub mod_path_stack: Vec<InternedString>,
314 /// Stack of spans of open delimiters. Used for error message.
315 pub open_braces: Vec<Span>,
316 /// Flag if this parser "owns" the directory that it is currently parsing
317 /// in. This will affect how nested files are looked up.
318 pub owns_directory: bool,
319 /// Name of the root module this parser originated from. If `None`, then the
320 /// name is not known. This does not change while the parser is descending
321 /// into modules, and sub-parsers have new values for this name.
322 pub root_module_name: Option<String>,
325 fn is_plain_ident_or_underscore(t: &token::Token) -> bool {
326 is_plain_ident(t) || *t == token::UNDERSCORE
329 /// Get a token the parser cares about
330 fn real_token(rdr: &mut Reader) -> TokenAndSpan {
331 let mut t = rdr.next_token();
334 token::WS | token::COMMENT | token::SHEBANG(_) => {
335 t = rdr.next_token();
343 impl<'a> Parser<'a> {
344 pub fn new(sess: &'a ParseSess, cfg: ast::CrateConfig,
345 mut rdr: Box<Reader>) -> Parser<'a> {
346 let tok0 = real_token(rdr);
348 let placeholder = TokenAndSpan {
349 tok: token::UNDERSCORE,
355 interner: token::get_ident_interner(),
371 restriction: UNRESTRICTED,
373 obsolete_set: HashSet::new(),
374 mod_path_stack: Vec::new(),
375 open_braces: Vec::new(),
376 owns_directory: true,
377 root_module_name: None,
381 /// Convert a token to a string using self's reader
382 pub fn token_to_string(token: &token::Token) -> String {
383 token::to_string(token)
386 /// Convert the current token to a string using self's reader
387 pub fn this_token_to_string(&mut self) -> String {
388 Parser::token_to_string(&self.token)
391 pub fn unexpected_last(&mut self, t: &token::Token) -> ! {
392 let token_str = Parser::token_to_string(t);
393 let last_span = self.last_span;
394 self.span_fatal(last_span, format!("unexpected token: `{}`",
395 token_str).as_slice());
398 pub fn unexpected(&mut self) -> ! {
399 let this_token = self.this_token_to_string();
400 self.fatal(format!("unexpected token: `{}`", this_token).as_slice());
403 /// Expect and consume the token t. Signal an error if
404 /// the next token is not t.
405 pub fn expect(&mut self, t: &token::Token) {
406 if self.token == *t {
409 let token_str = Parser::token_to_string(t);
410 let this_token_str = self.this_token_to_string();
411 self.fatal(format!("expected `{}` but found `{}`",
413 this_token_str).as_slice())
417 /// Expect next token to be edible or inedible token. If edible,
418 /// then consume it; if inedible, then return without consuming
419 /// anything. Signal a fatal error if next token is unexpected.
420 pub fn expect_one_of(&mut self,
421 edible: &[token::Token],
422 inedible: &[token::Token]) {
423 fn tokens_to_string(tokens: &[token::Token]) -> String {
424 let mut i = tokens.iter();
425 // This might be a sign we need a connect method on Iterator.
427 .map_or("".to_string(), |t| Parser::token_to_string(t));
431 b.push_str(Parser::token_to_string(a).as_slice());
435 if edible.contains(&self.token) {
437 } else if inedible.contains(&self.token) {
438 // leave it in the input
440 let expected = edible.iter().map(|x| (*x).clone()).collect::<Vec<_>>().append(inedible);
441 let expect = tokens_to_string(expected.as_slice());
442 let actual = self.this_token_to_string();
444 (if expected.len() != 1 {
445 (format!("expected one of `{}` but found `{}`",
449 (format!("expected `{}` but found `{}`",
457 /// Check for erroneous `ident { }`; if matches, signal error and
458 /// recover (without consuming any expected input token). Returns
459 /// true if and only if input was consumed for recovery.
460 pub fn check_for_erroneous_unit_struct_expecting(&mut self, expected: &[token::Token]) -> bool {
461 if self.token == token::LBRACE
462 && expected.iter().all(|t| *t != token::LBRACE)
463 && self.look_ahead(1, |t| *t == token::RBRACE) {
464 // matched; signal non-fatal error and recover.
465 let span = self.span;
467 "unit-like struct construction is written with no trailing `{ }`");
468 self.eat(&token::LBRACE);
469 self.eat(&token::RBRACE);
476 /// Commit to parsing a complete expression `e` expected to be
477 /// followed by some token from the set edible + inedible. Recover
478 /// from anticipated input errors, discarding erroneous characters.
479 pub fn commit_expr(&mut self, e: Gc<Expr>, edible: &[token::Token],
480 inedible: &[token::Token]) {
481 debug!("commit_expr {:?}", e);
484 // might be unit-struct construction; check for recoverableinput error.
485 let expected = edible.iter().map(|x| (*x).clone()).collect::<Vec<_>>()
487 self.check_for_erroneous_unit_struct_expecting(
488 expected.as_slice());
492 self.expect_one_of(edible, inedible)
495 pub fn commit_expr_expecting(&mut self, e: Gc<Expr>, edible: token::Token) {
496 self.commit_expr(e, &[edible], &[])
499 /// Commit to parsing a complete statement `s`, which expects to be
500 /// followed by some token from the set edible + inedible. Check
501 /// for recoverable input errors, discarding erroneous characters.
502 pub fn commit_stmt(&mut self, s: Gc<Stmt>, edible: &[token::Token],
503 inedible: &[token::Token]) {
504 debug!("commit_stmt {:?}", s);
505 let _s = s; // unused, but future checks might want to inspect `s`.
508 .map_or(false, |t| is_ident_or_path(&**t)) {
509 let expected = edible.iter().map(|x| (*x).clone()).collect::<Vec<_>>()
510 .append(inedible.as_slice());
511 self.check_for_erroneous_unit_struct_expecting(
512 expected.as_slice());
514 self.expect_one_of(edible, inedible)
517 pub fn commit_stmt_expecting(&mut self, s: Gc<Stmt>, edible: token::Token) {
518 self.commit_stmt(s, &[edible], &[])
521 pub fn parse_ident(&mut self) -> ast::Ident {
522 self.check_strict_keywords();
523 self.check_reserved_keywords();
525 token::IDENT(i, _) => {
529 token::INTERPOLATED(token::NtIdent(..)) => {
530 self.bug("ident interpolation not converted to real token");
533 let token_str = self.this_token_to_string();
534 self.fatal((format!("expected ident, found `{}`",
535 token_str)).as_slice())
540 pub fn parse_path_list_item(&mut self) -> ast::PathListItem {
541 let lo = self.span.lo;
542 let node = if self.eat_keyword(keywords::Mod) {
543 ast::PathListMod { id: ast::DUMMY_NODE_ID }
545 let ident = self.parse_ident();
546 ast::PathListIdent { name: ident, id: ast::DUMMY_NODE_ID }
548 let hi = self.last_span.hi;
549 spanned(lo, hi, node)
552 /// Consume token 'tok' if it exists. Returns true if the given
553 /// token was present, false otherwise.
554 pub fn eat(&mut self, tok: &token::Token) -> bool {
555 let is_present = self.token == *tok;
556 if is_present { self.bump() }
560 pub fn is_keyword(&mut self, kw: keywords::Keyword) -> bool {
561 token::is_keyword(kw, &self.token)
564 /// If the next token is the given keyword, eat it and return
565 /// true. Otherwise, return false.
566 pub fn eat_keyword(&mut self, kw: keywords::Keyword) -> bool {
568 token::IDENT(sid, false) if kw.to_name() == sid.name => {
576 /// If the given word is not a keyword, signal an error.
577 /// If the next token is not the given word, signal an error.
578 /// Otherwise, eat it.
579 pub fn expect_keyword(&mut self, kw: keywords::Keyword) {
580 if !self.eat_keyword(kw) {
581 let id_interned_str = token::get_name(kw.to_name());
582 let token_str = self.this_token_to_string();
583 self.fatal(format!("expected `{}`, found `{}`",
584 id_interned_str, token_str).as_slice())
588 /// Signal an error if the given string is a strict keyword
589 pub fn check_strict_keywords(&mut self) {
590 if token::is_strict_keyword(&self.token) {
591 let token_str = self.this_token_to_string();
592 let span = self.span;
594 format!("found `{}` in ident position",
595 token_str).as_slice());
599 /// Signal an error if the current token is a reserved keyword
600 pub fn check_reserved_keywords(&mut self) {
601 if token::is_reserved_keyword(&self.token) {
602 let token_str = self.this_token_to_string();
603 self.fatal(format!("`{}` is a reserved keyword",
604 token_str).as_slice())
608 /// Expect and consume an `&`. If `&&` is seen, replace it with a single
609 /// `&` and continue. If an `&` is not seen, signal an error.
610 fn expect_and(&mut self) {
612 token::BINOP(token::AND) => self.bump(),
614 let span = self.span;
615 let lo = span.lo + BytePos(1);
616 self.replace_token(token::BINOP(token::AND), lo, span.hi)
619 let token_str = self.this_token_to_string();
621 Parser::token_to_string(&token::BINOP(token::AND));
622 self.fatal(format!("expected `{}`, found `{}`",
624 token_str).as_slice())
629 /// Expect and consume a `|`. If `||` is seen, replace it with a single
630 /// `|` and continue. If a `|` is not seen, signal an error.
631 fn expect_or(&mut self) {
633 token::BINOP(token::OR) => self.bump(),
635 let span = self.span;
636 let lo = span.lo + BytePos(1);
637 self.replace_token(token::BINOP(token::OR), lo, span.hi)
640 let found_token = self.this_token_to_string();
642 Parser::token_to_string(&token::BINOP(token::OR));
643 self.fatal(format!("expected `{}`, found `{}`",
645 found_token).as_slice())
650 /// Attempt to consume a `<`. If `<<` is seen, replace it with a single
651 /// `<` and continue. If a `<` is not seen, return false.
653 /// This is meant to be used when parsing generics on a path to get the
654 /// starting token. The `force` parameter is used to forcefully break up a
655 /// `<<` token. If `force` is false, then `<<` is only broken when a lifetime
656 /// shows up next. For example, consider the expression:
658 /// foo as bar << test
660 /// The parser needs to know if `bar <<` is the start of a generic path or if
661 /// it's a left-shift token. If `test` were a lifetime, then it's impossible
662 /// for the token to be a left-shift, but if it's not a lifetime, then it's
663 /// considered a left-shift.
665 /// The reason for this is that the only current ambiguity with `<<` is when
666 /// parsing closure types:
668 /// foo::<<'a> ||>();
669 /// impl Foo<<'a> ||>() { ... }
670 fn eat_lt(&mut self, force: bool) -> bool {
672 token::LT => { self.bump(); true }
673 token::BINOP(token::SHL) => {
674 let next_lifetime = self.look_ahead(1, |t| match *t {
675 token::LIFETIME(..) => true,
678 if force || next_lifetime {
679 let span = self.span;
680 let lo = span.lo + BytePos(1);
681 self.replace_token(token::LT, lo, span.hi);
691 fn expect_lt(&mut self) {
692 if !self.eat_lt(true) {
693 let found_token = self.this_token_to_string();
694 let token_str = Parser::token_to_string(&token::LT);
695 self.fatal(format!("expected `{}`, found `{}`",
697 found_token).as_slice())
701 /// Parse a sequence bracketed by `|` and `|`, stopping before the `|`.
702 fn parse_seq_to_before_or<T>(
705 f: |&mut Parser| -> T)
707 let mut first = true;
708 let mut vector = Vec::new();
709 while self.token != token::BINOP(token::OR) &&
710 self.token != token::OROR {
722 /// Expect and consume a GT. if a >> is seen, replace it
723 /// with a single > and continue. If a GT is not seen,
725 pub fn expect_gt(&mut self) {
727 token::GT => self.bump(),
728 token::BINOP(token::SHR) => {
729 let span = self.span;
730 let lo = span.lo + BytePos(1);
731 self.replace_token(token::GT, lo, span.hi)
733 token::BINOPEQ(token::SHR) => {
734 let span = self.span;
735 let lo = span.lo + BytePos(1);
736 self.replace_token(token::GE, lo, span.hi)
739 let span = self.span;
740 let lo = span.lo + BytePos(1);
741 self.replace_token(token::EQ, lo, span.hi)
744 let gt_str = Parser::token_to_string(&token::GT);
745 let this_token_str = self.this_token_to_string();
746 self.fatal(format!("expected `{}`, found `{}`",
748 this_token_str).as_slice())
753 /// Parse a sequence bracketed by '<' and '>', stopping
755 pub fn parse_seq_to_before_gt<T>(
757 sep: Option<token::Token>,
758 f: |&mut Parser| -> T)
760 let mut first = true;
761 let mut v = Vec::new();
762 while self.token != token::GT
763 && self.token != token::BINOP(token::SHR)
764 && self.token != token::GE
765 && self.token != token::BINOPEQ(token::SHR) {
768 if first { first = false; }
769 else { self.expect(t); }
775 return OwnedSlice::from_vec(v);
778 pub fn parse_seq_to_gt<T>(
780 sep: Option<token::Token>,
781 f: |&mut Parser| -> T)
783 let v = self.parse_seq_to_before_gt(sep, f);
788 /// Parse a sequence, including the closing delimiter. The function
789 /// f must consume tokens until reaching the next separator or
791 pub fn parse_seq_to_end<T>(
795 f: |&mut Parser| -> T)
797 let val = self.parse_seq_to_before_end(ket, sep, f);
802 /// Parse a sequence, not including the closing delimiter. The function
803 /// f must consume tokens until reaching the next separator or
805 pub fn parse_seq_to_before_end<T>(
809 f: |&mut Parser| -> T)
811 let mut first: bool = true;
813 while self.token != *ket {
816 if first { first = false; }
817 else { self.expect(t); }
821 if sep.trailing_sep_allowed && self.token == *ket { break; }
827 /// Parse a sequence, including the closing delimiter. The function
828 /// f must consume tokens until reaching the next separator or
830 pub fn parse_unspanned_seq<T>(
835 f: |&mut Parser| -> T)
838 let result = self.parse_seq_to_before_end(ket, sep, f);
843 /// Parse a sequence parameter of enum variant. For consistency purposes,
844 /// these should not be empty.
845 pub fn parse_enum_variant_seq<T>(
850 f: |&mut Parser| -> T)
852 let result = self.parse_unspanned_seq(bra, ket, sep, f);
853 if result.is_empty() {
854 let last_span = self.last_span;
855 self.span_err(last_span,
856 "nullary enum variants are written with no trailing `( )`");
861 // NB: Do not use this function unless you actually plan to place the
862 // spanned list in the AST.
868 f: |&mut Parser| -> T)
869 -> Spanned<Vec<T> > {
870 let lo = self.span.lo;
872 let result = self.parse_seq_to_before_end(ket, sep, f);
873 let hi = self.span.hi;
875 spanned(lo, hi, result)
878 /// Advance the parser by one token
879 pub fn bump(&mut self) {
880 self.last_span = self.span;
881 // Stash token for error recovery (sometimes; clone is not necessarily cheap).
882 self.last_token = if is_ident_or_path(&self.token) {
883 Some(box self.token.clone())
887 let next = if self.buffer_start == self.buffer_end {
888 real_token(self.reader)
890 // Avoid token copies with `replace`.
891 let buffer_start = self.buffer_start as uint;
892 let next_index = (buffer_start + 1) & 3 as uint;
893 self.buffer_start = next_index as int;
895 let placeholder = TokenAndSpan {
896 tok: token::UNDERSCORE,
899 replace(&mut self.buffer[buffer_start], placeholder)
902 self.token = next.tok;
903 self.tokens_consumed += 1u;
906 /// Advance the parser by one token and return the bumped token.
907 pub fn bump_and_get(&mut self) -> token::Token {
908 let old_token = replace(&mut self.token, token::UNDERSCORE);
913 /// EFFECT: replace the current token and span with the given one
914 pub fn replace_token(&mut self,
918 self.last_span = mk_sp(self.span.lo, lo);
920 self.span = mk_sp(lo, hi);
922 pub fn buffer_length(&mut self) -> int {
923 if self.buffer_start <= self.buffer_end {
924 return self.buffer_end - self.buffer_start;
926 return (4 - self.buffer_start) + self.buffer_end;
928 pub fn look_ahead<R>(&mut self, distance: uint, f: |&token::Token| -> R)
930 let dist = distance as int;
931 while self.buffer_length() < dist {
932 self.buffer[self.buffer_end as uint] = real_token(self.reader);
933 self.buffer_end = (self.buffer_end + 1) & 3;
935 f(&self.buffer[((self.buffer_start + dist - 1) & 3) as uint].tok)
937 pub fn fatal(&mut self, m: &str) -> ! {
938 self.sess.span_diagnostic.span_fatal(self.span, m)
940 pub fn span_fatal(&mut self, sp: Span, m: &str) -> ! {
941 self.sess.span_diagnostic.span_fatal(sp, m)
943 pub fn span_note(&mut self, sp: Span, m: &str) {
944 self.sess.span_diagnostic.span_note(sp, m)
946 pub fn bug(&mut self, m: &str) -> ! {
947 self.sess.span_diagnostic.span_bug(self.span, m)
949 pub fn warn(&mut self, m: &str) {
950 self.sess.span_diagnostic.span_warn(self.span, m)
952 pub fn span_warn(&mut self, sp: Span, m: &str) {
953 self.sess.span_diagnostic.span_warn(sp, m)
955 pub fn span_err(&mut self, sp: Span, m: &str) {
956 self.sess.span_diagnostic.span_err(sp, m)
958 pub fn abort_if_errors(&mut self) {
959 self.sess.span_diagnostic.handler().abort_if_errors();
962 pub fn id_to_interned_str(&mut self, id: Ident) -> InternedString {
966 /// Is the current token one of the keywords that signals a bare function
968 pub fn token_is_bare_fn_keyword(&mut self) -> bool {
969 if token::is_keyword(keywords::Fn, &self.token) {
973 if token::is_keyword(keywords::Unsafe, &self.token) ||
974 token::is_keyword(keywords::Once, &self.token) {
975 return self.look_ahead(1, |t| token::is_keyword(keywords::Fn, t))
981 /// Is the current token one of the keywords that signals a closure type?
982 pub fn token_is_closure_keyword(&mut self) -> bool {
983 token::is_keyword(keywords::Unsafe, &self.token) ||
984 token::is_keyword(keywords::Once, &self.token)
987 /// Is the current token one of the keywords that signals an old-style
988 /// closure type (with explicit sigil)?
989 pub fn token_is_old_style_closure_keyword(&mut self) -> bool {
990 token::is_keyword(keywords::Unsafe, &self.token) ||
991 token::is_keyword(keywords::Once, &self.token) ||
992 token::is_keyword(keywords::Fn, &self.token)
995 pub fn token_is_lifetime(tok: &token::Token) -> bool {
997 token::LIFETIME(..) => true,
1002 pub fn get_lifetime(&mut self) -> ast::Ident {
1004 token::LIFETIME(ref ident) => *ident,
1005 _ => self.bug("not a lifetime"),
1009 /// parse a TyBareFn type:
1010 pub fn parse_ty_bare_fn(&mut self) -> Ty_ {
1013 [unsafe] [extern "ABI"] fn <'lt> (S) -> T
1014 ^~~~^ ^~~~^ ^~~~^ ^~^ ^
1017 | | | Argument types
1023 let fn_style = self.parse_unsafety();
1024 let abi = if self.eat_keyword(keywords::Extern) {
1025 self.parse_opt_abi().unwrap_or(abi::C)
1030 self.expect_keyword(keywords::Fn);
1031 let (decl, lifetimes) = self.parse_ty_fn_decl(true);
1032 return TyBareFn(box(GC) BareFnTy {
1035 lifetimes: lifetimes,
1040 /// Parses a procedure type (`proc`). The initial `proc` keyword must
1041 /// already have been parsed.
1042 pub fn parse_proc_type(&mut self) -> Ty_ {
1045 proc <'lt> (S) [:Bounds] -> T
1046 ^~~^ ^~~~^ ^ ^~~~~~~~^ ^
1056 let lifetimes = if self.eat(&token::LT) {
1057 let lifetimes = self.parse_lifetimes();
1064 let (inputs, variadic) = self.parse_fn_args(false, false);
1066 if self.eat(&token::COLON) {
1067 let (_, bounds) = self.parse_ty_param_bounds(false);
1073 let (ret_style, ret_ty) = self.parse_ret_ty();
1074 let decl = P(FnDecl {
1080 TyProc(box(GC) ClosureTy {
1085 lifetimes: lifetimes,
1089 /// Parse a TyClosure type
1090 pub fn parse_ty_closure(&mut self) -> Ty_ {
1093 [unsafe] [once] <'lt> |S| [:Bounds] -> T
1094 ^~~~~~~^ ^~~~~^ ^~~~^ ^ ^~~~~~~~^ ^
1096 | | | | | Return type
1097 | | | | Closure bounds
1098 | | | Argument types
1100 | Once-ness (a.k.a., affine)
1105 let fn_style = self.parse_unsafety();
1106 let onceness = if self.eat_keyword(keywords::Once) {Once} else {Many};
1108 let lifetimes = if self.eat(&token::LT) {
1109 let lifetimes = self.parse_lifetimes();
1117 let (is_unboxed, inputs) = if self.eat(&token::OROR) {
1122 let is_unboxed = self.token == token::BINOP(token::AND) &&
1123 self.look_ahead(1, |t| {
1124 token::is_keyword(keywords::Mut, t)
1126 self.look_ahead(2, |t| *t == token::COLON);
1133 let inputs = self.parse_seq_to_before_or(
1135 |p| p.parse_arg_general(false));
1137 (is_unboxed, inputs)
1140 let (region, bounds) = {
1141 if self.eat(&token::COLON) {
1142 let (region, bounds) = self.parse_ty_param_bounds(true);
1143 (region, Some(bounds))
1149 let (return_style, output) = self.parse_ret_ty();
1150 let decl = P(FnDecl {
1158 TyUnboxedFn(box(GC) UnboxedFnTy {
1162 TyClosure(box(GC) ClosureTy {
1167 lifetimes: lifetimes,
1172 pub fn parse_unsafety(&mut self) -> FnStyle {
1173 if self.eat_keyword(keywords::Unsafe) {
1180 /// Parse a function type (following the 'fn')
1181 pub fn parse_ty_fn_decl(&mut self, allow_variadic: bool)
1182 -> (P<FnDecl>, Vec<ast::Lifetime>) {
1193 let lifetimes = if self.eat(&token::LT) {
1194 let lifetimes = self.parse_lifetimes();
1201 let (inputs, variadic) = self.parse_fn_args(false, allow_variadic);
1202 let (ret_style, ret_ty) = self.parse_ret_ty();
1203 let decl = P(FnDecl {
1212 /// Parse the methods in a trait declaration
1213 pub fn parse_trait_methods(&mut self) -> Vec<TraitMethod> {
1214 self.parse_unspanned_seq(
1219 let attrs = p.parse_outer_attributes();
1222 // NB: at the moment, trait methods are public by default; this
1224 let vis = p.parse_visibility();
1225 let abi = if p.eat_keyword(keywords::Extern) {
1226 p.parse_opt_abi().unwrap_or(abi::C)
1227 } else if attr::contains_name(attrs.as_slice(),
1228 "rust_call_abi_hack") {
1229 // FIXME(stage0, pcwalton): Remove this awful hack after a
1230 // snapshot, and change to `extern "rust-call" fn`.
1235 let style = p.parse_fn_style();
1236 let ident = p.parse_ident();
1238 let generics = p.parse_generics();
1240 let (explicit_self, d) = p.parse_fn_decl_with_self(|p| {
1241 // This is somewhat dubious; We don't want to allow argument
1242 // names to be left off if there is a definition...
1243 p.parse_arg_general(false)
1246 let hi = p.last_span.hi;
1250 debug!("parse_trait_methods(): parsing required method");
1251 Required(TypeMethod {
1258 explicit_self: explicit_self,
1259 id: ast::DUMMY_NODE_ID,
1260 span: mk_sp(lo, hi),
1265 debug!("parse_trait_methods(): parsing provided method");
1266 let (inner_attrs, body) =
1267 p.parse_inner_attrs_and_block();
1268 let attrs = attrs.append(inner_attrs.as_slice());
1269 Provided(box(GC) ast::Method {
1271 id: ast::DUMMY_NODE_ID,
1272 span: mk_sp(lo, hi),
1273 node: ast::MethDecl(ident,
1285 let token_str = p.this_token_to_string();
1286 p.fatal((format!("expected `;` or `{{` but found `{}`",
1287 token_str)).as_slice())
1293 /// Parse a possibly mutable type
1294 pub fn parse_mt(&mut self) -> MutTy {
1295 let mutbl = self.parse_mutability();
1296 let t = self.parse_ty(true);
1297 MutTy { ty: t, mutbl: mutbl }
1300 /// Parse [mut/const/imm] ID : TY
1301 /// now used only by obsolete record syntax parser...
1302 pub fn parse_ty_field(&mut self) -> TypeField {
1303 let lo = self.span.lo;
1304 let mutbl = self.parse_mutability();
1305 let id = self.parse_ident();
1306 self.expect(&token::COLON);
1307 let ty = self.parse_ty(true);
1308 let hi = ty.span.hi;
1311 mt: MutTy { ty: ty, mutbl: mutbl },
1312 span: mk_sp(lo, hi),
1316 /// Parse optional return type [ -> TY ] in function decl
1317 pub fn parse_ret_ty(&mut self) -> (RetStyle, P<Ty>) {
1318 return if self.eat(&token::RARROW) {
1319 let lo = self.span.lo;
1320 if self.eat(&token::NOT) {
1324 id: ast::DUMMY_NODE_ID,
1326 span: mk_sp(lo, self.last_span.hi)
1330 (Return, self.parse_ty(true))
1333 let pos = self.span.lo;
1337 id: ast::DUMMY_NODE_ID,
1339 span: mk_sp(pos, pos),
1347 /// The second parameter specifies whether the `+` binary operator is
1348 /// allowed in the type grammar.
1349 pub fn parse_ty(&mut self, plus_allowed: bool) -> P<Ty> {
1350 maybe_whole!(no_clone self, NtTy);
1352 let lo = self.span.lo;
1354 let t = if self.token == token::LPAREN {
1356 if self.token == token::RPAREN {
1360 // (t) is a parenthesized ty
1361 // (t,) is the type of a tuple with only one field,
1363 let mut ts = vec!(self.parse_ty(true));
1364 let mut one_tuple = false;
1365 while self.token == token::COMMA {
1367 if self.token != token::RPAREN {
1368 ts.push(self.parse_ty(true));
1375 if ts.len() == 1 && !one_tuple {
1376 self.expect(&token::RPAREN);
1380 self.expect(&token::RPAREN);
1384 } else if self.token == token::AT {
1387 let span = self.last_span;
1388 self.obsolete(span, ObsoleteManagedType);
1389 TyBox(self.parse_ty(plus_allowed))
1390 } else if self.token == token::TILDE {
1393 let last_span = self.last_span;
1396 self.obsolete(last_span, ObsoleteOwnedVector),
1397 _ => self.obsolete(last_span, ObsoleteOwnedType),
1399 TyUniq(self.parse_ty(true))
1400 } else if self.token == token::BINOP(token::STAR) {
1401 // STAR POINTER (bare pointer?)
1403 TyPtr(self.parse_ptr())
1404 } else if self.token == token::LBRACKET {
1406 self.expect(&token::LBRACKET);
1407 let t = self.parse_ty(true);
1409 // Parse the `, ..e` in `[ int, ..e ]`
1410 // where `e` is a const expression
1411 let t = match self.maybe_parse_fixed_vstore() {
1413 Some(suffix) => TyFixedLengthVec(t, suffix)
1415 self.expect(&token::RBRACKET);
1417 } else if self.token == token::BINOP(token::AND) ||
1418 self.token == token::ANDAND {
1421 self.parse_borrowed_pointee()
1422 } else if self.is_keyword(keywords::Extern) ||
1423 self.is_keyword(keywords::Unsafe) ||
1424 self.token_is_bare_fn_keyword() {
1426 self.parse_ty_bare_fn()
1427 } else if self.token_is_closure_keyword() ||
1428 self.token == token::BINOP(token::OR) ||
1429 self.token == token::OROR ||
1430 self.token == token::LT {
1433 // FIXME(pcwalton): Eventually `token::LT` will not unambiguously
1434 // introduce a closure, once procs can have lifetime bounds. We
1435 // will need to refactor the grammar a little bit at that point.
1437 self.parse_ty_closure()
1438 } else if self.eat_keyword(keywords::Typeof) {
1440 // In order to not be ambiguous, the type must be surrounded by parens.
1441 self.expect(&token::LPAREN);
1442 let e = self.parse_expr();
1443 self.expect(&token::RPAREN);
1445 } else if self.eat_keyword(keywords::Proc) {
1446 self.parse_proc_type()
1447 } else if self.token == token::MOD_SEP
1448 || is_ident_or_path(&self.token) {
1450 let mode = if plus_allowed {
1451 LifetimeAndTypesAndBounds
1453 LifetimeAndTypesWithoutColons
1458 } = self.parse_path(mode);
1459 TyPath(path, bounds, ast::DUMMY_NODE_ID)
1460 } else if self.eat(&token::UNDERSCORE) {
1461 // TYPE TO BE INFERRED
1464 let msg = format!("expected type, found token {:?}", self.token);
1465 self.fatal(msg.as_slice());
1468 let sp = mk_sp(lo, self.last_span.hi);
1469 P(Ty {id: ast::DUMMY_NODE_ID, node: t, span: sp})
1472 pub fn parse_borrowed_pointee(&mut self) -> Ty_ {
1473 // look for `&'lt` or `&'foo ` and interpret `foo` as the region name:
1474 let opt_lifetime = self.parse_opt_lifetime();
1476 let mt = self.parse_mt();
1477 return TyRptr(opt_lifetime, mt);
1480 pub fn parse_ptr(&mut self) -> MutTy {
1481 let mutbl = if self.eat_keyword(keywords::Mut) {
1483 } else if self.eat_keyword(keywords::Const) {
1486 let span = self.last_span;
1488 "bare raw pointers are no longer allowed, you should \
1489 likely use `*mut T`, but otherwise `*T` is now \
1490 known as `*const T`");
1493 let t = self.parse_ty(true);
1494 MutTy { ty: t, mutbl: mutbl }
1497 pub fn is_named_argument(&mut self) -> bool {
1498 let offset = match self.token {
1499 token::BINOP(token::AND) => 1,
1501 _ if token::is_keyword(keywords::Mut, &self.token) => 1,
1505 debug!("parser is_named_argument offset:{}", offset);
1508 is_plain_ident_or_underscore(&self.token)
1509 && self.look_ahead(1, |t| *t == token::COLON)
1511 self.look_ahead(offset, |t| is_plain_ident_or_underscore(t))
1512 && self.look_ahead(offset + 1, |t| *t == token::COLON)
1516 /// This version of parse arg doesn't necessarily require
1517 /// identifier names.
1518 pub fn parse_arg_general(&mut self, require_name: bool) -> Arg {
1519 let pat = if require_name || self.is_named_argument() {
1520 debug!("parse_arg_general parse_pat (require_name:{:?})",
1522 let pat = self.parse_pat();
1524 self.expect(&token::COLON);
1527 debug!("parse_arg_general ident_to_pat");
1528 ast_util::ident_to_pat(ast::DUMMY_NODE_ID,
1530 special_idents::invalid)
1533 let t = self.parse_ty(true);
1538 id: ast::DUMMY_NODE_ID,
1542 /// Parse a single function argument
1543 pub fn parse_arg(&mut self) -> Arg {
1544 self.parse_arg_general(true)
1547 /// Parse an argument in a lambda header e.g. |arg, arg|
1548 pub fn parse_fn_block_arg(&mut self) -> Arg {
1549 let pat = self.parse_pat();
1550 let t = if self.eat(&token::COLON) {
1554 id: ast::DUMMY_NODE_ID,
1556 span: mk_sp(self.span.lo, self.span.hi),
1562 id: ast::DUMMY_NODE_ID
1566 pub fn maybe_parse_fixed_vstore(&mut self) -> Option<Gc<ast::Expr>> {
1567 if self.token == token::COMMA &&
1568 self.look_ahead(1, |t| *t == token::DOTDOT) {
1571 Some(self.parse_expr())
1577 /// Matches token_lit = LIT_INTEGER | ...
1578 pub fn lit_from_token(&mut self, tok: &token::Token) -> Lit_ {
1580 token::LIT_BYTE(i) => LitByte(parse::byte_lit(i.as_str()).val0()),
1581 token::LIT_CHAR(i) => LitChar(parse::char_lit(i.as_str()).val0()),
1582 token::LIT_INTEGER(s) => parse::integer_lit(s.as_str(),
1583 &self.sess.span_diagnostic, self.span),
1584 token::LIT_FLOAT(s) => parse::float_lit(s.as_str()),
1585 token::LIT_STR(s) => {
1586 LitStr(token::intern_and_get_ident(parse::str_lit(s.as_str()).as_slice()),
1589 token::LIT_STR_RAW(s, n) => {
1590 LitStr(token::intern_and_get_ident(parse::raw_str_lit(s.as_str()).as_slice()),
1593 token::LIT_BINARY(i) =>
1594 LitBinary(parse::binary_lit(i.as_str())),
1595 token::LIT_BINARY_RAW(i, _) =>
1596 LitBinary(Rc::new(i.as_str().as_bytes().iter().map(|&x| x).collect())),
1597 token::LPAREN => { self.expect(&token::RPAREN); LitNil },
1598 _ => { self.unexpected_last(tok); }
1602 /// Matches lit = true | false | token_lit
1603 pub fn parse_lit(&mut self) -> Lit {
1604 let lo = self.span.lo;
1605 let lit = if self.eat_keyword(keywords::True) {
1607 } else if self.eat_keyword(keywords::False) {
1610 let token = self.bump_and_get();
1611 let lit = self.lit_from_token(&token);
1614 codemap::Spanned { node: lit, span: mk_sp(lo, self.last_span.hi) }
1617 /// matches '-' lit | lit
1618 pub fn parse_literal_maybe_minus(&mut self) -> Gc<Expr> {
1619 let minus_lo = self.span.lo;
1620 let minus_present = self.eat(&token::BINOP(token::MINUS));
1622 let lo = self.span.lo;
1623 let literal = box(GC) self.parse_lit();
1624 let hi = self.span.hi;
1625 let expr = self.mk_expr(lo, hi, ExprLit(literal));
1628 let minus_hi = self.span.hi;
1629 let unary = self.mk_unary(UnNeg, expr);
1630 self.mk_expr(minus_lo, minus_hi, unary)
1636 /// Parses a path and optional type parameter bounds, depending on the
1637 /// mode. The `mode` parameter determines whether lifetimes, types, and/or
1638 /// bounds are permitted and whether `::` must precede type parameter
1640 pub fn parse_path(&mut self, mode: PathParsingMode) -> PathAndBounds {
1641 // Check for a whole path...
1642 let found = match self.token {
1643 INTERPOLATED(token::NtPath(_)) => Some(self.bump_and_get()),
1647 Some(INTERPOLATED(token::NtPath(box path))) => {
1648 return PathAndBounds {
1656 let lo = self.span.lo;
1657 let is_global = self.eat(&token::MOD_SEP);
1659 // Parse any number of segments and bound sets. A segment is an
1660 // identifier followed by an optional lifetime and a set of types.
1661 // A bound set is a set of type parameter bounds.
1662 let mut segments = Vec::new();
1664 // First, parse an identifier.
1665 let identifier = self.parse_ident();
1667 // Parse the '::' before type parameters if it's required. If
1668 // it is required and wasn't present, then we're done.
1669 if mode == LifetimeAndTypesWithColons &&
1670 !self.eat(&token::MOD_SEP) {
1671 segments.push(ast::PathSegment {
1672 identifier: identifier,
1673 lifetimes: Vec::new(),
1674 types: OwnedSlice::empty(),
1679 // Parse the `<` before the lifetime and types, if applicable.
1680 let (any_lifetime_or_types, lifetimes, types) = {
1681 if mode != NoTypesAllowed && self.eat_lt(false) {
1682 let (lifetimes, types) =
1683 self.parse_generic_values_after_lt();
1684 (true, lifetimes, OwnedSlice::from_vec(types))
1686 (false, Vec::new(), OwnedSlice::empty())
1690 // Assemble and push the result.
1691 segments.push(ast::PathSegment {
1692 identifier: identifier,
1693 lifetimes: lifetimes,
1697 // We're done if we don't see a '::', unless the mode required
1698 // a double colon to get here in the first place.
1699 if !(mode == LifetimeAndTypesWithColons &&
1700 !any_lifetime_or_types) {
1701 if !self.eat(&token::MOD_SEP) {
1707 // Next, parse a plus and bounded type parameters, if applicable.
1708 let bounds = if mode == LifetimeAndTypesAndBounds {
1710 if self.eat(&token::BINOP(token::PLUS)) {
1711 let (_, bounds) = self.parse_ty_param_bounds(false);
1712 if bounds.len() == 0 {
1713 let last_span = self.last_span;
1714 self.span_err(last_span,
1715 "at least one type parameter bound \
1716 must be specified after the `+`");
1728 // Assemble the span.
1729 let span = mk_sp(lo, self.last_span.hi);
1731 // Assemble the result.
1742 /// parses 0 or 1 lifetime
1743 pub fn parse_opt_lifetime(&mut self) -> Option<ast::Lifetime> {
1745 token::LIFETIME(..) => {
1746 Some(self.parse_lifetime())
1754 /// Parses a single lifetime
1755 /// Matches lifetime = LIFETIME
1756 pub fn parse_lifetime(&mut self) -> ast::Lifetime {
1758 token::LIFETIME(i) => {
1759 let span = self.span;
1761 return ast::Lifetime {
1762 id: ast::DUMMY_NODE_ID,
1768 self.fatal(format!("expected a lifetime name").as_slice());
1773 // matches lifetimes = ( lifetime ) | ( lifetime , lifetimes )
1774 // actually, it matches the empty one too, but putting that in there
1775 // messes up the grammar....
1776 pub fn parse_lifetimes(&mut self) -> Vec<ast::Lifetime> {
1779 * Parses zero or more comma separated lifetimes.
1780 * Expects each lifetime to be followed by either
1781 * a comma or `>`. Used when parsing type parameter
1782 * lists, where we expect something like `<'a, 'b, T>`.
1785 let mut res = Vec::new();
1788 token::LIFETIME(_) => {
1789 res.push(self.parse_lifetime());
1797 token::COMMA => { self.bump();}
1798 token::GT => { return res; }
1799 token::BINOP(token::SHR) => { return res; }
1801 let msg = format!("expected `,` or `>` after lifetime \
1804 self.fatal(msg.as_slice());
1810 pub fn token_is_mutability(tok: &token::Token) -> bool {
1811 token::is_keyword(keywords::Mut, tok) ||
1812 token::is_keyword(keywords::Const, tok)
1815 /// Parse mutability declaration (mut/const/imm)
1816 pub fn parse_mutability(&mut self) -> Mutability {
1817 if self.eat_keyword(keywords::Mut) {
1824 /// Parse ident COLON expr
1825 pub fn parse_field(&mut self) -> Field {
1826 let lo = self.span.lo;
1827 let i = self.parse_ident();
1828 let hi = self.last_span.hi;
1829 self.expect(&token::COLON);
1830 let e = self.parse_expr();
1832 ident: spanned(lo, hi, i),
1834 span: mk_sp(lo, e.span.hi),
1838 pub fn mk_expr(&mut self, lo: BytePos, hi: BytePos, node: Expr_) -> Gc<Expr> {
1840 id: ast::DUMMY_NODE_ID,
1842 span: mk_sp(lo, hi),
1846 pub fn mk_unary(&mut self, unop: ast::UnOp, expr: Gc<Expr>) -> ast::Expr_ {
1847 ExprUnary(unop, expr)
1850 pub fn mk_binary(&mut self, binop: ast::BinOp,
1851 lhs: Gc<Expr>, rhs: Gc<Expr>) -> ast::Expr_ {
1852 ExprBinary(binop, lhs, rhs)
1855 pub fn mk_call(&mut self, f: Gc<Expr>, args: Vec<Gc<Expr>>) -> ast::Expr_ {
1859 fn mk_method_call(&mut self,
1860 ident: ast::SpannedIdent,
1862 args: Vec<Gc<Expr>>)
1864 ExprMethodCall(ident, tps, args)
1867 pub fn mk_index(&mut self, expr: Gc<Expr>, idx: Gc<Expr>) -> ast::Expr_ {
1868 ExprIndex(expr, idx)
1871 pub fn mk_field(&mut self, expr: Gc<Expr>, ident: ast::SpannedIdent,
1872 tys: Vec<P<Ty>>) -> ast::Expr_ {
1873 ExprField(expr, ident, tys)
1876 pub fn mk_assign_op(&mut self, binop: ast::BinOp,
1877 lhs: Gc<Expr>, rhs: Gc<Expr>) -> ast::Expr_ {
1878 ExprAssignOp(binop, lhs, rhs)
1881 pub fn mk_mac_expr(&mut self, lo: BytePos, hi: BytePos, m: Mac_) -> Gc<Expr> {
1883 id: ast::DUMMY_NODE_ID,
1884 node: ExprMac(codemap::Spanned {node: m, span: mk_sp(lo, hi)}),
1885 span: mk_sp(lo, hi),
1889 pub fn mk_lit_u32(&mut self, i: u32) -> Gc<Expr> {
1890 let span = &self.span;
1891 let lv_lit = box(GC) codemap::Spanned {
1892 node: LitUint(i as u64, TyU32),
1897 id: ast::DUMMY_NODE_ID,
1898 node: ExprLit(lv_lit),
1903 /// At the bottom (top?) of the precedence hierarchy,
1904 /// parse things like parenthesized exprs,
1905 /// macros, return, etc.
1906 pub fn parse_bottom_expr(&mut self) -> Gc<Expr> {
1907 maybe_whole_expr!(self);
1909 let lo = self.span.lo;
1910 let mut hi = self.span.hi;
1917 // (e) is parenthesized e
1918 // (e,) is a tuple with only one field, e
1919 let mut trailing_comma = false;
1920 if self.token == token::RPAREN {
1923 let lit = box(GC) spanned(lo, hi, LitNil);
1924 return self.mk_expr(lo, hi, ExprLit(lit));
1926 let mut es = vec!(self.parse_expr());
1927 self.commit_expr(*es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]);
1928 while self.token == token::COMMA {
1930 if self.token != token::RPAREN {
1931 es.push(self.parse_expr());
1932 self.commit_expr(*es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]);
1935 trailing_comma = true;
1939 self.commit_expr_expecting(*es.last().unwrap(), token::RPAREN);
1941 return if es.len() == 1 && !trailing_comma {
1942 self.mk_expr(lo, hi, ExprParen(*es.get(0)))
1945 self.mk_expr(lo, hi, ExprTup(es))
1950 let blk = self.parse_block_tail(lo, DefaultBlock);
1951 return self.mk_expr(blk.span.lo, blk.span.hi,
1954 token::BINOP(token::OR) | token::OROR => {
1955 return self.parse_lambda_expr();
1957 // FIXME #13626: Should be able to stick in
1958 // token::SELF_KEYWORD_NAME
1959 token::IDENT(id @ ast::Ident{
1960 name: ast::Name(token::SELF_KEYWORD_NAME_NUM),
1964 let path = ast_util::ident_to_path(mk_sp(lo, hi), id);
1965 ex = ExprPath(path);
1966 hi = self.last_span.hi;
1968 token::LBRACKET => {
1971 if self.token == token::RBRACKET {
1974 ex = ExprVec(Vec::new());
1977 let first_expr = self.parse_expr();
1978 if self.token == token::COMMA &&
1979 self.look_ahead(1, |t| *t == token::DOTDOT) {
1980 // Repeating vector syntax: [ 0, ..512 ]
1983 let count = self.parse_expr();
1984 self.expect(&token::RBRACKET);
1985 ex = ExprRepeat(first_expr, count);
1986 } else if self.token == token::COMMA {
1987 // Vector with two or more elements.
1989 let remaining_exprs = self.parse_seq_to_end(
1991 seq_sep_trailing_allowed(token::COMMA),
1994 let mut exprs = vec!(first_expr);
1995 exprs.push_all_move(remaining_exprs);
1996 ex = ExprVec(exprs);
1998 // Vector with one element.
1999 self.expect(&token::RBRACKET);
2000 ex = ExprVec(vec!(first_expr));
2003 hi = self.last_span.hi;
2006 if self.eat_keyword(keywords::Proc) {
2007 let decl = self.parse_proc_decl();
2008 let body = self.parse_expr();
2009 let fakeblock = P(ast::Block {
2010 view_items: Vec::new(),
2013 id: ast::DUMMY_NODE_ID,
2014 rules: DefaultBlock,
2017 return self.mk_expr(lo, body.span.hi, ExprProc(decl, fakeblock));
2019 if self.eat_keyword(keywords::If) {
2020 return self.parse_if_expr();
2022 if self.eat_keyword(keywords::For) {
2023 return self.parse_for_expr(None);
2025 if self.eat_keyword(keywords::While) {
2026 return self.parse_while_expr();
2028 if Parser::token_is_lifetime(&self.token) {
2029 let lifetime = self.get_lifetime();
2031 self.expect(&token::COLON);
2032 if self.eat_keyword(keywords::For) {
2033 return self.parse_for_expr(Some(lifetime))
2035 if self.eat_keyword(keywords::Loop) {
2036 return self.parse_loop_expr(Some(lifetime))
2038 self.fatal("expected `for` or `loop` after a label")
2040 if self.eat_keyword(keywords::Loop) {
2041 return self.parse_loop_expr(None);
2043 if self.eat_keyword(keywords::Continue) {
2044 let lo = self.span.lo;
2045 let ex = if Parser::token_is_lifetime(&self.token) {
2046 let lifetime = self.get_lifetime();
2048 ExprAgain(Some(lifetime))
2052 let hi = self.span.hi;
2053 return self.mk_expr(lo, hi, ex);
2055 if self.eat_keyword(keywords::Match) {
2056 return self.parse_match_expr();
2058 if self.eat_keyword(keywords::Unsafe) {
2059 return self.parse_block_expr(
2061 UnsafeBlock(ast::UserProvided));
2063 if self.eat_keyword(keywords::Return) {
2064 // RETURN expression
2065 if can_begin_expr(&self.token) {
2066 let e = self.parse_expr();
2068 ex = ExprRet(Some(e));
2072 } else if self.eat_keyword(keywords::Break) {
2074 if Parser::token_is_lifetime(&self.token) {
2075 let lifetime = self.get_lifetime();
2077 ex = ExprBreak(Some(lifetime));
2079 ex = ExprBreak(None);
2082 } else if self.token == token::MOD_SEP ||
2083 is_ident(&self.token) &&
2084 !self.is_keyword(keywords::True) &&
2085 !self.is_keyword(keywords::False) {
2087 self.parse_path(LifetimeAndTypesWithColons).path;
2089 // `!`, as an operator, is prefix, so we know this isn't that
2090 if self.token == token::NOT {
2091 // MACRO INVOCATION expression
2094 let ket = token::close_delimiter_for(&self.token)
2095 .unwrap_or_else(|| {
2096 self.fatal("expected open delimiter")
2100 let tts = self.parse_seq_to_end(
2103 |p| p.parse_token_tree());
2104 let hi = self.span.hi;
2106 return self.mk_mac_expr(lo,
2112 if self.token == token::LBRACE {
2113 // This is a struct literal, unless we're prohibited
2114 // from parsing struct literals here.
2115 if self.restriction != RESTRICT_NO_STRUCT_LITERAL {
2116 // It's a struct literal.
2118 let mut fields = Vec::new();
2119 let mut base = None;
2121 while self.token != token::RBRACE {
2122 if self.eat(&token::DOTDOT) {
2123 base = Some(self.parse_expr());
2127 fields.push(self.parse_field());
2128 self.commit_expr(fields.last().unwrap().expr,
2133 if fields.len() == 0 && base.is_none() {
2134 let last_span = self.last_span;
2135 self.span_err(last_span,
2136 "structure literal must either \
2137 have at least one field or use \
2138 functional structure update \
2143 self.expect(&token::RBRACE);
2144 ex = ExprStruct(pth, fields, base);
2145 return self.mk_expr(lo, hi, ex);
2152 // other literal expression
2153 let lit = self.parse_lit();
2155 ex = ExprLit(box(GC) lit);
2160 return self.mk_expr(lo, hi, ex);
2163 /// Parse a block or unsafe block
2164 pub fn parse_block_expr(&mut self, lo: BytePos, blk_mode: BlockCheckMode)
2166 self.expect(&token::LBRACE);
2167 let blk = self.parse_block_tail(lo, blk_mode);
2168 return self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk));
2171 /// parse a.b or a(13) or a[4] or just a
2172 pub fn parse_dot_or_call_expr(&mut self) -> Gc<Expr> {
2173 let b = self.parse_bottom_expr();
2174 self.parse_dot_or_call_expr_with(b)
2177 pub fn parse_dot_or_call_expr_with(&mut self, e0: Gc<Expr>) -> Gc<Expr> {
2183 if self.eat(&token::DOT) {
2185 token::IDENT(i, _) => {
2186 let dot = self.last_span.hi;
2189 let (_, tys) = if self.eat(&token::MOD_SEP) {
2191 self.parse_generic_values_after_lt()
2193 (Vec::new(), Vec::new())
2196 // expr.f() method call
2199 let mut es = self.parse_unspanned_seq(
2202 seq_sep_trailing_disallowed(token::COMMA),
2205 hi = self.last_span.hi;
2208 let id = spanned(dot, hi, i);
2209 let nd = self.mk_method_call(id, tys, es);
2210 e = self.mk_expr(lo, hi, nd);
2213 let id = spanned(dot, hi, i);
2214 let field = self.mk_field(e, id, tys);
2215 e = self.mk_expr(lo, hi, field)
2219 _ => self.unexpected()
2223 if self.expr_is_complete(e) { break; }
2227 let es = self.parse_unspanned_seq(
2230 seq_sep_trailing_allowed(token::COMMA),
2233 hi = self.last_span.hi;
2235 let nd = self.mk_call(e, es);
2236 e = self.mk_expr(lo, hi, nd);
2240 token::LBRACKET => {
2242 let ix = self.parse_expr();
2244 self.commit_expr_expecting(ix, token::RBRACKET);
2245 let index = self.mk_index(e, ix);
2246 e = self.mk_expr(lo, hi, index)
2255 /// Parse an optional separator followed by a kleene-style
2256 /// repetition token (+ or *).
2257 pub fn parse_sep_and_zerok(&mut self) -> (Option<token::Token>, bool) {
2258 fn parse_zerok(parser: &mut Parser) -> Option<bool> {
2259 match parser.token {
2260 token::BINOP(token::STAR) | token::BINOP(token::PLUS) => {
2261 let zerok = parser.token == token::BINOP(token::STAR);
2269 match parse_zerok(self) {
2270 Some(zerok) => return (None, zerok),
2274 let separator = self.bump_and_get();
2275 match parse_zerok(self) {
2276 Some(zerok) => (Some(separator), zerok),
2277 None => self.fatal("expected `*` or `+`")
2281 /// parse a single token tree from the input.
2282 pub fn parse_token_tree(&mut self) -> TokenTree {
2283 // FIXME #6994: currently, this is too eager. It
2284 // parses token trees but also identifies TTSeq's
2285 // and TTNonterminal's; it's too early to know yet
2286 // whether something will be a nonterminal or a seq
2288 maybe_whole!(deref self, NtTT);
2290 // this is the fall-through for the 'match' below.
2291 // invariants: the current token is not a left-delimiter,
2292 // not an EOF, and not the desired right-delimiter (if
2293 // it were, parse_seq_to_before_end would have prevented
2294 // reaching this point.
2295 fn parse_non_delim_tt_tok(p: &mut Parser) -> TokenTree {
2296 maybe_whole!(deref p, NtTT);
2298 token::RPAREN | token::RBRACE | token::RBRACKET => {
2299 // This is a conservative error: only report the last unclosed delimiter. The
2300 // previous unclosed delimiters could actually be closed! The parser just hasn't
2301 // gotten to them yet.
2302 match p.open_braces.last() {
2304 Some(&sp) => p.span_note(sp, "unclosed delimiter"),
2306 let token_str = p.this_token_to_string();
2307 p.fatal(format!("incorrect close delimiter: `{}`",
2308 token_str).as_slice())
2310 /* we ought to allow different depths of unquotation */
2311 token::DOLLAR if p.quote_depth > 0u => {
2315 if p.token == token::LPAREN {
2316 let seq = p.parse_seq(
2320 |p| p.parse_token_tree()
2322 let (s, z) = p.parse_sep_and_zerok();
2323 let seq = match seq {
2324 Spanned { node, .. } => node,
2326 TTSeq(mk_sp(sp.lo, p.span.hi), Rc::new(seq), s, z)
2328 TTNonterminal(sp, p.parse_ident())
2337 // turn the next token into a TTTok:
2338 fn parse_any_tt_tok(p: &mut Parser) -> TokenTree {
2339 TTTok(p.span, p.bump_and_get())
2342 match (&self.token, token::close_delimiter_for(&self.token)) {
2343 (&token::EOF, _) => {
2344 let open_braces = self.open_braces.clone();
2345 for sp in open_braces.iter() {
2346 self.span_note(*sp, "Did you mean to close this delimiter?");
2348 // There shouldn't really be a span, but it's easier for the test runner
2349 // if we give it one
2350 self.fatal("this file contains an un-closed delimiter ");
2352 (_, Some(close_delim)) => {
2353 // Parse the open delimiter.
2354 self.open_braces.push(self.span);
2355 let mut result = vec!(parse_any_tt_tok(self));
2358 self.parse_seq_to_before_end(&close_delim,
2360 |p| p.parse_token_tree());
2361 result.push_all_move(trees);
2363 // Parse the close delimiter.
2364 result.push(parse_any_tt_tok(self));
2365 self.open_braces.pop().unwrap();
2367 TTDelim(Rc::new(result))
2369 _ => parse_non_delim_tt_tok(self)
2373 // parse a stream of tokens into a list of TokenTree's,
2375 pub fn parse_all_token_trees(&mut self) -> Vec<TokenTree> {
2376 let mut tts = Vec::new();
2377 while self.token != token::EOF {
2378 tts.push(self.parse_token_tree());
2383 pub fn parse_matchers(&mut self) -> Vec<Matcher> {
2384 // unification of Matcher's and TokenTree's would vastly improve
2385 // the interpolation of Matcher's
2386 maybe_whole!(self, NtMatchers);
2387 let mut name_idx = 0u;
2388 match token::close_delimiter_for(&self.token) {
2389 Some(other_delimiter) => {
2391 self.parse_matcher_subseq_upto(&mut name_idx, &other_delimiter)
2393 None => self.fatal("expected open delimiter")
2397 /// This goofy function is necessary to correctly match parens in Matcher's.
2398 /// Otherwise, `$( ( )` would be a valid Matcher, and `$( () )` would be
2399 /// invalid. It's similar to common::parse_seq.
2400 pub fn parse_matcher_subseq_upto(&mut self,
2401 name_idx: &mut uint,
2404 let mut ret_val = Vec::new();
2405 let mut lparens = 0u;
2407 while self.token != *ket || lparens > 0u {
2408 if self.token == token::LPAREN { lparens += 1u; }
2409 if self.token == token::RPAREN { lparens -= 1u; }
2410 ret_val.push(self.parse_matcher(name_idx));
2418 pub fn parse_matcher(&mut self, name_idx: &mut uint) -> Matcher {
2419 let lo = self.span.lo;
2421 let m = if self.token == token::DOLLAR {
2423 if self.token == token::LPAREN {
2424 let name_idx_lo = *name_idx;
2426 let ms = self.parse_matcher_subseq_upto(name_idx,
2429 self.fatal("repetition body must be nonempty");
2431 let (sep, zerok) = self.parse_sep_and_zerok();
2432 MatchSeq(ms, sep, zerok, name_idx_lo, *name_idx)
2434 let bound_to = self.parse_ident();
2435 self.expect(&token::COLON);
2436 let nt_name = self.parse_ident();
2437 let m = MatchNonterminal(bound_to, nt_name, *name_idx);
2442 MatchTok(self.bump_and_get())
2445 return spanned(lo, self.span.hi, m);
2448 /// Parse a prefix-operator expr
2449 pub fn parse_prefix_expr(&mut self) -> Gc<Expr> {
2450 let lo = self.span.lo;
2457 let e = self.parse_prefix_expr();
2459 ex = self.mk_unary(UnNot, e);
2461 token::BINOP(token::MINUS) => {
2463 let e = self.parse_prefix_expr();
2465 ex = self.mk_unary(UnNeg, e);
2467 token::BINOP(token::STAR) => {
2469 let e = self.parse_prefix_expr();
2471 ex = self.mk_unary(UnDeref, e);
2473 token::BINOP(token::AND) | token::ANDAND => {
2475 let m = self.parse_mutability();
2476 let e = self.parse_prefix_expr();
2478 // HACK: turn &[...] into a &-vec
2480 ExprVec(..) if m == MutImmutable => {
2481 ExprVstore(e, ExprVstoreSlice)
2483 ExprVec(..) if m == MutMutable => {
2484 ExprVstore(e, ExprVstoreMutSlice)
2486 _ => ExprAddrOf(m, e)
2491 let span = self.last_span;
2492 self.obsolete(span, ObsoleteManagedExpr);
2493 let e = self.parse_prefix_expr();
2495 ex = self.mk_unary(UnBox, e);
2500 let e = self.parse_prefix_expr();
2502 // HACK: turn ~[...] into a ~-vec
2503 let last_span = self.last_span;
2505 ExprVec(..) | ExprRepeat(..) => {
2506 self.obsolete(last_span, ObsoleteOwnedVector);
2507 ExprVstore(e, ExprVstoreUniq)
2509 ExprLit(lit) if lit_is_str(lit) => {
2510 self.obsolete(last_span, ObsoleteOwnedExpr);
2511 ExprVstore(e, ExprVstoreUniq)
2514 self.obsolete(last_span, ObsoleteOwnedExpr);
2515 self.mk_unary(UnUniq, e)
2519 token::IDENT(_, _) => {
2520 if self.is_keyword(keywords::Box) {
2523 // Check for a place: `box(PLACE) EXPR`.
2524 if self.eat(&token::LPAREN) {
2525 // Support `box() EXPR` as the default.
2526 if !self.eat(&token::RPAREN) {
2527 let place = self.parse_expr();
2528 self.expect(&token::RPAREN);
2529 let subexpression = self.parse_prefix_expr();
2530 hi = subexpression.span.hi;
2531 ex = ExprBox(place, subexpression);
2532 return self.mk_expr(lo, hi, ex);
2536 // Otherwise, we use the unique pointer default.
2537 let subexpression = self.parse_prefix_expr();
2538 hi = subexpression.span.hi;
2539 // HACK: turn `box [...]` into a boxed-vec
2540 ex = match subexpression.node {
2541 ExprVec(..) | ExprRepeat(..) => {
2542 let last_span = self.last_span;
2543 self.obsolete(last_span, ObsoleteOwnedVector);
2544 ExprVstore(subexpression, ExprVstoreUniq)
2546 ExprLit(lit) if lit_is_str(lit) => {
2547 ExprVstore(subexpression, ExprVstoreUniq)
2549 _ => self.mk_unary(UnUniq, subexpression)
2552 return self.parse_dot_or_call_expr()
2555 _ => return self.parse_dot_or_call_expr()
2557 return self.mk_expr(lo, hi, ex);
2560 /// Parse an expression of binops
2561 pub fn parse_binops(&mut self) -> Gc<Expr> {
2562 let prefix_expr = self.parse_prefix_expr();
2563 self.parse_more_binops(prefix_expr, 0)
2566 /// Parse an expression of binops of at least min_prec precedence
2567 pub fn parse_more_binops(&mut self, lhs: Gc<Expr>,
2568 min_prec: uint) -> Gc<Expr> {
2569 if self.expr_is_complete(lhs) { return lhs; }
2571 // Prevent dynamic borrow errors later on by limiting the
2572 // scope of the borrows.
2574 let token: &token::Token = &self.token;
2575 let restriction: &restriction = &self.restriction;
2576 match (token, restriction) {
2577 (&token::BINOP(token::OR), &RESTRICT_NO_BAR_OP) => return lhs,
2578 (&token::BINOP(token::OR),
2579 &RESTRICT_NO_BAR_OR_DOUBLEBAR_OP) => return lhs,
2580 (&token::OROR, &RESTRICT_NO_BAR_OR_DOUBLEBAR_OP) => return lhs,
2585 let cur_opt = token_to_binop(&self.token);
2588 let cur_prec = operator_prec(cur_op);
2589 if cur_prec > min_prec {
2591 let expr = self.parse_prefix_expr();
2592 let rhs = self.parse_more_binops(expr, cur_prec);
2593 let binary = self.mk_binary(cur_op, lhs, rhs);
2594 let bin = self.mk_expr(lhs.span.lo, rhs.span.hi, binary);
2595 self.parse_more_binops(bin, min_prec)
2601 if as_prec > min_prec && self.eat_keyword(keywords::As) {
2602 let rhs = self.parse_ty(false);
2603 let _as = self.mk_expr(lhs.span.lo,
2605 ExprCast(lhs, rhs));
2606 self.parse_more_binops(_as, min_prec)
2614 /// Parse an assignment expression....
2615 /// actually, this seems to be the main entry point for
2616 /// parsing an arbitrary expression.
2617 pub fn parse_assign_expr(&mut self) -> Gc<Expr> {
2618 let lo = self.span.lo;
2619 let lhs = self.parse_binops();
2623 let rhs = self.parse_expr();
2624 self.mk_expr(lo, rhs.span.hi, ExprAssign(lhs, rhs))
2626 token::BINOPEQ(op) => {
2628 let rhs = self.parse_expr();
2629 let aop = match op {
2630 token::PLUS => BiAdd,
2631 token::MINUS => BiSub,
2632 token::STAR => BiMul,
2633 token::SLASH => BiDiv,
2634 token::PERCENT => BiRem,
2635 token::CARET => BiBitXor,
2636 token::AND => BiBitAnd,
2637 token::OR => BiBitOr,
2638 token::SHL => BiShl,
2641 let assign_op = self.mk_assign_op(aop, lhs, rhs);
2642 self.mk_expr(lo, rhs.span.hi, assign_op)
2650 /// Parse an 'if' expression ('if' token already eaten)
2651 pub fn parse_if_expr(&mut self) -> Gc<Expr> {
2652 let lo = self.last_span.lo;
2653 let cond = self.parse_expr_res(RESTRICT_NO_STRUCT_LITERAL);
2654 let thn = self.parse_block();
2655 let mut els: Option<Gc<Expr>> = None;
2656 let mut hi = thn.span.hi;
2657 if self.eat_keyword(keywords::Else) {
2658 let elexpr = self.parse_else_expr();
2660 hi = elexpr.span.hi;
2662 self.mk_expr(lo, hi, ExprIf(cond, thn, els))
2666 pub fn parse_lambda_expr(&mut self) -> Gc<Expr> {
2667 let lo = self.span.lo;
2668 let (decl, is_unboxed) = self.parse_fn_block_decl();
2669 let body = self.parse_expr();
2670 let fakeblock = P(ast::Block {
2671 view_items: Vec::new(),
2674 id: ast::DUMMY_NODE_ID,
2675 rules: DefaultBlock,
2680 self.mk_expr(lo, body.span.hi, ExprUnboxedFn(decl, fakeblock))
2682 self.mk_expr(lo, body.span.hi, ExprFnBlock(decl, fakeblock))
2686 pub fn parse_else_expr(&mut self) -> Gc<Expr> {
2687 if self.eat_keyword(keywords::If) {
2688 return self.parse_if_expr();
2690 let blk = self.parse_block();
2691 return self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk));
2695 /// Parse a 'for' .. 'in' expression ('for' token already eaten)
2696 pub fn parse_for_expr(&mut self, opt_ident: Option<ast::Ident>) -> Gc<Expr> {
2697 // Parse: `for <src_pat> in <src_expr> <src_loop_block>`
2699 let lo = self.last_span.lo;
2700 let pat = self.parse_pat();
2701 self.expect_keyword(keywords::In);
2702 let expr = self.parse_expr_res(RESTRICT_NO_STRUCT_LITERAL);
2703 let loop_block = self.parse_block();
2704 let hi = self.span.hi;
2706 self.mk_expr(lo, hi, ExprForLoop(pat, expr, loop_block, opt_ident))
2709 pub fn parse_while_expr(&mut self) -> Gc<Expr> {
2710 let lo = self.last_span.lo;
2711 let cond = self.parse_expr_res(RESTRICT_NO_STRUCT_LITERAL);
2712 let body = self.parse_block();
2713 let hi = body.span.hi;
2714 return self.mk_expr(lo, hi, ExprWhile(cond, body));
2717 pub fn parse_loop_expr(&mut self, opt_ident: Option<ast::Ident>) -> Gc<Expr> {
2718 let lo = self.last_span.lo;
2719 let body = self.parse_block();
2720 let hi = body.span.hi;
2721 self.mk_expr(lo, hi, ExprLoop(body, opt_ident))
2724 fn parse_match_expr(&mut self) -> Gc<Expr> {
2725 let lo = self.last_span.lo;
2726 let discriminant = self.parse_expr_res(RESTRICT_NO_STRUCT_LITERAL);
2727 self.commit_expr_expecting(discriminant, token::LBRACE);
2728 let mut arms: Vec<Arm> = Vec::new();
2729 while self.token != token::RBRACE {
2730 arms.push(self.parse_arm());
2732 let hi = self.span.hi;
2734 return self.mk_expr(lo, hi, ExprMatch(discriminant, arms));
2737 pub fn parse_arm(&mut self) -> Arm {
2738 let attrs = self.parse_outer_attributes();
2739 let pats = self.parse_pats();
2740 let mut guard = None;
2741 if self.eat_keyword(keywords::If) {
2742 guard = Some(self.parse_expr());
2744 self.expect(&token::FAT_ARROW);
2745 let expr = self.parse_expr_res(RESTRICT_STMT_EXPR);
2748 !classify::expr_is_simple_block(expr)
2749 && self.token != token::RBRACE;
2752 self.commit_expr(expr, &[token::COMMA], &[token::RBRACE]);
2754 self.eat(&token::COMMA);
2765 /// Parse an expression
2766 pub fn parse_expr(&mut self) -> Gc<Expr> {
2767 return self.parse_expr_res(UNRESTRICTED);
2770 /// Parse an expression, subject to the given restriction
2771 pub fn parse_expr_res(&mut self, r: restriction) -> Gc<Expr> {
2772 let old = self.restriction;
2773 self.restriction = r;
2774 let e = self.parse_assign_expr();
2775 self.restriction = old;
2779 /// Parse the RHS of a local variable declaration (e.g. '= 14;')
2780 fn parse_initializer(&mut self) -> Option<Gc<Expr>> {
2781 if self.token == token::EQ {
2783 Some(self.parse_expr())
2789 /// Parse patterns, separated by '|' s
2790 fn parse_pats(&mut self) -> Vec<Gc<Pat>> {
2791 let mut pats = Vec::new();
2793 pats.push(self.parse_pat());
2794 if self.token == token::BINOP(token::OR) { self.bump(); }
2795 else { return pats; }
2799 fn parse_pat_vec_elements(
2801 ) -> (Vec<Gc<Pat>> , Option<Gc<Pat>>, Vec<Gc<Pat>> ) {
2802 let mut before = Vec::new();
2803 let mut slice = None;
2804 let mut after = Vec::new();
2805 let mut first = true;
2806 let mut before_slice = true;
2808 while self.token != token::RBRACKET {
2809 if first { first = false; }
2810 else { self.expect(&token::COMMA); }
2812 let mut is_slice = false;
2814 if self.token == token::DOTDOT {
2817 before_slice = false;
2822 if self.token == token::COMMA || self.token == token::RBRACKET {
2823 slice = Some(box(GC) ast::Pat {
2824 id: ast::DUMMY_NODE_ID,
2829 let subpat = self.parse_pat();
2831 ast::Pat { node: PatIdent(_, _, _), .. } => {
2832 slice = Some(subpat);
2834 ast::Pat { span, .. } => self.span_fatal(
2835 span, "expected an identifier or nothing"
2840 let subpat = self.parse_pat();
2842 before.push(subpat);
2849 (before, slice, after)
2852 /// Parse the fields of a struct-like pattern
2853 fn parse_pat_fields(&mut self) -> (Vec<ast::FieldPat> , bool) {
2854 let mut fields = Vec::new();
2855 let mut etc = false;
2856 let mut first = true;
2857 while self.token != token::RBRACE {
2861 self.expect(&token::COMMA);
2862 // accept trailing commas
2863 if self.token == token::RBRACE { break }
2866 if self.token == token::DOTDOT {
2868 if self.token != token::RBRACE {
2869 let token_str = self.this_token_to_string();
2870 self.fatal(format!("expected `{}`, found `{}`", "}",
2871 token_str).as_slice())
2877 let bind_type = if self.eat_keyword(keywords::Mut) {
2878 BindByValue(MutMutable)
2879 } else if self.eat_keyword(keywords::Ref) {
2880 BindByRef(self.parse_mutability())
2882 BindByValue(MutImmutable)
2885 let fieldname = self.parse_ident();
2887 let subpat = if self.token == token::COLON {
2889 BindByRef(..) | BindByValue(MutMutable) => {
2890 let token_str = self.this_token_to_string();
2891 self.fatal(format!("unexpected `{}`",
2892 token_str).as_slice())
2900 let fieldpath = codemap::Spanned{span:self.last_span, node: fieldname};
2902 id: ast::DUMMY_NODE_ID,
2903 node: PatIdent(bind_type, fieldpath, None),
2904 span: self.last_span
2907 fields.push(ast::FieldPat { ident: fieldname, pat: subpat });
2909 return (fields, etc);
2912 /// Parse a pattern.
2913 pub fn parse_pat(&mut self) -> Gc<Pat> {
2914 maybe_whole!(self, NtPat);
2916 let lo = self.span.lo;
2921 token::UNDERSCORE => {
2924 hi = self.last_span.hi;
2925 return box(GC) ast::Pat {
2926 id: ast::DUMMY_NODE_ID,
2934 let sub = self.parse_pat();
2936 let last_span = self.last_span;
2938 self.obsolete(last_span, ObsoleteOwnedPattern);
2939 return box(GC) ast::Pat {
2940 id: ast::DUMMY_NODE_ID,
2945 token::BINOP(token::AND) | token::ANDAND => {
2947 let lo = self.span.lo;
2949 let sub = self.parse_pat();
2950 pat = PatRegion(sub);
2951 hi = self.last_span.hi;
2952 return box(GC) ast::Pat {
2953 id: ast::DUMMY_NODE_ID,
2959 // parse (pat,pat,pat,...) as tuple
2961 if self.token == token::RPAREN {
2964 let lit = box(GC) codemap::Spanned {
2966 span: mk_sp(lo, hi)};
2967 let expr = self.mk_expr(lo, hi, ExprLit(lit));
2970 let mut fields = vec!(self.parse_pat());
2971 if self.look_ahead(1, |t| *t != token::RPAREN) {
2972 while self.token == token::COMMA {
2974 if self.token == token::RPAREN { break; }
2975 fields.push(self.parse_pat());
2978 if fields.len() == 1 { self.expect(&token::COMMA); }
2979 self.expect(&token::RPAREN);
2980 pat = PatTup(fields);
2982 hi = self.last_span.hi;
2983 return box(GC) ast::Pat {
2984 id: ast::DUMMY_NODE_ID,
2989 token::LBRACKET => {
2990 // parse [pat,pat,...] as vector pattern
2992 let (before, slice, after) =
2993 self.parse_pat_vec_elements();
2995 self.expect(&token::RBRACKET);
2996 pat = ast::PatVec(before, slice, after);
2997 hi = self.last_span.hi;
2998 return box(GC) ast::Pat {
2999 id: ast::DUMMY_NODE_ID,
3006 // at this point, token != _, ~, &, &&, (, [
3008 if (!is_ident_or_path(&self.token) && self.token != token::MOD_SEP)
3009 || self.is_keyword(keywords::True)
3010 || self.is_keyword(keywords::False) {
3011 // Parse an expression pattern or exp .. exp.
3013 // These expressions are limited to literals (possibly
3014 // preceded by unary-minus) or identifiers.
3015 let val = self.parse_literal_maybe_minus();
3016 if self.eat(&token::DOTDOT) {
3017 let end = if is_ident_or_path(&self.token) {
3018 let path = self.parse_path(LifetimeAndTypesWithColons)
3020 let hi = self.span.hi;
3021 self.mk_expr(lo, hi, ExprPath(path))
3023 self.parse_literal_maybe_minus()
3025 pat = PatRange(val, end);
3029 } else if self.eat_keyword(keywords::Mut) {
3030 pat = self.parse_pat_ident(BindByValue(MutMutable));
3031 } else if self.eat_keyword(keywords::Ref) {
3033 let mutbl = self.parse_mutability();
3034 pat = self.parse_pat_ident(BindByRef(mutbl));
3035 } else if self.eat_keyword(keywords::Box) {
3038 // FIXME(#13910): Rename to `PatBox` and extend to full DST
3040 let sub = self.parse_pat();
3042 hi = self.last_span.hi;
3043 return box(GC) ast::Pat {
3044 id: ast::DUMMY_NODE_ID,
3049 let can_be_enum_or_struct = self.look_ahead(1, |t| {
3051 token::LPAREN | token::LBRACKET | token::LT |
3052 token::LBRACE | token::MOD_SEP => true,
3057 if self.look_ahead(1, |t| *t == token::DOTDOT) {
3058 let start = self.parse_expr_res(RESTRICT_NO_BAR_OP);
3059 self.eat(&token::DOTDOT);
3060 let end = self.parse_expr_res(RESTRICT_NO_BAR_OP);
3061 pat = PatRange(start, end);
3062 } else if is_plain_ident(&self.token) && !can_be_enum_or_struct {
3063 let id = self.parse_ident();
3064 let id_span = self.last_span;
3065 let pth1 = codemap::Spanned{span:id_span, node: id};
3066 if self.eat(&token::NOT) {
3068 let ket = token::close_delimiter_for(&self.token)
3069 .unwrap_or_else(|| self.fatal("expected open delimiter"));
3072 let tts = self.parse_seq_to_end(&ket,
3074 |p| p.parse_token_tree());
3076 let mac = MacInvocTT(ident_to_path(id_span,id), tts, EMPTY_CTXT);
3077 pat = ast::PatMac(codemap::Spanned {node: mac, span: self.span});
3079 let sub = if self.eat(&token::AT) {
3081 Some(self.parse_pat())
3086 pat = PatIdent(BindByValue(MutImmutable), pth1, sub);
3089 // parse an enum pat
3090 let enum_path = self.parse_path(LifetimeAndTypesWithColons)
3096 self.parse_pat_fields();
3098 pat = PatStruct(enum_path, fields, etc);
3101 let mut args: Vec<Gc<Pat>> = Vec::new();
3104 let is_dotdot = self.look_ahead(1, |t| {
3106 token::DOTDOT => true,
3111 // This is a "top constructor only" pat
3114 self.expect(&token::RPAREN);
3115 pat = PatEnum(enum_path, None);
3117 args = self.parse_enum_variant_seq(
3120 seq_sep_trailing_disallowed(token::COMMA),
3123 pat = PatEnum(enum_path, Some(args));
3127 if !enum_path.global && enum_path.segments.len() == 1 {
3128 // it could still be either an enum
3129 // or an identifier pattern, resolve
3130 // will sort it out:
3131 pat = PatIdent(BindByValue(MutImmutable),
3133 span: enum_path.span,
3134 node: enum_path.segments.get(0)
3138 pat = PatEnum(enum_path, Some(args));
3146 hi = self.last_span.hi;
3148 id: ast::DUMMY_NODE_ID,
3150 span: mk_sp(lo, hi),
3154 /// Parse ident or ident @ pat
3155 /// used by the copy foo and ref foo patterns to give a good
3156 /// error message when parsing mistakes like ref foo(a,b)
3157 fn parse_pat_ident(&mut self,
3158 binding_mode: ast::BindingMode)
3160 if !is_plain_ident(&self.token) {
3161 let last_span = self.last_span;
3162 self.span_fatal(last_span,
3163 "expected identifier, found path");
3165 let ident = self.parse_ident();
3166 let last_span = self.last_span;
3167 let name = codemap::Spanned{span: last_span, node: ident};
3168 let sub = if self.eat(&token::AT) {
3169 Some(self.parse_pat())
3174 // just to be friendly, if they write something like
3176 // we end up here with ( as the current token. This shortly
3177 // leads to a parse error. Note that if there is no explicit
3178 // binding mode then we do not end up here, because the lookahead
3179 // will direct us over to parse_enum_variant()
3180 if self.token == token::LPAREN {
3181 let last_span = self.last_span;
3184 "expected identifier, found enum pattern");
3187 PatIdent(binding_mode, name, sub)
3190 /// Parse a local variable declaration
3191 fn parse_local(&mut self) -> Gc<Local> {
3192 let lo = self.span.lo;
3193 let pat = self.parse_pat();
3196 id: ast::DUMMY_NODE_ID,
3198 span: mk_sp(lo, lo),
3200 if self.eat(&token::COLON) {
3201 ty = self.parse_ty(true);
3203 let init = self.parse_initializer();
3204 box(GC) ast::Local {
3208 id: ast::DUMMY_NODE_ID,
3209 span: mk_sp(lo, self.last_span.hi),
3214 /// Parse a "let" stmt
3215 fn parse_let(&mut self) -> Gc<Decl> {
3216 let lo = self.span.lo;
3217 let local = self.parse_local();
3218 box(GC) spanned(lo, self.last_span.hi, DeclLocal(local))
3221 /// Parse a structure field
3222 fn parse_name_and_ty(&mut self, pr: Visibility,
3223 attrs: Vec<Attribute> ) -> StructField {
3224 let lo = self.span.lo;
3225 if !is_plain_ident(&self.token) {
3226 self.fatal("expected ident");
3228 let name = self.parse_ident();
3229 self.expect(&token::COLON);
3230 let ty = self.parse_ty(true);
3231 spanned(lo, self.last_span.hi, ast::StructField_ {
3232 kind: NamedField(name, pr),
3233 id: ast::DUMMY_NODE_ID,
3239 /// Parse a statement. may include decl.
3240 /// Precondition: any attributes are parsed already
3241 pub fn parse_stmt(&mut self, item_attrs: Vec<Attribute>) -> Gc<Stmt> {
3242 maybe_whole!(self, NtStmt);
3244 fn check_expected_item(p: &mut Parser, found_attrs: bool) {
3245 // If we have attributes then we should have an item
3247 let last_span = p.last_span;
3248 p.span_err(last_span, "expected item after attributes");
3252 let lo = self.span.lo;
3253 if self.is_keyword(keywords::Let) {
3254 check_expected_item(self, !item_attrs.is_empty());
3255 self.expect_keyword(keywords::Let);
3256 let decl = self.parse_let();
3257 return box(GC) spanned(lo, decl.span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID));
3258 } else if is_ident(&self.token)
3259 && !token::is_any_keyword(&self.token)
3260 && self.look_ahead(1, |t| *t == token::NOT) {
3261 // it's a macro invocation:
3263 check_expected_item(self, !item_attrs.is_empty());
3265 // Potential trouble: if we allow macros with paths instead of
3266 // idents, we'd need to look ahead past the whole path here...
3267 let pth = self.parse_path(NoTypesAllowed).path;
3270 let id = if token::close_delimiter_for(&self.token).is_some() {
3271 token::special_idents::invalid // no special identifier
3276 // check that we're pointing at delimiters (need to check
3277 // again after the `if`, because of `parse_ident`
3278 // consuming more tokens).
3279 let (bra, ket) = match token::close_delimiter_for(&self.token) {
3280 Some(ket) => (self.token.clone(), ket),
3282 // we only expect an ident if we didn't parse one
3284 let ident_str = if id.name == token::special_idents::invalid.name {
3289 let tok_str = self.this_token_to_string();
3290 self.fatal(format!("expected {}`(` or `{{`, but found `{}`",
3292 tok_str).as_slice())
3296 let tts = self.parse_unspanned_seq(
3300 |p| p.parse_token_tree()
3302 let hi = self.span.hi;
3304 if id.name == token::special_idents::invalid.name {
3305 return box(GC) spanned(lo, hi, StmtMac(
3306 spanned(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT)), false));
3308 // if it has a special ident, it's definitely an item
3309 return box(GC) spanned(lo, hi, StmtDecl(
3310 box(GC) spanned(lo, hi, DeclItem(
3312 lo, hi, id /*id is good here*/,
3313 ItemMac(spanned(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT))),
3314 Inherited, Vec::new(/*no attrs*/)))),
3315 ast::DUMMY_NODE_ID));
3319 let found_attrs = !item_attrs.is_empty();
3320 match self.parse_item_or_view_item(item_attrs, false) {
3323 let decl = box(GC) spanned(lo, hi, DeclItem(i));
3324 return box(GC) spanned(lo, hi, StmtDecl(decl, ast::DUMMY_NODE_ID));
3326 IoviViewItem(vi) => {
3327 self.span_fatal(vi.span,
3328 "view items must be declared at the top of the block");
3330 IoviForeignItem(_) => {
3331 self.fatal("foreign items are not allowed here");
3333 IoviNone(_) => { /* fallthrough */ }
3336 check_expected_item(self, found_attrs);
3338 // Remainder are line-expr stmts.
3339 let e = self.parse_expr_res(RESTRICT_STMT_EXPR);
3340 return box(GC) spanned(lo, e.span.hi, StmtExpr(e, ast::DUMMY_NODE_ID));
3344 /// Is this expression a successfully-parsed statement?
3345 fn expr_is_complete(&mut self, e: Gc<Expr>) -> bool {
3346 return self.restriction == RESTRICT_STMT_EXPR &&
3347 !classify::expr_requires_semi_to_be_stmt(e);
3350 /// Parse a block. No inner attrs are allowed.
3351 pub fn parse_block(&mut self) -> P<Block> {
3352 maybe_whole!(no_clone self, NtBlock);
3354 let lo = self.span.lo;
3355 self.expect(&token::LBRACE);
3357 return self.parse_block_tail_(lo, DefaultBlock, Vec::new());
3360 /// Parse a block. Inner attrs are allowed.
3361 fn parse_inner_attrs_and_block(&mut self)
3362 -> (Vec<Attribute> , P<Block>) {
3364 maybe_whole!(pair_empty self, NtBlock);
3366 let lo = self.span.lo;
3367 self.expect(&token::LBRACE);
3368 let (inner, next) = self.parse_inner_attrs_and_next();
3370 (inner, self.parse_block_tail_(lo, DefaultBlock, next))
3373 /// Precondition: already parsed the '{' or '#{'
3374 /// I guess that also means "already parsed the 'impure'" if
3375 /// necessary, and this should take a qualifier.
3376 /// Some blocks start with "#{"...
3377 fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> P<Block> {
3378 self.parse_block_tail_(lo, s, Vec::new())
3381 /// Parse the rest of a block expression or function body
3382 fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
3383 first_item_attrs: Vec<Attribute> ) -> P<Block> {
3384 let mut stmts = Vec::new();
3385 let mut expr = None;
3387 // wouldn't it be more uniform to parse view items only, here?
3388 let ParsedItemsAndViewItems {
3389 attrs_remaining: attrs_remaining,
3390 view_items: view_items,
3393 } = self.parse_items_and_view_items(first_item_attrs,
3396 for item in items.iter() {
3397 let decl = box(GC) spanned(item.span.lo, item.span.hi, DeclItem(*item));
3398 stmts.push(box(GC) spanned(item.span.lo, item.span.hi,
3399 StmtDecl(decl, ast::DUMMY_NODE_ID)));
3402 let mut attributes_box = attrs_remaining;
3404 while self.token != token::RBRACE {
3405 // parsing items even when they're not allowed lets us give
3406 // better error messages and recover more gracefully.
3407 attributes_box.push_all(self.parse_outer_attributes().as_slice());
3410 if !attributes_box.is_empty() {
3411 let last_span = self.last_span;
3412 self.span_err(last_span, "expected item after attributes");
3413 attributes_box = Vec::new();
3415 self.bump(); // empty
3418 // fall through and out.
3421 let stmt = self.parse_stmt(attributes_box);
3422 attributes_box = Vec::new();
3424 StmtExpr(e, stmt_id) => {
3425 // expression without semicolon
3426 if classify::stmt_ends_with_semi(&*stmt) {
3427 // Just check for errors and recover; do not eat semicolon yet.
3428 self.commit_stmt(stmt, &[], &[token::SEMI, token::RBRACE]);
3434 let span_with_semi = Span {
3436 hi: self.last_span.hi,
3437 expn_info: stmt.span.expn_info,
3439 stmts.push(box(GC) codemap::Spanned {
3440 node: StmtSemi(e, stmt_id),
3441 span: span_with_semi,
3452 StmtMac(ref m, _) => {
3453 // statement macro; might be an expr
3457 stmts.push(box(GC) codemap::Spanned {
3458 node: StmtMac((*m).clone(), true),
3463 // if a block ends in `m!(arg)` without
3464 // a `;`, it must be an expr
3466 self.mk_mac_expr(stmt.span.lo,
3475 _ => { // all other kinds of statements:
3476 stmts.push(stmt.clone());
3478 if classify::stmt_ends_with_semi(&*stmt) {
3479 self.commit_stmt_expecting(stmt, token::SEMI);
3487 if !attributes_box.is_empty() {
3488 let last_span = self.last_span;
3489 self.span_err(last_span, "expected item after attributes");
3492 let hi = self.span.hi;
3495 view_items: view_items,
3498 id: ast::DUMMY_NODE_ID,
3500 span: mk_sp(lo, hi),
3504 fn parse_unboxed_function_type(&mut self) -> UnboxedFnTy {
3505 let inputs = if self.eat(&token::OROR) {
3510 if self.token == token::BINOP(token::AND) &&
3511 self.look_ahead(1, |t| {
3512 token::is_keyword(keywords::Mut, t)
3514 self.look_ahead(2, |t| *t == token::COLON) {
3520 let inputs = self.parse_seq_to_before_or(&token::COMMA,
3522 p.parse_arg_general(false)
3528 let (return_style, output) = self.parse_ret_ty();
3539 /// matches optbounds = ( ( : ( boundseq )? )? )
3540 /// where boundseq = ( bound + boundseq ) | bound
3541 /// and bound = 'static | ty
3542 /// Returns "None" if there's no colon (e.g. "T");
3543 /// Returns "Some(Empty)" if there's a colon but nothing after (e.g. "T:")
3544 /// Returns "Some(stuff)" otherwise (e.g. "T:stuff").
3545 /// NB: The None/Some distinction is important for issue #7264.
3547 /// Note that the `allow_any_lifetime` argument is a hack for now while the
3548 /// AST doesn't support arbitrary lifetimes in bounds on type parameters. In
3549 /// the future, this flag should be removed, and the return value of this
3550 /// function should be Option<~[TyParamBound]>
3551 fn parse_ty_param_bounds(&mut self, allow_any_lifetime: bool)
3552 -> (Option<ast::Lifetime>,
3553 OwnedSlice<TyParamBound>) {
3554 let mut ret_lifetime = None;
3555 let mut result = vec!();
3558 token::LIFETIME(lifetime) => {
3559 let lifetime_interned_string = token::get_ident(lifetime);
3560 if lifetime_interned_string.equiv(&("'static")) {
3561 result.push(StaticRegionTyParamBound);
3562 if allow_any_lifetime && ret_lifetime.is_none() {
3563 ret_lifetime = Some(ast::Lifetime {
3564 id: ast::DUMMY_NODE_ID,
3569 } else if allow_any_lifetime && ret_lifetime.is_none() {
3570 ret_lifetime = Some(ast::Lifetime {
3571 id: ast::DUMMY_NODE_ID,
3576 result.push(OtherRegionTyParamBound(self.span));
3580 token::MOD_SEP | token::IDENT(..) => {
3581 let tref = self.parse_trait_ref();
3582 result.push(TraitTyParamBound(tref));
3584 token::BINOP(token::OR) | token::OROR => {
3585 let unboxed_function_type =
3586 self.parse_unboxed_function_type();
3587 result.push(UnboxedFnTyParamBound(unboxed_function_type));
3592 if !self.eat(&token::BINOP(token::PLUS)) {
3597 return (ret_lifetime, OwnedSlice::from_vec(result));
3600 fn trait_ref_from_ident(ident: Ident, span: Span) -> ast::TraitRef {
3601 let segment = ast::PathSegment {
3603 lifetimes: Vec::new(),
3604 types: OwnedSlice::empty(),
3606 let path = ast::Path {
3609 segments: vec![segment],
3613 ref_id: ast::DUMMY_NODE_ID,
3617 /// Matches typaram = (unbound`?`)? IDENT optbounds ( EQ ty )?
3618 fn parse_ty_param(&mut self) -> TyParam {
3619 // This is a bit hacky. Currently we are only interested in a single
3620 // unbound, and it may only be `Sized`. To avoid backtracking and other
3621 // complications, we parse an ident, then check for `?`. If we find it,
3622 // we use the ident as the unbound, otherwise, we use it as the name of
3624 let mut span = self.span;
3625 let mut ident = self.parse_ident();
3626 let mut unbound = None;
3627 if self.eat(&token::QUESTION) {
3628 let tref = Parser::trait_ref_from_ident(ident, span);
3629 unbound = Some(TraitTyParamBound(tref));
3631 ident = self.parse_ident();
3635 if self.eat(&token::COLON) {
3636 let (_, bounds) = self.parse_ty_param_bounds(false);
3642 // For typarams we don't care about the difference b/w "<T>" and "<T:>".
3643 let bounds = opt_bounds.unwrap_or_default();
3645 let default = if self.token == token::EQ {
3647 Some(self.parse_ty(true))
3653 id: ast::DUMMY_NODE_ID,
3661 /// Parse a set of optional generic type parameter declarations
3662 /// matches generics = ( ) | ( < > ) | ( < typaramseq ( , )? > ) | ( < lifetimes ( , )? > )
3663 /// | ( < lifetimes , typaramseq ( , )? > )
3664 /// where typaramseq = ( typaram ) | ( typaram , typaramseq )
3665 pub fn parse_generics(&mut self) -> ast::Generics {
3666 if self.eat(&token::LT) {
3667 let lifetimes = self.parse_lifetimes();
3668 let mut seen_default = false;
3669 let ty_params = self.parse_seq_to_gt(Some(token::COMMA), |p| {
3670 p.forbid_lifetime();
3671 let ty_param = p.parse_ty_param();
3672 if ty_param.default.is_some() {
3673 seen_default = true;
3674 } else if seen_default {
3675 let last_span = p.last_span;
3676 p.span_err(last_span,
3677 "type parameters with a default must be trailing");
3681 ast::Generics { lifetimes: lifetimes, ty_params: ty_params }
3683 ast_util::empty_generics()
3687 fn parse_generic_values_after_lt(&mut self) -> (Vec<ast::Lifetime>, Vec<P<Ty>> ) {
3688 let lifetimes = self.parse_lifetimes();
3689 let result = self.parse_seq_to_gt(
3692 p.forbid_lifetime();
3696 (lifetimes, result.into_vec())
3699 fn forbid_lifetime(&mut self) {
3700 if Parser::token_is_lifetime(&self.token) {
3701 let span = self.span;
3702 self.span_fatal(span, "lifetime parameters must be declared \
3703 prior to type parameters");
3707 fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool)
3708 -> (Vec<Arg> , bool) {
3710 let mut args: Vec<Option<Arg>> =
3711 self.parse_unspanned_seq(
3714 seq_sep_trailing_allowed(token::COMMA),
3716 if p.token == token::DOTDOTDOT {
3719 if p.token != token::RPAREN {
3722 "`...` must be last in argument list for variadic function");
3727 "only foreign functions are allowed to be variadic");
3731 Some(p.parse_arg_general(named_args))
3736 let variadic = match args.pop() {
3739 // Need to put back that last arg
3746 if variadic && args.is_empty() {
3748 "variadic function must be declared with at least one named argument");
3751 let args = args.move_iter().map(|x| x.unwrap()).collect();
3756 /// Parse the argument list and result type of a function declaration
3757 pub fn parse_fn_decl(&mut self, allow_variadic: bool) -> P<FnDecl> {
3759 let (args, variadic) = self.parse_fn_args(true, allow_variadic);
3760 let (ret_style, ret_ty) = self.parse_ret_ty();
3770 fn is_self_ident(&mut self) -> bool {
3772 token::IDENT(id, false) => id.name == special_idents::self_.name,
3777 fn expect_self_ident(&mut self) -> ast::Ident {
3779 token::IDENT(id, false) if id.name == special_idents::self_.name => {
3784 let token_str = self.this_token_to_string();
3785 self.fatal(format!("expected `self` but found `{}`",
3786 token_str).as_slice())
3791 /// Parse the argument list and result type of a function
3792 /// that may have a self type.
3793 fn parse_fn_decl_with_self(&mut self, parse_arg_fn: |&mut Parser| -> Arg)
3794 -> (ExplicitSelf, P<FnDecl>) {
3795 fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
3796 -> ast::ExplicitSelf_ {
3797 // The following things are possible to see here:
3802 // fn(&'lt mut self)
3804 // We already know that the current token is `&`.
3806 if this.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) {
3808 SelfRegion(None, MutImmutable, this.expect_self_ident())
3809 } else if this.look_ahead(1, |t| Parser::token_is_mutability(t)) &&
3811 |t| token::is_keyword(keywords::Self,
3814 let mutability = this.parse_mutability();
3815 SelfRegion(None, mutability, this.expect_self_ident())
3816 } else if this.look_ahead(1, |t| Parser::token_is_lifetime(t)) &&
3818 |t| token::is_keyword(keywords::Self,
3821 let lifetime = this.parse_lifetime();
3822 SelfRegion(Some(lifetime), MutImmutable, this.expect_self_ident())
3823 } else if this.look_ahead(1, |t| Parser::token_is_lifetime(t)) &&
3824 this.look_ahead(2, |t| {
3825 Parser::token_is_mutability(t)
3827 this.look_ahead(3, |t| token::is_keyword(keywords::Self,
3830 let lifetime = this.parse_lifetime();
3831 let mutability = this.parse_mutability();
3832 SelfRegion(Some(lifetime), mutability, this.expect_self_ident())
3838 self.expect(&token::LPAREN);
3840 // A bit of complexity and lookahead is needed here in order to be
3841 // backwards compatible.
3842 let lo = self.span.lo;
3843 let mut mutbl_self = MutImmutable;
3844 let explicit_self = match self.token {
3845 token::BINOP(token::AND) => {
3846 maybe_parse_borrowed_explicit_self(self)
3849 // We need to make sure it isn't a type
3850 if self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) {
3852 drop(self.expect_self_ident());
3853 let last_span = self.last_span;
3854 self.obsolete(last_span, ObsoleteOwnedSelf)
3858 token::BINOP(token::STAR) => {
3859 // Possibly "*self" or "*mut self" -- not supported. Try to avoid
3860 // emitting cryptic "unexpected token" errors.
3862 let _mutability = if Parser::token_is_mutability(&self.token) {
3863 self.parse_mutability()
3867 if self.is_self_ident() {
3868 let span = self.span;
3869 self.span_err(span, "cannot pass self by unsafe pointer");
3872 // error case, making bogus self ident:
3873 SelfValue(special_idents::self_)
3875 token::IDENT(..) => {
3876 if self.is_self_ident() {
3877 let self_ident = self.expect_self_ident();
3879 // Determine whether this is the fully explicit form, `self:
3881 if self.eat(&token::COLON) {
3882 SelfExplicit(self.parse_ty(false), self_ident)
3884 SelfValue(self_ident)
3886 } else if Parser::token_is_mutability(&self.token) &&
3887 self.look_ahead(1, |t| {
3888 token::is_keyword(keywords::Self, t)
3890 mutbl_self = self.parse_mutability();
3891 let self_ident = self.expect_self_ident();
3893 // Determine whether this is the fully explicit form,
3895 if self.eat(&token::COLON) {
3896 SelfExplicit(self.parse_ty(false), self_ident)
3898 SelfValue(self_ident)
3900 } else if Parser::token_is_mutability(&self.token) &&
3901 self.look_ahead(1, |t| *t == token::TILDE) &&
3902 self.look_ahead(2, |t| {
3903 token::is_keyword(keywords::Self, t)
3905 mutbl_self = self.parse_mutability();
3907 drop(self.expect_self_ident());
3908 let last_span = self.last_span;
3909 self.obsolete(last_span, ObsoleteOwnedSelf);
3918 let explicit_self_sp = mk_sp(lo, self.span.hi);
3920 // shared fall-through for the three cases below. borrowing prevents simply
3921 // writing this as a closure
3922 macro_rules! parse_remaining_arguments {
3925 // If we parsed a self type, expect a comma before the argument list.
3929 let sep = seq_sep_trailing_disallowed(token::COMMA);
3930 let mut fn_inputs = self.parse_seq_to_before_end(
3935 fn_inputs.unshift(Arg::new_self(explicit_self_sp, mutbl_self, $self_id));
3939 vec!(Arg::new_self(explicit_self_sp, mutbl_self, $self_id))
3942 let token_str = self.this_token_to_string();
3943 self.fatal(format!("expected `,` or `)`, found `{}`",
3944 token_str).as_slice())
3950 let fn_inputs = match explicit_self {
3952 let sep = seq_sep_trailing_disallowed(token::COMMA);
3953 self.parse_seq_to_before_end(&token::RPAREN, sep, parse_arg_fn)
3955 SelfValue(id) => parse_remaining_arguments!(id),
3956 SelfRegion(_,_,id) => parse_remaining_arguments!(id),
3957 SelfExplicit(_,id) => parse_remaining_arguments!(id),
3961 self.expect(&token::RPAREN);
3963 let hi = self.span.hi;
3965 let (ret_style, ret_ty) = self.parse_ret_ty();
3967 let fn_decl = P(FnDecl {
3974 (spanned(lo, hi, explicit_self), fn_decl)
3977 // parse the |arg, arg| header on a lambda
3978 fn parse_fn_block_decl(&mut self) -> (P<FnDecl>, bool) {
3979 let (is_unboxed, inputs_captures) = {
3980 if self.eat(&token::OROR) {
3983 self.expect(&token::BINOP(token::OR));
3984 let is_unboxed = self.token == token::BINOP(token::AND) &&
3985 self.look_ahead(1, |t| {
3986 token::is_keyword(keywords::Mut, t)
3988 self.look_ahead(2, |t| *t == token::COLON);
3994 let args = self.parse_seq_to_before_end(
3995 &token::BINOP(token::OR),
3996 seq_sep_trailing_disallowed(token::COMMA),
3997 |p| p.parse_fn_block_arg()
4003 let output = if self.eat(&token::RARROW) {
4007 id: ast::DUMMY_NODE_ID,
4014 inputs: inputs_captures,
4021 /// Parses the `(arg, arg) -> return_type` header on a procedure.
4022 fn parse_proc_decl(&mut self) -> P<FnDecl> {
4024 self.parse_unspanned_seq(&token::LPAREN,
4026 seq_sep_trailing_allowed(token::COMMA),
4027 |p| p.parse_fn_block_arg());
4029 let output = if self.eat(&token::RARROW) {
4033 id: ast::DUMMY_NODE_ID,
4047 /// Parse the name and optional generic types of a function header.
4048 fn parse_fn_header(&mut self) -> (Ident, ast::Generics) {
4049 let id = self.parse_ident();
4050 let generics = self.parse_generics();
4054 fn mk_item(&mut self, lo: BytePos, hi: BytePos, ident: Ident,
4055 node: Item_, vis: Visibility,
4056 attrs: Vec<Attribute>) -> Gc<Item> {
4060 id: ast::DUMMY_NODE_ID,
4067 /// Parse an item-position function declaration.
4068 fn parse_item_fn(&mut self, fn_style: FnStyle, abi: abi::Abi) -> ItemInfo {
4069 let (ident, generics) = self.parse_fn_header();
4070 let decl = self.parse_fn_decl(false);
4071 let (inner_attrs, body) = self.parse_inner_attrs_and_block();
4072 (ident, ItemFn(decl, fn_style, abi, generics, body), Some(inner_attrs))
4075 /// Parse a method in a trait impl, starting with `attrs` attributes.
4076 pub fn parse_method(&mut self,
4077 already_parsed_attrs: Option<Vec<Attribute>>)
4079 let next_attrs = self.parse_outer_attributes();
4080 let attrs = match already_parsed_attrs {
4081 Some(mut a) => { a.push_all_move(next_attrs); a }
4085 let lo = self.span.lo;
4087 // code copied from parse_macro_use_or_failure... abstraction!
4088 let (method_, hi, new_attrs) = {
4089 if !token::is_any_keyword(&self.token)
4090 && self.look_ahead(1, |t| *t == token::NOT)
4091 && (self.look_ahead(2, |t| *t == token::LPAREN)
4092 || self.look_ahead(2, |t| *t == token::LBRACE)) {
4094 let pth = self.parse_path(NoTypesAllowed).path;
4095 self.expect(&token::NOT);
4097 // eat a matched-delimiter token tree:
4098 let tts = match token::close_delimiter_for(&self.token) {
4101 self.parse_seq_to_end(&ket,
4103 |p| p.parse_token_tree())
4105 None => self.fatal("expected open delimiter")
4107 let m_ = ast::MacInvocTT(pth, tts, EMPTY_CTXT);
4108 let m: ast::Mac = codemap::Spanned { node: m_,
4109 span: mk_sp(self.span.lo,
4111 (ast::MethMac(m), self.span.hi, attrs)
4113 let visa = self.parse_visibility();
4114 let abi = if self.eat_keyword(keywords::Extern) {
4115 self.parse_opt_abi().unwrap_or(abi::C)
4116 } else if attr::contains_name(attrs.as_slice(),
4117 "rust_call_abi_hack") {
4118 // FIXME(stage0, pcwalton): Remove this awful hack after a
4119 // snapshot, and change to `extern "rust-call" fn`.
4124 let fn_style = self.parse_fn_style();
4125 let ident = self.parse_ident();
4126 let generics = self.parse_generics();
4127 let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| {
4130 let (inner_attrs, body) = self.parse_inner_attrs_and_block();
4131 let new_attrs = attrs.append(inner_attrs.as_slice());
4132 (ast::MethDecl(ident,
4140 body.span.hi, new_attrs)
4143 box(GC) ast::Method {
4145 id: ast::DUMMY_NODE_ID,
4146 span: mk_sp(lo, hi),
4151 /// Parse trait Foo { ... }
4152 fn parse_item_trait(&mut self) -> ItemInfo {
4153 let ident = self.parse_ident();
4154 let tps = self.parse_generics();
4155 let sized = self.parse_for_sized();
4157 // Parse traits, if necessary.
4159 if self.token == token::COLON {
4161 traits = self.parse_trait_ref_list(&token::LBRACE);
4163 traits = Vec::new();
4166 let meths = self.parse_trait_methods();
4167 (ident, ItemTrait(tps, sized, traits, meths), None)
4170 /// Parses two variants (with the region/type params always optional):
4171 /// impl<T> Foo { ... }
4172 /// impl<T> ToString for ~[T] { ... }
4173 fn parse_item_impl(&mut self) -> ItemInfo {
4174 // First, parse type parameters if necessary.
4175 let generics = self.parse_generics();
4177 // Special case: if the next identifier that follows is '(', don't
4178 // allow this to be parsed as a trait.
4179 let could_be_trait = self.token != token::LPAREN;
4182 let mut ty = self.parse_ty(true);
4184 // Parse traits, if necessary.
4185 let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) {
4186 // New-style trait. Reinterpret the type as a trait.
4187 let opt_trait_ref = match ty.node {
4188 TyPath(ref path, None, node_id) => {
4190 path: /* bad */ (*path).clone(),
4195 self.span_err(ty.span,
4196 "bounded traits are only valid in type position");
4200 self.span_err(ty.span, "not a trait");
4205 ty = self.parse_ty(true);
4211 let mut meths = Vec::new();
4212 self.expect(&token::LBRACE);
4213 let (inner_attrs, next) = self.parse_inner_attrs_and_next();
4214 let mut method_attrs = Some(next);
4215 while !self.eat(&token::RBRACE) {
4216 meths.push(self.parse_method(method_attrs));
4217 method_attrs = None;
4220 let ident = ast_util::impl_pretty_name(&opt_trait, &*ty);
4222 (ident, ItemImpl(generics, opt_trait, ty, meths), Some(inner_attrs))
4225 /// Parse a::B<String,int>
4226 fn parse_trait_ref(&mut self) -> TraitRef {
4228 path: self.parse_path(LifetimeAndTypesWithoutColons).path,
4229 ref_id: ast::DUMMY_NODE_ID,
4233 /// Parse B + C<String,int> + D
4234 fn parse_trait_ref_list(&mut self, ket: &token::Token) -> Vec<TraitRef> {
4235 self.parse_seq_to_before_end(
4237 seq_sep_trailing_disallowed(token::BINOP(token::PLUS)),
4238 |p| p.parse_trait_ref()
4242 /// Parse struct Foo { ... }
4243 fn parse_item_struct(&mut self, is_virtual: bool) -> ItemInfo {
4244 let class_name = self.parse_ident();
4245 let generics = self.parse_generics();
4247 let super_struct = if self.eat(&token::COLON) {
4248 let ty = self.parse_ty(true);
4250 TyPath(_, None, _) => {
4254 self.span_err(ty.span, "not a struct");
4262 let mut fields: Vec<StructField>;
4265 if self.eat(&token::LBRACE) {
4266 // It's a record-like struct.
4267 is_tuple_like = false;
4268 fields = Vec::new();
4269 while self.token != token::RBRACE {
4270 fields.push(self.parse_struct_decl_field());
4272 if fields.len() == 0 {
4273 self.fatal(format!("unit-like struct definition should be \
4274 written as `struct {};`",
4275 token::get_ident(class_name)).as_slice());
4278 } else if self.token == token::LPAREN {
4279 // It's a tuple-like struct.
4280 is_tuple_like = true;
4281 fields = self.parse_unspanned_seq(
4284 seq_sep_trailing_allowed(token::COMMA),
4286 let attrs = p.parse_outer_attributes();
4288 let struct_field_ = ast::StructField_ {
4289 kind: UnnamedField(p.parse_visibility()),
4290 id: ast::DUMMY_NODE_ID,
4291 ty: p.parse_ty(true),
4294 spanned(lo, p.span.hi, struct_field_)
4296 if fields.len() == 0 {
4297 self.fatal(format!("unit-like struct definition should be \
4298 written as `struct {};`",
4299 token::get_ident(class_name)).as_slice());
4301 self.expect(&token::SEMI);
4302 } else if self.eat(&token::SEMI) {
4303 // It's a unit-like struct.
4304 is_tuple_like = true;
4305 fields = Vec::new();
4307 let token_str = self.this_token_to_string();
4308 self.fatal(format!("expected `{}`, `(`, or `;` after struct \
4309 name but found `{}`", "{",
4310 token_str).as_slice())
4313 let _ = ast::DUMMY_NODE_ID; // FIXME: Workaround for crazy bug.
4314 let new_id = ast::DUMMY_NODE_ID;
4316 ItemStruct(box(GC) ast::StructDef {
4318 ctor_id: if is_tuple_like { Some(new_id) } else { None },
4319 super_struct: super_struct,
4320 is_virtual: is_virtual,
4325 /// Parse a structure field declaration
4326 pub fn parse_single_struct_field(&mut self,
4328 attrs: Vec<Attribute> )
4330 let a_var = self.parse_name_and_ty(vis, attrs);
4337 let span = self.span;
4338 let token_str = self.this_token_to_string();
4339 self.span_fatal(span,
4340 format!("expected `,`, or `}}` but found `{}`",
4341 token_str).as_slice())
4347 /// Parse an element of a struct definition
4348 fn parse_struct_decl_field(&mut self) -> StructField {
4350 let attrs = self.parse_outer_attributes();
4352 if self.eat_keyword(keywords::Pub) {
4353 return self.parse_single_struct_field(Public, attrs);
4356 return self.parse_single_struct_field(Inherited, attrs);
4359 /// Parse visiility: PUB, PRIV, or nothing
4360 fn parse_visibility(&mut self) -> Visibility {
4361 if self.eat_keyword(keywords::Pub) { Public }
4365 fn parse_for_sized(&mut self) -> Option<ast::TyParamBound> {
4366 if self.eat_keyword(keywords::For) {
4367 let span = self.span;
4368 let ident = self.parse_ident();
4369 if !self.eat(&token::QUESTION) {
4371 "expected 'Sized?' after `for` in trait item");
4374 let tref = Parser::trait_ref_from_ident(ident, span);
4375 Some(TraitTyParamBound(tref))
4381 /// Given a termination token and a vector of already-parsed
4382 /// attributes (of length 0 or 1), parse all of the items in a module
4383 fn parse_mod_items(&mut self,
4385 first_item_attrs: Vec<Attribute>,
4388 // parse all of the items up to closing or an attribute.
4389 // view items are legal here.
4390 let ParsedItemsAndViewItems {
4391 attrs_remaining: attrs_remaining,
4392 view_items: view_items,
4393 items: starting_items,
4395 } = self.parse_items_and_view_items(first_item_attrs, true, true);
4396 let mut items: Vec<Gc<Item>> = starting_items;
4397 let attrs_remaining_len = attrs_remaining.len();
4399 // don't think this other loop is even necessary....
4401 let mut first = true;
4402 while self.token != term {
4403 let mut attrs = self.parse_outer_attributes();
4405 attrs = attrs_remaining.clone().append(attrs.as_slice());
4408 debug!("parse_mod_items: parse_item_or_view_item(attrs={:?})",
4410 match self.parse_item_or_view_item(attrs,
4411 true /* macros allowed */) {
4412 IoviItem(item) => items.push(item),
4413 IoviViewItem(view_item) => {
4414 self.span_fatal(view_item.span,
4415 "view items must be declared at the top of \
4419 let token_str = self.this_token_to_string();
4420 self.fatal(format!("expected item but found `{}`",
4421 token_str).as_slice())
4426 if first && attrs_remaining_len > 0u {
4427 // We parsed attributes for the first item but didn't find it
4428 let last_span = self.last_span;
4429 self.span_err(last_span, "expected item after attributes");
4433 inner: mk_sp(inner_lo, self.span.lo),
4434 view_items: view_items,
4439 fn parse_item_const(&mut self) -> ItemInfo {
4440 let m = if self.eat_keyword(keywords::Mut) {MutMutable} else {MutImmutable};
4441 let id = self.parse_ident();
4442 self.expect(&token::COLON);
4443 let ty = self.parse_ty(true);
4444 self.expect(&token::EQ);
4445 let e = self.parse_expr();
4446 self.commit_expr_expecting(e, token::SEMI);
4447 (id, ItemStatic(ty, m, e), None)
4450 /// Parse a `mod <foo> { ... }` or `mod <foo>;` item
4451 fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> ItemInfo {
4452 let id_span = self.span;
4453 let id = self.parse_ident();
4454 if self.token == token::SEMI {
4456 // This mod is in an external file. Let's go get it!
4457 let (m, attrs) = self.eval_src_mod(id, outer_attrs, id_span);
4458 (id, m, Some(attrs))
4460 self.push_mod_path(id, outer_attrs);
4461 self.expect(&token::LBRACE);
4462 let mod_inner_lo = self.span.lo;
4463 let old_owns_directory = self.owns_directory;
4464 self.owns_directory = true;
4465 let (inner, next) = self.parse_inner_attrs_and_next();
4466 let m = self.parse_mod_items(token::RBRACE, next, mod_inner_lo);
4467 self.expect(&token::RBRACE);
4468 self.owns_directory = old_owns_directory;
4469 self.pop_mod_path();
4470 (id, ItemMod(m), Some(inner))
4474 fn push_mod_path(&mut self, id: Ident, attrs: &[Attribute]) {
4475 let default_path = self.id_to_interned_str(id);
4476 let file_path = match ::attr::first_attr_value_str_by_name(attrs,
4479 None => default_path,
4481 self.mod_path_stack.push(file_path)
4484 fn pop_mod_path(&mut self) {
4485 self.mod_path_stack.pop().unwrap();
4488 /// Read a module from a source file.
4489 fn eval_src_mod(&mut self,
4491 outer_attrs: &[ast::Attribute],
4493 -> (ast::Item_, Vec<ast::Attribute> ) {
4494 let mut prefix = Path::new(self.sess.span_diagnostic.cm.span_to_filename(self.span));
4496 let mod_path = Path::new(".").join_many(self.mod_path_stack.as_slice());
4497 let dir_path = prefix.join(&mod_path);
4498 let mod_string = token::get_ident(id);
4499 let (file_path, owns_directory) = match ::attr::first_attr_value_str_by_name(
4500 outer_attrs, "path") {
4501 Some(d) => (dir_path.join(d), true),
4503 let mod_name = mod_string.get().to_string();
4504 let default_path_str = format!("{}.rs", mod_name);
4505 let secondary_path_str = format!("{}/mod.rs", mod_name);
4506 let default_path = dir_path.join(default_path_str.as_slice());
4507 let secondary_path = dir_path.join(secondary_path_str.as_slice());
4508 let default_exists = default_path.exists();
4509 let secondary_exists = secondary_path.exists();
4511 if !self.owns_directory {
4512 self.span_err(id_sp,
4513 "cannot declare a new module at this location");
4514 let this_module = match self.mod_path_stack.last() {
4515 Some(name) => name.get().to_string(),
4516 None => self.root_module_name.get_ref().clone(),
4518 self.span_note(id_sp,
4519 format!("maybe move this module `{0}` \
4520 to its own directory via \
4522 this_module).as_slice());
4523 if default_exists || secondary_exists {
4524 self.span_note(id_sp,
4525 format!("... or maybe `use` the module \
4526 `{}` instead of possibly \
4528 mod_name).as_slice());
4530 self.abort_if_errors();
4533 match (default_exists, secondary_exists) {
4534 (true, false) => (default_path, false),
4535 (false, true) => (secondary_path, true),
4537 self.span_fatal(id_sp,
4538 format!("file not found for module \
4540 mod_name).as_slice());
4545 format!("file for module `{}` found at both {} \
4549 secondary_path_str).as_slice());
4555 self.eval_src_mod_from_path(file_path, owns_directory,
4556 mod_string.get().to_string(), id_sp)
4559 fn eval_src_mod_from_path(&mut self,
4561 owns_directory: bool,
4563 id_sp: Span) -> (ast::Item_, Vec<ast::Attribute> ) {
4564 let mut included_mod_stack = self.sess.included_mod_stack.borrow_mut();
4565 match included_mod_stack.iter().position(|p| *p == path) {
4567 let mut err = String::from_str("circular modules: ");
4568 let len = included_mod_stack.len();
4569 for p in included_mod_stack.slice(i, len).iter() {
4570 err.push_str(p.display().as_maybe_owned().as_slice());
4571 err.push_str(" -> ");
4573 err.push_str(path.display().as_maybe_owned().as_slice());
4574 self.span_fatal(id_sp, err.as_slice());
4578 included_mod_stack.push(path.clone());
4579 drop(included_mod_stack);
4582 new_sub_parser_from_file(self.sess,
4588 let mod_inner_lo = p0.span.lo;
4589 let (mod_attrs, next) = p0.parse_inner_attrs_and_next();
4590 let first_item_outer_attrs = next;
4591 let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs, mod_inner_lo);
4592 self.sess.included_mod_stack.borrow_mut().pop();
4593 return (ast::ItemMod(m0), mod_attrs);
4596 /// Parse a function declaration from a foreign module
4597 fn parse_item_foreign_fn(&mut self, vis: ast::Visibility,
4598 attrs: Vec<Attribute>) -> Gc<ForeignItem> {
4599 let lo = self.span.lo;
4600 self.expect_keyword(keywords::Fn);
4602 let (ident, generics) = self.parse_fn_header();
4603 let decl = self.parse_fn_decl(true);
4604 let hi = self.span.hi;
4605 self.expect(&token::SEMI);
4606 box(GC) ast::ForeignItem { ident: ident,
4608 node: ForeignItemFn(decl, generics),
4609 id: ast::DUMMY_NODE_ID,
4610 span: mk_sp(lo, hi),
4614 /// Parse a static item from a foreign module
4615 fn parse_item_foreign_static(&mut self, vis: ast::Visibility,
4616 attrs: Vec<Attribute> ) -> Gc<ForeignItem> {
4617 let lo = self.span.lo;
4619 self.expect_keyword(keywords::Static);
4620 let mutbl = self.eat_keyword(keywords::Mut);
4622 let ident = self.parse_ident();
4623 self.expect(&token::COLON);
4624 let ty = self.parse_ty(true);
4625 let hi = self.span.hi;
4626 self.expect(&token::SEMI);
4627 box(GC) ast::ForeignItem {
4630 node: ForeignItemStatic(ty, mutbl),
4631 id: ast::DUMMY_NODE_ID,
4632 span: mk_sp(lo, hi),
4637 /// Parse safe/unsafe and fn
4638 fn parse_fn_style(&mut self) -> FnStyle {
4639 if self.eat_keyword(keywords::Fn) { NormalFn }
4640 else if self.eat_keyword(keywords::Unsafe) {
4641 self.expect_keyword(keywords::Fn);
4644 else { self.unexpected(); }
4648 /// At this point, this is essentially a wrapper for
4649 /// parse_foreign_items.
4650 fn parse_foreign_mod_items(&mut self,
4652 first_item_attrs: Vec<Attribute> )
4654 let ParsedItemsAndViewItems {
4655 attrs_remaining: attrs_remaining,
4656 view_items: view_items,
4658 foreign_items: foreign_items
4659 } = self.parse_foreign_items(first_item_attrs, true);
4660 if ! attrs_remaining.is_empty() {
4661 let last_span = self.last_span;
4662 self.span_err(last_span,
4663 "expected item after attributes");
4665 assert!(self.token == token::RBRACE);
4668 view_items: view_items,
4669 items: foreign_items
4673 /// Parse extern crate links
4677 /// extern crate url;
4678 /// extern crate foo = "bar";
4679 fn parse_item_extern_crate(&mut self,
4681 visibility: Visibility,
4682 attrs: Vec<Attribute> )
4685 let (maybe_path, ident) = match self.token {
4686 token::IDENT(..) => {
4687 let the_ident = self.parse_ident();
4688 self.expect_one_of(&[], &[token::EQ, token::SEMI]);
4689 let path = if self.token == token::EQ {
4691 Some(self.parse_str())
4694 self.expect(&token::SEMI);
4698 let span = self.span;
4699 let token_str = self.this_token_to_string();
4700 self.span_fatal(span,
4701 format!("expected extern crate name but \
4703 token_str).as_slice());
4707 IoviViewItem(ast::ViewItem {
4708 node: ViewItemExternCrate(ident, maybe_path, ast::DUMMY_NODE_ID),
4711 span: mk_sp(lo, self.last_span.hi)
4715 /// Parse `extern` for foreign ABIs
4718 /// `extern` is expected to have been
4719 /// consumed before calling this method
4725 fn parse_item_foreign_mod(&mut self,
4727 opt_abi: Option<abi::Abi>,
4728 visibility: Visibility,
4729 attrs: Vec<Attribute> )
4732 self.expect(&token::LBRACE);
4734 let abi = opt_abi.unwrap_or(abi::C);
4736 let (inner, next) = self.parse_inner_attrs_and_next();
4737 let m = self.parse_foreign_mod_items(abi, next);
4738 self.expect(&token::RBRACE);
4740 let last_span = self.last_span;
4741 let item = self.mk_item(lo,
4743 special_idents::invalid,
4746 maybe_append(attrs, Some(inner)));
4747 return IoviItem(item);
4750 /// Parse type Foo = Bar;
4751 fn parse_item_type(&mut self) -> ItemInfo {
4752 let ident = self.parse_ident();
4753 let tps = self.parse_generics();
4754 self.expect(&token::EQ);
4755 let ty = self.parse_ty(true);
4756 self.expect(&token::SEMI);
4757 (ident, ItemTy(ty, tps), None)
4760 /// Parse a structure-like enum variant definition
4761 /// this should probably be renamed or refactored...
4762 fn parse_struct_def(&mut self) -> Gc<StructDef> {
4763 let mut fields: Vec<StructField> = Vec::new();
4764 while self.token != token::RBRACE {
4765 fields.push(self.parse_struct_decl_field());
4769 return box(GC) ast::StructDef {
4777 /// Parse the part of an "enum" decl following the '{'
4778 fn parse_enum_def(&mut self, _generics: &ast::Generics) -> EnumDef {
4779 let mut variants = Vec::new();
4780 let mut all_nullary = true;
4781 let mut have_disr = false;
4782 while self.token != token::RBRACE {
4783 let variant_attrs = self.parse_outer_attributes();
4784 let vlo = self.span.lo;
4786 let vis = self.parse_visibility();
4790 let mut args = Vec::new();
4791 let mut disr_expr = None;
4792 ident = self.parse_ident();
4793 if self.eat(&token::LBRACE) {
4794 // Parse a struct variant.
4795 all_nullary = false;
4796 kind = StructVariantKind(self.parse_struct_def());
4797 } else if self.token == token::LPAREN {
4798 all_nullary = false;
4799 let arg_tys = self.parse_enum_variant_seq(
4802 seq_sep_trailing_disallowed(token::COMMA),
4803 |p| p.parse_ty(true)
4805 for ty in arg_tys.move_iter() {
4806 args.push(ast::VariantArg {
4808 id: ast::DUMMY_NODE_ID,
4811 kind = TupleVariantKind(args);
4812 } else if self.eat(&token::EQ) {
4814 disr_expr = Some(self.parse_expr());
4815 kind = TupleVariantKind(args);
4817 kind = TupleVariantKind(Vec::new());
4820 let vr = ast::Variant_ {
4822 attrs: variant_attrs,
4824 id: ast::DUMMY_NODE_ID,
4825 disr_expr: disr_expr,
4828 variants.push(P(spanned(vlo, self.last_span.hi, vr)));
4830 if !self.eat(&token::COMMA) { break; }
4832 self.expect(&token::RBRACE);
4833 if have_disr && !all_nullary {
4834 self.fatal("discriminator values can only be used with a c-like \
4838 ast::EnumDef { variants: variants }
4841 /// Parse an "enum" declaration
4842 fn parse_item_enum(&mut self) -> ItemInfo {
4843 let id = self.parse_ident();
4844 let generics = self.parse_generics();
4845 self.expect(&token::LBRACE);
4847 let enum_definition = self.parse_enum_def(&generics);
4848 (id, ItemEnum(enum_definition, generics), None)
4851 fn fn_expr_lookahead(tok: &token::Token) -> bool {
4853 token::LPAREN | token::AT | token::TILDE | token::BINOP(_) => true,
4858 /// Parses a string as an ABI spec on an extern type or module. Consumes
4859 /// the `extern` keyword, if one is found.
4860 fn parse_opt_abi(&mut self) -> Option<abi::Abi> {
4862 token::LIT_STR(s) | token::LIT_STR_RAW(s, _) => {
4864 let the_string = s.as_str();
4865 match abi::lookup(the_string) {
4866 Some(abi) => Some(abi),
4868 let last_span = self.last_span;
4871 format!("illegal ABI: expected one of [{}], \
4873 abi::all_names().connect(", "),
4874 the_string).as_slice());
4884 /// Parse one of the items or view items allowed by the
4885 /// flags; on failure, return IoviNone.
4886 /// NB: this function no longer parses the items inside an
4888 fn parse_item_or_view_item(&mut self,
4889 attrs: Vec<Attribute> ,
4890 macros_allowed: bool)
4893 INTERPOLATED(token::NtItem(item)) => {
4895 let new_attrs = attrs.append(item.attrs.as_slice());
4896 return IoviItem(box(GC) Item {
4904 let lo = self.span.lo;
4906 let visibility = self.parse_visibility();
4908 // must be a view item:
4909 if self.eat_keyword(keywords::Use) {
4910 // USE ITEM (IoviViewItem)
4911 let view_item = self.parse_use();
4912 self.expect(&token::SEMI);
4913 return IoviViewItem(ast::ViewItem {
4917 span: mk_sp(lo, self.last_span.hi)
4920 // either a view item or an item:
4921 if self.eat_keyword(keywords::Extern) {
4922 let next_is_mod = self.eat_keyword(keywords::Mod);
4924 if next_is_mod || self.eat_keyword(keywords::Crate) {
4926 let last_span = self.last_span;
4927 self.span_err(mk_sp(lo, last_span.hi),
4928 format!("`extern mod` is obsolete, use \
4929 `extern crate` instead \
4930 to refer to external \
4931 crates.").as_slice())
4933 return self.parse_item_extern_crate(lo, visibility, attrs);
4936 let opt_abi = self.parse_opt_abi();
4938 if self.eat_keyword(keywords::Fn) {
4939 // EXTERN FUNCTION ITEM
4940 let abi = opt_abi.unwrap_or(abi::C);
4941 let (ident, item_, extra_attrs) =
4942 self.parse_item_fn(NormalFn, abi);
4943 let last_span = self.last_span;
4944 let item = self.mk_item(lo,
4949 maybe_append(attrs, extra_attrs));
4950 return IoviItem(item);
4951 } else if self.token == token::LBRACE {
4952 return self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs);
4955 let span = self.span;
4956 let token_str = self.this_token_to_string();
4957 self.span_fatal(span,
4958 format!("expected `{}` or `fn` but found `{}`", "{",
4959 token_str).as_slice());
4962 let is_virtual = self.eat_keyword(keywords::Virtual);
4963 if is_virtual && !self.is_keyword(keywords::Struct) {
4964 let span = self.span;
4966 "`virtual` keyword may only be used with `struct`");
4969 // the rest are all guaranteed to be items:
4970 if self.is_keyword(keywords::Static) {
4973 let (ident, item_, extra_attrs) = self.parse_item_const();
4974 let last_span = self.last_span;
4975 let item = self.mk_item(lo,
4980 maybe_append(attrs, extra_attrs));
4981 return IoviItem(item);
4983 if self.is_keyword(keywords::Fn) &&
4984 self.look_ahead(1, |f| !Parser::fn_expr_lookahead(f)) {
4987 let (ident, item_, extra_attrs) =
4988 self.parse_item_fn(NormalFn, abi::Rust);
4989 let last_span = self.last_span;
4990 let item = self.mk_item(lo,
4995 maybe_append(attrs, extra_attrs));
4996 return IoviItem(item);
4998 if self.is_keyword(keywords::Unsafe)
4999 && self.look_ahead(1u, |t| *t != token::LBRACE) {
5000 // UNSAFE FUNCTION ITEM
5002 let abi = if self.eat_keyword(keywords::Extern) {
5003 self.parse_opt_abi().unwrap_or(abi::C)
5007 self.expect_keyword(keywords::Fn);
5008 let (ident, item_, extra_attrs) =
5009 self.parse_item_fn(UnsafeFn, abi);
5010 let last_span = self.last_span;
5011 let item = self.mk_item(lo,
5016 maybe_append(attrs, extra_attrs));
5017 return IoviItem(item);
5019 if self.eat_keyword(keywords::Mod) {
5021 let (ident, item_, extra_attrs) =
5022 self.parse_item_mod(attrs.as_slice());
5023 let last_span = self.last_span;
5024 let item = self.mk_item(lo,
5029 maybe_append(attrs, extra_attrs));
5030 return IoviItem(item);
5032 if self.eat_keyword(keywords::Type) {
5034 let (ident, item_, extra_attrs) = self.parse_item_type();
5035 let last_span = self.last_span;
5036 let item = self.mk_item(lo,
5041 maybe_append(attrs, extra_attrs));
5042 return IoviItem(item);
5044 if self.eat_keyword(keywords::Enum) {
5046 let (ident, item_, extra_attrs) = self.parse_item_enum();
5047 let last_span = self.last_span;
5048 let item = self.mk_item(lo,
5053 maybe_append(attrs, extra_attrs));
5054 return IoviItem(item);
5056 if self.eat_keyword(keywords::Trait) {
5058 let (ident, item_, extra_attrs) = self.parse_item_trait();
5059 let last_span = self.last_span;
5060 let item = self.mk_item(lo,
5065 maybe_append(attrs, extra_attrs));
5066 return IoviItem(item);
5068 if self.eat_keyword(keywords::Impl) {
5070 let (ident, item_, extra_attrs) = self.parse_item_impl();
5071 let last_span = self.last_span;
5072 let item = self.mk_item(lo,
5077 maybe_append(attrs, extra_attrs));
5078 return IoviItem(item);
5080 if self.eat_keyword(keywords::Struct) {
5082 let (ident, item_, extra_attrs) = self.parse_item_struct(is_virtual);
5083 let last_span = self.last_span;
5084 let item = self.mk_item(lo,
5089 maybe_append(attrs, extra_attrs));
5090 return IoviItem(item);
5092 self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
5095 /// Parse a foreign item; on failure, return IoviNone.
5096 fn parse_foreign_item(&mut self,
5097 attrs: Vec<Attribute> ,
5098 macros_allowed: bool)
5100 maybe_whole!(iovi self, NtItem);
5101 let lo = self.span.lo;
5103 let visibility = self.parse_visibility();
5105 if self.is_keyword(keywords::Static) {
5106 // FOREIGN STATIC ITEM
5107 let item = self.parse_item_foreign_static(visibility, attrs);
5108 return IoviForeignItem(item);
5110 if self.is_keyword(keywords::Fn) || self.is_keyword(keywords::Unsafe) {
5111 // FOREIGN FUNCTION ITEM
5112 let item = self.parse_item_foreign_fn(visibility, attrs);
5113 return IoviForeignItem(item);
5115 self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
5118 /// This is the fall-through for parsing items.
5119 fn parse_macro_use_or_failure(
5121 attrs: Vec<Attribute> ,
5122 macros_allowed: bool,
5124 visibility: Visibility
5125 ) -> ItemOrViewItem {
5126 if macros_allowed && !token::is_any_keyword(&self.token)
5127 && self.look_ahead(1, |t| *t == token::NOT)
5128 && (self.look_ahead(2, |t| is_plain_ident(t))
5129 || self.look_ahead(2, |t| *t == token::LPAREN)
5130 || self.look_ahead(2, |t| *t == token::LBRACE)) {
5131 // MACRO INVOCATION ITEM
5134 let pth = self.parse_path(NoTypesAllowed).path;
5135 self.expect(&token::NOT);
5137 // a 'special' identifier (like what `macro_rules!` uses)
5138 // is optional. We should eventually unify invoc syntax
5140 let id = if is_plain_ident(&self.token) {
5143 token::special_idents::invalid // no special identifier
5145 // eat a matched-delimiter token tree:
5146 let tts = match token::close_delimiter_for(&self.token) {
5149 self.parse_seq_to_end(&ket,
5151 |p| p.parse_token_tree())
5153 None => self.fatal("expected open delimiter")
5155 // single-variant-enum... :
5156 let m = ast::MacInvocTT(pth, tts, EMPTY_CTXT);
5157 let m: ast::Mac = codemap::Spanned { node: m,
5158 span: mk_sp(self.span.lo,
5160 let item_ = ItemMac(m);
5161 let last_span = self.last_span;
5162 let item = self.mk_item(lo,
5168 return IoviItem(item);
5171 // FAILURE TO PARSE ITEM
5172 if visibility != Inherited {
5173 let mut s = String::from_str("unmatched visibility `");
5174 if visibility == Public {
5180 let last_span = self.last_span;
5181 self.span_fatal(last_span, s.as_slice());
5183 return IoviNone(attrs);
5186 pub fn parse_item_with_outer_attributes(&mut self) -> Option<Gc<Item>> {
5187 let attrs = self.parse_outer_attributes();
5188 self.parse_item(attrs)
5191 pub fn parse_item(&mut self, attrs: Vec<Attribute> ) -> Option<Gc<Item>> {
5192 match self.parse_item_or_view_item(attrs, true) {
5193 IoviNone(_) => None,
5195 self.fatal("view items are not allowed here"),
5196 IoviForeignItem(_) =>
5197 self.fatal("foreign items are not allowed here"),
5198 IoviItem(item) => Some(item)
5202 /// Parse, e.g., "use a::b::{z,y}"
5203 fn parse_use(&mut self) -> ViewItem_ {
5204 return ViewItemUse(self.parse_view_path());
5208 /// Matches view_path : MOD? IDENT EQ non_global_path
5209 /// | MOD? non_global_path MOD_SEP LBRACE RBRACE
5210 /// | MOD? non_global_path MOD_SEP LBRACE ident_seq RBRACE
5211 /// | MOD? non_global_path MOD_SEP STAR
5212 /// | MOD? non_global_path
5213 fn parse_view_path(&mut self) -> Gc<ViewPath> {
5214 let lo = self.span.lo;
5216 if self.token == token::LBRACE {
5218 let idents = self.parse_unspanned_seq(
5219 &token::LBRACE, &token::RBRACE,
5220 seq_sep_trailing_allowed(token::COMMA),
5221 |p| p.parse_path_list_item());
5222 let path = ast::Path {
5223 span: mk_sp(lo, self.span.hi),
5225 segments: Vec::new()
5227 return box(GC) spanned(lo, self.span.hi,
5228 ViewPathList(path, idents, ast::DUMMY_NODE_ID));
5231 let first_ident = self.parse_ident();
5232 let mut path = vec!(first_ident);
5237 let path_lo = self.span.lo;
5238 path = vec!(self.parse_ident());
5239 while self.token == token::MOD_SEP {
5241 let id = self.parse_ident();
5244 let path = ast::Path {
5245 span: mk_sp(path_lo, self.span.hi),
5247 segments: path.move_iter().map(|identifier| {
5249 identifier: identifier,
5250 lifetimes: Vec::new(),
5251 types: OwnedSlice::empty(),
5255 return box(GC) spanned(lo, self.span.hi,
5256 ViewPathSimple(first_ident, path,
5257 ast::DUMMY_NODE_ID));
5261 // foo::bar or foo::{a,b,c} or foo::*
5262 while self.token == token::MOD_SEP {
5266 token::IDENT(i, _) => {
5271 // foo::bar::{a,b,c}
5273 let idents = self.parse_unspanned_seq(
5276 seq_sep_trailing_allowed(token::COMMA),
5277 |p| p.parse_path_list_item()
5279 let path = ast::Path {
5280 span: mk_sp(lo, self.span.hi),
5282 segments: path.move_iter().map(|identifier| {
5284 identifier: identifier,
5285 lifetimes: Vec::new(),
5286 types: OwnedSlice::empty(),
5290 return box(GC) spanned(lo, self.span.hi,
5291 ViewPathList(path, idents, ast::DUMMY_NODE_ID));
5295 token::BINOP(token::STAR) => {
5297 let path = ast::Path {
5298 span: mk_sp(lo, self.span.hi),
5300 segments: path.move_iter().map(|identifier| {
5302 identifier: identifier,
5303 lifetimes: Vec::new(),
5304 types: OwnedSlice::empty(),
5308 return box(GC) spanned(lo, self.span.hi,
5309 ViewPathGlob(path, ast::DUMMY_NODE_ID));
5318 let last = *path.get(path.len() - 1u);
5319 let path = ast::Path {
5320 span: mk_sp(lo, self.span.hi),
5322 segments: path.move_iter().map(|identifier| {
5324 identifier: identifier,
5325 lifetimes: Vec::new(),
5326 types: OwnedSlice::empty(),
5330 return box(GC) spanned(lo,
5332 ViewPathSimple(last, path, ast::DUMMY_NODE_ID));
5335 /// Parses a sequence of items. Stops when it finds program
5336 /// text that can't be parsed as an item
5337 /// - mod_items uses extern_mod_allowed = true
5338 /// - block_tail_ uses extern_mod_allowed = false
5339 fn parse_items_and_view_items(&mut self,
5340 first_item_attrs: Vec<Attribute> ,
5341 mut extern_mod_allowed: bool,
5342 macros_allowed: bool)
5343 -> ParsedItemsAndViewItems {
5344 let mut attrs = first_item_attrs.append(self.parse_outer_attributes().as_slice());
5345 // First, parse view items.
5346 let mut view_items : Vec<ast::ViewItem> = Vec::new();
5347 let mut items = Vec::new();
5349 // I think this code would probably read better as a single
5350 // loop with a mutable three-state-variable (for extern crates,
5351 // view items, and regular items) ... except that because
5352 // of macros, I'd like to delay that entire check until later.
5354 match self.parse_item_or_view_item(attrs, macros_allowed) {
5355 IoviNone(attrs) => {
5356 return ParsedItemsAndViewItems {
5357 attrs_remaining: attrs,
5358 view_items: view_items,
5360 foreign_items: Vec::new()
5363 IoviViewItem(view_item) => {
5364 match view_item.node {
5365 ViewItemUse(..) => {
5366 // `extern crate` must precede `use`.
5367 extern_mod_allowed = false;
5369 ViewItemExternCrate(..) if !extern_mod_allowed => {
5370 self.span_err(view_item.span,
5371 "\"extern crate\" declarations are \
5374 ViewItemExternCrate(..) => {}
5376 view_items.push(view_item);
5380 attrs = self.parse_outer_attributes();
5383 IoviForeignItem(_) => {
5387 attrs = self.parse_outer_attributes();
5390 // Next, parse items.
5392 match self.parse_item_or_view_item(attrs, macros_allowed) {
5393 IoviNone(returned_attrs) => {
5394 attrs = returned_attrs;
5397 IoviViewItem(view_item) => {
5398 attrs = self.parse_outer_attributes();
5399 self.span_err(view_item.span,
5400 "`use` and `extern crate` declarations must precede items");
5403 attrs = self.parse_outer_attributes();
5406 IoviForeignItem(_) => {
5412 ParsedItemsAndViewItems {
5413 attrs_remaining: attrs,
5414 view_items: view_items,
5416 foreign_items: Vec::new()
5420 /// Parses a sequence of foreign items. Stops when it finds program
5421 /// text that can't be parsed as an item
5422 fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute> ,
5423 macros_allowed: bool)
5424 -> ParsedItemsAndViewItems {
5425 let mut attrs = first_item_attrs.append(self.parse_outer_attributes().as_slice());
5426 let mut foreign_items = Vec::new();
5428 match self.parse_foreign_item(attrs, macros_allowed) {
5429 IoviNone(returned_attrs) => {
5430 if self.token == token::RBRACE {
5431 attrs = returned_attrs;
5436 IoviViewItem(view_item) => {
5437 // I think this can't occur:
5438 self.span_err(view_item.span,
5439 "`use` and `extern crate` declarations must precede items");
5442 // FIXME #5668: this will occur for a macro invocation:
5443 self.span_fatal(item.span, "macros cannot expand to foreign items");
5445 IoviForeignItem(foreign_item) => {
5446 foreign_items.push(foreign_item);
5449 attrs = self.parse_outer_attributes();
5452 ParsedItemsAndViewItems {
5453 attrs_remaining: attrs,
5454 view_items: Vec::new(),
5456 foreign_items: foreign_items
5460 /// Parses a source module as a crate. This is the main
5461 /// entry point for the parser.
5462 pub fn parse_crate_mod(&mut self) -> Crate {
5463 let lo = self.span.lo;
5464 // parse the crate's inner attrs, maybe (oops) one
5465 // of the attrs of an item:
5466 let (inner, next) = self.parse_inner_attrs_and_next();
5467 let first_item_outer_attrs = next;
5468 // parse the items inside the crate:
5469 let m = self.parse_mod_items(token::EOF, first_item_outer_attrs, lo);
5474 config: self.cfg.clone(),
5475 span: mk_sp(lo, self.span.lo),
5476 exported_macros: Vec::new(),
5480 pub fn parse_optional_str(&mut self)
5481 -> Option<(InternedString, ast::StrStyle)> {
5482 let (s, style) = match self.token {
5483 token::LIT_STR(s) => (self.id_to_interned_str(s.ident()), ast::CookedStr),
5484 token::LIT_STR_RAW(s, n) => {
5485 (self.id_to_interned_str(s.ident()), ast::RawStr(n))
5493 pub fn parse_str(&mut self) -> (InternedString, StrStyle) {
5494 match self.parse_optional_str() {
5496 _ => self.fatal("expected string literal")