1 // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
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.
15 use ast::{Sigil, BorrowedSigil, ManagedSigil, OwnedSigil};
16 use ast::{BareFnTy, ClosureTy};
17 use ast::{RegionTyParamBound, TraitTyParamBound};
18 use ast::{Provided, Public, Purity};
19 use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue};
20 use ast::{BiBitAnd, BiBitOr, BiBitXor, Block};
21 use ast::{BlockCheckMode, UnBox};
22 use ast::{Crate, CrateConfig, Decl, DeclItem};
23 use ast::{DeclLocal, DefaultBlock, UnDeref, BiDiv, EMPTY_CTXT, EnumDef, ExplicitSelf};
24 use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain};
25 use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox};
26 use ast::{ExprBreak, ExprCall, ExprCast};
27 use ast::{ExprField, ExprFnBlock, ExprIf, ExprIndex};
28 use ast::{ExprLit, ExprLoop, ExprMac};
29 use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc};
30 use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary};
31 use ast::{ExprVec, ExprVstore, ExprVstoreSlice};
32 use ast::{ExprVstoreMutSlice, ExprWhile, ExprForLoop, ExternFn, Field, FnDecl};
33 use ast::{ExprVstoreUniq, Onceness, Once, Many};
34 use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod};
35 use ast::{Ident, ImpureFn, Inherited, Item, Item_, ItemStatic};
36 use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl};
37 use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy, Lit, Lit_};
38 use ast::{LitBool, LitFloat, LitFloatUnsuffixed, LitInt, LitChar};
39 use ast::{LitIntUnsuffixed, LitNil, LitStr, LitUint, Local};
40 use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, Matcher, MatchNonterminal};
41 use ast::{MatchSeq, MatchTok, Method, MutTy, BiMul, Mutability};
42 use ast::{NamedField, UnNeg, NoReturn, UnNot, P, Pat, PatEnum};
43 use ast::{PatIdent, PatLit, PatRange, PatRegion, PatStruct};
44 use ast::{PatTup, PatUniq, PatWild, PatWildMulti, Private};
45 use ast::{BiRem, Required};
46 use ast::{RetStyle, Return, BiShl, BiShr, Stmt, StmtDecl};
47 use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField};
48 use ast::{StructVariantKind, BiSub};
50 use ast::{SelfRegion, SelfStatic, SelfUniq, SelfValue};
51 use ast::{TokenTree, TraitMethod, TraitRef, TTDelim, TTSeq, TTTok};
52 use ast::{TTNonterminal, TupleVariantKind, Ty, Ty_, TyBot, TyBox};
53 use ast::{TypeField, TyFixedLengthVec, TyClosure, TyBareFn, TyTypeof};
54 use ast::{TyInfer, TypeMethod};
55 use ast::{TyNil, TyParam, TyParamBound, TyPath, TyPtr, TyRptr};
56 use ast::{TyTup, TyU32, TyUniq, TyVec, UnUniq};
57 use ast::{UnnamedField, UnsafeBlock, UnsafeFn, ViewItem};
58 use ast::{ViewItem_, ViewItemExternCrate, ViewItemUse};
59 use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
62 use ast_util::{as_prec, lit_is_str, operator_prec};
64 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 collections::HashSet;
81 use std::kinds::marker;
82 use std::mem::replace;
85 #[allow(non_camel_case_types)]
87 pub enum restriction {
91 RESTRICT_NO_BAR_OR_DOUBLEBAR_OP,
94 type ItemInfo = (Ident, Item_, Option<Vec<Attribute> >);
96 /// How to parse a path. There are four different kinds of paths, all of which
97 /// are parsed somewhat differently.
99 pub enum PathParsingMode {
100 /// A path with no type parameters; e.g. `foo::bar::Baz`
102 /// A path with a lifetime and type parameters, with no double colons
103 /// before the type parameters; e.g. `foo::bar<'a>::Baz<T>`
104 LifetimeAndTypesWithoutColons,
105 /// A path with a lifetime and type parameters with double colons before
106 /// the type parameters; e.g. `foo::bar::<'a>::Baz::<T>`
107 LifetimeAndTypesWithColons,
108 /// A path with a lifetime and type parameters with bounds before the last
109 /// set of type parameters only; e.g. `foo::bar<'a>::Baz:X+Y<T>` This
110 /// form does not use extra double colons.
111 LifetimeAndTypesAndBounds,
114 /// A path paired with optional type bounds.
115 pub struct PathAndBounds {
117 bounds: Option<OwnedSlice<TyParamBound>>,
120 enum ItemOrViewItem {
121 // Indicates a failure to parse any kind of item. The attributes are
123 IoviNone(Vec<Attribute> ),
125 IoviForeignItem(@ForeignItem),
126 IoviViewItem(ViewItem)
129 /* The expr situation is not as complex as I thought it would be.
130 The important thing is to make sure that lookahead doesn't balk
131 at INTERPOLATED tokens */
132 macro_rules! maybe_whole_expr (
135 let mut maybe_path = match ($p).token {
136 INTERPOLATED(token::NtPath(ref pt)) => Some((**pt).clone()),
139 let ret = match ($p).token {
140 INTERPOLATED(token::NtExpr(e)) => {
143 INTERPOLATED(token::NtPath(_)) => {
144 let pt = maybe_path.take_unwrap();
145 Some($p.mk_expr(($p).span.lo, ($p).span.hi, ExprPath(pt)))
160 macro_rules! maybe_whole (
161 ($p:expr, $constructor:ident) => (
163 let __found__ = match ($p).token {
164 INTERPOLATED(token::$constructor(_)) => {
165 Some(($p).bump_and_get())
170 Some(INTERPOLATED(token::$constructor(x))) => {
177 (no_clone $p:expr, $constructor:ident) => (
179 let __found__ = match ($p).token {
180 INTERPOLATED(token::$constructor(_)) => {
181 Some(($p).bump_and_get())
186 Some(INTERPOLATED(token::$constructor(x))) => {
193 (deref $p:expr, $constructor:ident) => (
195 let __found__ = match ($p).token {
196 INTERPOLATED(token::$constructor(_)) => {
197 Some(($p).bump_and_get())
202 Some(INTERPOLATED(token::$constructor(x))) => {
209 (Some $p:expr, $constructor:ident) => (
211 let __found__ = match ($p).token {
212 INTERPOLATED(token::$constructor(_)) => {
213 Some(($p).bump_and_get())
218 Some(INTERPOLATED(token::$constructor(x))) => {
219 return Some(x.clone()),
225 (iovi $p:expr, $constructor:ident) => (
227 let __found__ = match ($p).token {
228 INTERPOLATED(token::$constructor(_)) => {
229 Some(($p).bump_and_get())
234 Some(INTERPOLATED(token::$constructor(x))) => {
235 return IoviItem(x.clone())
241 (pair_empty $p:expr, $constructor:ident) => (
243 let __found__ = match ($p).token {
244 INTERPOLATED(token::$constructor(_)) => {
245 Some(($p).bump_and_get())
250 Some(INTERPOLATED(token::$constructor(x))) => {
251 return (Vec::new(), x)
260 fn maybe_append(lhs: Vec<Attribute> , rhs: Option<Vec<Attribute> >)
264 Some(ref attrs) => vec::append(lhs, attrs.as_slice())
269 struct ParsedItemsAndViewItems {
270 attrs_remaining: Vec<Attribute> ,
271 view_items: Vec<ViewItem> ,
273 foreign_items: Vec<@ForeignItem> }
275 /* ident is handled by common.rs */
277 pub fn Parser<'a>(sess: &'a ParseSess, cfg: ast::CrateConfig, rdr: ~Reader:)
279 let tok0 = rdr.next_token();
281 let placeholder = TokenAndSpan {
282 tok: token::UNDERSCORE,
288 interner: token::get_ident_interner(),
304 restriction: UNRESTRICTED,
306 obsolete_set: HashSet::new(),
307 mod_path_stack: Vec::new(),
308 open_braces: Vec::new(),
309 nocopy: marker::NoCopy
313 pub struct Parser<'a> {
316 // the current token:
318 // the span of the current token:
320 // the span of the prior token:
322 // the previous token or None (only stashed sometimes).
323 last_token: Option<~token::Token>,
324 buffer: [TokenAndSpan, ..4],
327 tokens_consumed: uint,
328 restriction: restriction,
329 quote_depth: uint, // not (yet) related to the quasiquoter
331 interner: @token::IdentInterner,
332 /// The set of seen errors about obsolete syntax. Used to suppress
333 /// extra detail when the same error is seen twice
334 obsolete_set: HashSet<ObsoleteSyntax>,
335 /// Used to determine the path to externally loaded source files
336 mod_path_stack: Vec<InternedString> ,
337 /// Stack of spans of open delimiters. Used for error message.
338 open_braces: Vec<Span> ,
339 /* do not copy the parser; its state is tied to outside state */
340 priv nocopy: marker::NoCopy
343 fn is_plain_ident_or_underscore(t: &token::Token) -> bool {
344 is_plain_ident(t) || *t == token::UNDERSCORE
347 impl<'a> Parser<'a> {
348 // convert a token to a string using self's reader
349 pub fn token_to_str(token: &token::Token) -> ~str {
353 // convert the current token to a string using self's reader
354 pub fn this_token_to_str(&mut self) -> ~str {
355 Parser::token_to_str(&self.token)
358 pub fn unexpected_last(&mut self, t: &token::Token) -> ! {
359 let token_str = Parser::token_to_str(t);
360 self.span_fatal(self.last_span, format!("unexpected token: `{}`",
364 pub fn unexpected(&mut self) -> ! {
365 let this_token = self.this_token_to_str();
366 self.fatal(format!("unexpected token: `{}`", this_token));
369 // expect and consume the token t. Signal an error if
370 // the next token is not t.
371 pub fn expect(&mut self, t: &token::Token) {
372 if self.token == *t {
375 let token_str = Parser::token_to_str(t);
376 let this_token_str = self.this_token_to_str();
377 self.fatal(format!("expected `{}` but found `{}`",
383 // Expect next token to be edible or inedible token. If edible,
384 // then consume it; if inedible, then return without consuming
385 // anything. Signal a fatal error if next token is unexpected.
386 pub fn expect_one_of(&mut self,
387 edible: &[token::Token],
388 inedible: &[token::Token]) {
389 fn tokens_to_str(tokens: &[token::Token]) -> ~str {
390 let mut i = tokens.iter();
391 // This might be a sign we need a connect method on Iterator.
392 let b = i.next().map_or(~"", |t| Parser::token_to_str(t));
393 i.fold(b, |b,a| b + "`, `" + Parser::token_to_str(a))
395 if edible.contains(&self.token) {
397 } else if inedible.contains(&self.token) {
398 // leave it in the input
400 let expected = vec::append(edible.iter()
401 .map(|x| (*x).clone())
404 let expect = tokens_to_str(expected.as_slice());
405 let actual = self.this_token_to_str();
407 if expected.len() != 1 {
408 format!("expected one of `{}` but found `{}`", expect, actual)
410 format!("expected `{}` but found `{}`", expect, actual)
416 // Check for erroneous `ident { }`; if matches, signal error and
417 // recover (without consuming any expected input token). Returns
418 // true if and only if input was consumed for recovery.
419 pub fn check_for_erroneous_unit_struct_expecting(&mut self, expected: &[token::Token]) -> bool {
420 if self.token == token::LBRACE
421 && expected.iter().all(|t| *t != token::LBRACE)
422 && self.look_ahead(1, |t| *t == token::RBRACE) {
423 // matched; signal non-fatal error and recover.
424 self.span_err(self.span,
425 "unit-like struct construction is written with no trailing `{ }`");
426 self.eat(&token::LBRACE);
427 self.eat(&token::RBRACE);
434 // Commit to parsing a complete expression `e` expected to be
435 // followed by some token from the set edible + inedible. Recover
436 // from anticipated input errors, discarding erroneous characters.
437 pub fn commit_expr(&mut self, e: @Expr, edible: &[token::Token], inedible: &[token::Token]) {
438 debug!("commit_expr {:?}", e);
441 // might be unit-struct construction; check for recoverableinput error.
442 let expected = vec::append(edible.iter()
443 .map(|x| (*x).clone())
446 self.check_for_erroneous_unit_struct_expecting(
447 expected.as_slice());
451 self.expect_one_of(edible, inedible)
454 pub fn commit_expr_expecting(&mut self, e: @Expr, edible: token::Token) {
455 self.commit_expr(e, &[edible], &[])
458 // Commit to parsing a complete statement `s`, which expects to be
459 // followed by some token from the set edible + inedible. Check
460 // for recoverable input errors, discarding erroneous characters.
461 pub fn commit_stmt(&mut self, s: @Stmt, edible: &[token::Token], inedible: &[token::Token]) {
462 debug!("commit_stmt {:?}", s);
463 let _s = s; // unused, but future checks might want to inspect `s`.
464 if self.last_token.as_ref().map_or(false, |t| is_ident_or_path(*t)) {
465 let expected = vec::append(edible.iter()
466 .map(|x| (*x).clone())
468 inedible.as_slice());
469 self.check_for_erroneous_unit_struct_expecting(
470 expected.as_slice());
472 self.expect_one_of(edible, inedible)
475 pub fn commit_stmt_expecting(&mut self, s: @Stmt, edible: token::Token) {
476 self.commit_stmt(s, &[edible], &[])
479 pub fn parse_ident(&mut self) -> ast::Ident {
480 self.check_strict_keywords();
481 self.check_reserved_keywords();
483 token::IDENT(i, _) => {
487 token::INTERPOLATED(token::NtIdent(..)) => {
488 self.bug("ident interpolation not converted to real token");
491 let token_str = self.this_token_to_str();
492 self.fatal(format!( "expected ident, found `{}`", token_str))
497 pub fn parse_path_list_ident(&mut self) -> ast::PathListIdent {
498 let lo = self.span.lo;
499 let ident = self.parse_ident();
500 let hi = self.last_span.hi;
501 spanned(lo, hi, ast::PathListIdent_ { name: ident,
502 id: ast::DUMMY_NODE_ID })
505 // consume token 'tok' if it exists. Returns true if the given
506 // token was present, false otherwise.
507 pub fn eat(&mut self, tok: &token::Token) -> bool {
508 let is_present = self.token == *tok;
509 if is_present { self.bump() }
513 pub fn is_keyword(&mut self, kw: keywords::Keyword) -> bool {
514 token::is_keyword(kw, &self.token)
517 // if the next token is the given keyword, eat it and return
518 // true. Otherwise, return false.
519 pub fn eat_keyword(&mut self, kw: keywords::Keyword) -> bool {
520 let is_kw = match self.token {
521 token::IDENT(sid, false) => kw.to_ident().name == sid.name,
524 if is_kw { self.bump() }
528 // if the given word is not a keyword, signal an error.
529 // if the next token is not the given word, signal an error.
530 // otherwise, eat it.
531 pub fn expect_keyword(&mut self, kw: keywords::Keyword) {
532 if !self.eat_keyword(kw) {
533 let id_interned_str = token::get_ident(kw.to_ident());
534 let token_str = self.this_token_to_str();
535 self.fatal(format!("expected `{}`, found `{}`",
536 id_interned_str, token_str))
540 // signal an error if the given string is a strict keyword
541 pub fn check_strict_keywords(&mut self) {
542 if token::is_strict_keyword(&self.token) {
543 let token_str = self.this_token_to_str();
544 self.span_err(self.span,
545 format!("found `{}` in ident position", token_str));
549 // signal an error if the current token is a reserved keyword
550 pub fn check_reserved_keywords(&mut self) {
551 if token::is_reserved_keyword(&self.token) {
552 let token_str = self.this_token_to_str();
553 self.fatal(format!("`{}` is a reserved keyword", token_str))
557 // Expect and consume a `|`. If `||` is seen, replace it with a single
558 // `|` and continue. If a `|` is not seen, signal an error.
559 fn expect_or(&mut self) {
561 token::BINOP(token::OR) => self.bump(),
563 let lo = self.span.lo + BytePos(1);
564 self.replace_token(token::BINOP(token::OR), lo, self.span.hi)
567 let token_str = self.this_token_to_str();
569 Parser::token_to_str(&token::BINOP(token::OR));
570 self.fatal(format!("expected `{}`, found `{}`",
577 // Parse a sequence bracketed by `|` and `|`, stopping before the `|`.
578 fn parse_seq_to_before_or<T>(
581 f: |&mut Parser| -> T)
583 let mut first = true;
584 let mut vector = Vec::new();
585 while self.token != token::BINOP(token::OR) &&
586 self.token != token::OROR {
598 // expect and consume a GT. if a >> is seen, replace it
599 // with a single > and continue. If a GT is not seen,
601 pub fn expect_gt(&mut self) {
603 token::GT => self.bump(),
604 token::BINOP(token::SHR) => {
605 let lo = self.span.lo + BytePos(1);
606 self.replace_token(token::GT, lo, self.span.hi)
609 let gt_str = Parser::token_to_str(&token::GT);
610 let this_token_str = self.this_token_to_str();
611 self.fatal(format!("expected `{}`, found `{}`",
618 // parse a sequence bracketed by '<' and '>', stopping
620 pub fn parse_seq_to_before_gt<T>(
622 sep: Option<token::Token>,
623 f: |&mut Parser| -> T)
625 let mut first = true;
626 let mut v = Vec::new();
627 while self.token != token::GT
628 && self.token != token::BINOP(token::SHR) {
631 if first { first = false; }
632 else { self.expect(t); }
638 return OwnedSlice::from_vec(v);
641 pub fn parse_seq_to_gt<T>(
643 sep: Option<token::Token>,
644 f: |&mut Parser| -> T)
646 let v = self.parse_seq_to_before_gt(sep, f);
651 // parse a sequence, including the closing delimiter. The function
652 // f must consume tokens until reaching the next separator or
654 pub fn parse_seq_to_end<T>(
658 f: |&mut Parser| -> T)
660 let val = self.parse_seq_to_before_end(ket, sep, f);
665 // parse a sequence, not including the closing delimiter. The function
666 // f must consume tokens until reaching the next separator or
668 pub fn parse_seq_to_before_end<T>(
672 f: |&mut Parser| -> T)
674 let mut first: bool = true;
676 while self.token != *ket {
679 if first { first = false; }
680 else { self.expect(t); }
684 if sep.trailing_sep_allowed && self.token == *ket { break; }
690 // parse a sequence, including the closing delimiter. The function
691 // f must consume tokens until reaching the next separator or
693 pub fn parse_unspanned_seq<T>(
698 f: |&mut Parser| -> T)
701 let result = self.parse_seq_to_before_end(ket, sep, f);
706 // parse a sequence parameter of enum variant. For consistency purposes,
707 // these should not be empty.
708 pub fn parse_enum_variant_seq<T>(
713 f: |&mut Parser| -> T)
715 let result = self.parse_unspanned_seq(bra, ket, sep, f);
716 if result.is_empty() {
717 self.span_err(self.last_span,
718 "nullary enum variants are written with no trailing `( )`");
723 // NB: Do not use this function unless you actually plan to place the
724 // spanned list in the AST.
730 f: |&mut Parser| -> T)
731 -> Spanned<Vec<T> > {
732 let lo = self.span.lo;
734 let result = self.parse_seq_to_before_end(ket, sep, f);
735 let hi = self.span.hi;
737 spanned(lo, hi, result)
740 // advance the parser by one token
741 pub fn bump(&mut self) {
742 self.last_span = self.span;
743 // Stash token for error recovery (sometimes; clone is not necessarily cheap).
744 self.last_token = if is_ident_or_path(&self.token) {
745 Some(~self.token.clone())
749 let next = if self.buffer_start == self.buffer_end {
750 self.reader.next_token()
752 // Avoid token copies with `replace`.
753 let buffer_start = self.buffer_start as uint;
754 let next_index = (buffer_start + 1) & 3 as uint;
755 self.buffer_start = next_index as int;
757 let placeholder = TokenAndSpan {
758 tok: token::UNDERSCORE,
761 replace(&mut self.buffer[buffer_start], placeholder)
764 self.token = next.tok;
765 self.tokens_consumed += 1u;
768 // Advance the parser by one token and return the bumped token.
769 pub fn bump_and_get(&mut self) -> token::Token {
770 let old_token = replace(&mut self.token, token::UNDERSCORE);
775 // EFFECT: replace the current token and span with the given one
776 pub fn replace_token(&mut self,
780 self.last_span = mk_sp(self.span.lo, lo);
782 self.span = mk_sp(lo, hi);
784 pub fn buffer_length(&mut self) -> int {
785 if self.buffer_start <= self.buffer_end {
786 return self.buffer_end - self.buffer_start;
788 return (4 - self.buffer_start) + self.buffer_end;
790 pub fn look_ahead<R>(&mut self, distance: uint, f: |&token::Token| -> R)
792 let dist = distance as int;
793 while self.buffer_length() < dist {
794 self.buffer[self.buffer_end] = self.reader.next_token();
795 self.buffer_end = (self.buffer_end + 1) & 3;
797 f(&self.buffer[(self.buffer_start + dist - 1) & 3].tok)
799 pub fn fatal(&mut self, m: &str) -> ! {
800 self.sess.span_diagnostic.span_fatal(self.span, m)
802 pub fn span_fatal(&mut self, sp: Span, m: &str) -> ! {
803 self.sess.span_diagnostic.span_fatal(sp, m)
805 pub fn span_note(&mut self, sp: Span, m: &str) {
806 self.sess.span_diagnostic.span_note(sp, m)
808 pub fn bug(&mut self, m: &str) -> ! {
809 self.sess.span_diagnostic.span_bug(self.span, m)
811 pub fn warn(&mut self, m: &str) {
812 self.sess.span_diagnostic.span_warn(self.span, m)
814 pub fn span_warn(&mut self, sp: Span, m: &str) {
815 self.sess.span_diagnostic.span_warn(sp, m)
817 pub fn span_err(&mut self, sp: Span, m: &str) {
818 self.sess.span_diagnostic.span_err(sp, m)
820 pub fn abort_if_errors(&mut self) {
821 self.sess.span_diagnostic.handler().abort_if_errors();
824 pub fn id_to_interned_str(&mut self, id: Ident) -> InternedString {
828 // Is the current token one of the keywords that signals a bare function
830 pub fn token_is_bare_fn_keyword(&mut self) -> bool {
831 if token::is_keyword(keywords::Fn, &self.token) {
835 if token::is_keyword(keywords::Unsafe, &self.token) ||
836 token::is_keyword(keywords::Once, &self.token) {
837 return self.look_ahead(1, |t| token::is_keyword(keywords::Fn, t))
843 // Is the current token one of the keywords that signals a closure type?
844 pub fn token_is_closure_keyword(&mut self) -> bool {
845 token::is_keyword(keywords::Unsafe, &self.token) ||
846 token::is_keyword(keywords::Once, &self.token)
849 // Is the current token one of the keywords that signals an old-style
850 // closure type (with explicit sigil)?
851 pub fn token_is_old_style_closure_keyword(&mut self) -> bool {
852 token::is_keyword(keywords::Unsafe, &self.token) ||
853 token::is_keyword(keywords::Once, &self.token) ||
854 token::is_keyword(keywords::Fn, &self.token)
857 pub fn token_is_lifetime(tok: &token::Token) -> bool {
859 token::LIFETIME(..) => true,
864 pub fn get_lifetime(&mut self) -> ast::Ident {
866 token::LIFETIME(ref ident) => *ident,
867 _ => self.bug("not a lifetime"),
871 // parse a TyBareFn type:
872 pub fn parse_ty_bare_fn(&mut self) -> Ty_ {
875 [extern "ABI"] [unsafe] fn <'lt> (S) -> T
876 ^~~~^ ^~~~~~~^ ^~~~^ ^~^ ^
887 let abis = if self.eat_keyword(keywords::Extern) {
888 self.parse_opt_abis().unwrap_or(AbiSet::C())
893 let purity = self.parse_unsafety();
894 self.expect_keyword(keywords::Fn);
895 let (decl, lifetimes) = self.parse_ty_fn_decl(true);
896 return TyBareFn(@BareFnTy {
899 lifetimes: lifetimes,
904 // Parses a procedure type (`proc`). The initial `proc` keyword must
905 // already have been parsed.
906 pub fn parse_proc_type(&mut self) -> Ty_ {
907 let bounds = self.parse_optional_ty_param_bounds();
908 let (decl, lifetimes) = self.parse_ty_fn_decl(false);
909 TyClosure(@ClosureTy {
916 lifetimes: lifetimes,
920 // parse a TyClosure type
921 pub fn parse_ty_closure(&mut self,
922 opt_sigil: Option<ast::Sigil>,
923 mut region: Option<ast::Lifetime>)
927 (&|~|@) ['r] [unsafe] [once] fn [:Bounds] <'lt> (S) -> T
928 ^~~~~~^ ^~~^ ^~~~~~~^ ^~~~~^ ^~~~~~~~^ ^~~~^ ^~^ ^
930 | | | | | | | Return type
931 | | | | | | Argument types
933 | | | | Closure bounds
934 | | | Once-ness (a.k.a., affine)
941 // At this point, the allocation type and lifetime bound have been
944 let purity = self.parse_unsafety();
945 let onceness = parse_onceness(self);
947 let (sigil, decl, lifetimes, bounds) = match opt_sigil {
949 // Old-style closure syntax (`fn(A)->B`).
950 self.expect_keyword(keywords::Fn);
951 let bounds = self.parse_optional_ty_param_bounds();
952 let (decl, lifetimes) = self.parse_ty_fn_decl(false);
953 (sigil, decl, lifetimes, bounds)
956 // New-style closure syntax (`<'lt>|A|:K -> B`).
957 let lifetimes = if self.eat(&token::LT) {
958 let lifetimes = self.parse_lifetimes();
961 // Re-parse the region here. What a hack.
962 if region.is_some() {
963 self.span_err(self.last_span,
964 "lifetime declarations must precede \
965 the lifetime associated with a \
968 region = self.parse_opt_lifetime();
975 let inputs = if self.eat(&token::OROR) {
979 let inputs = self.parse_seq_to_before_or(
981 |p| p.parse_arg_general(false));
986 let bounds = self.parse_optional_ty_param_bounds();
988 let (return_style, output) = self.parse_ret_ty();
989 let decl = P(FnDecl {
996 (BorrowedSigil, decl, lifetimes, bounds)
1000 return TyClosure(@ClosureTy {
1007 lifetimes: lifetimes,
1010 fn parse_onceness(this: &mut Parser) -> Onceness {
1011 if this.eat_keyword(keywords::Once) {
1019 pub fn parse_unsafety(&mut self) -> Purity {
1020 if self.eat_keyword(keywords::Unsafe) {
1027 // parse a function type (following the 'fn')
1028 pub fn parse_ty_fn_decl(&mut self, allow_variadic: bool)
1029 -> (P<FnDecl>, Vec<ast::Lifetime>) {
1040 let lifetimes = if self.eat(&token::LT) {
1041 let lifetimes = self.parse_lifetimes();
1048 let (inputs, variadic) = self.parse_fn_args(false, allow_variadic);
1049 let (ret_style, ret_ty) = self.parse_ret_ty();
1050 let decl = P(FnDecl {
1059 // parse the methods in a trait declaration
1060 pub fn parse_trait_methods(&mut self) -> Vec<TraitMethod> {
1061 self.parse_unspanned_seq(
1066 let attrs = p.parse_outer_attributes();
1069 let vis_span = p.span;
1070 let vis = p.parse_visibility();
1071 let pur = p.parse_fn_purity();
1072 // NB: at the moment, trait methods are public by default; this
1074 let ident = p.parse_ident();
1076 let generics = p.parse_generics();
1078 let (explicit_self, d) = p.parse_fn_decl_with_self(|p| {
1079 // This is somewhat dubious; We don't want to allow argument
1080 // names to be left off if there is a definition...
1081 p.parse_arg_general(false)
1084 let hi = p.last_span.hi;
1088 debug!("parse_trait_methods(): parsing required method");
1089 // NB: at the moment, visibility annotations on required
1090 // methods are ignored; this could change.
1091 if vis != ast::Inherited {
1092 p.obsolete(vis_span, ObsoleteTraitFuncVisibility);
1094 Required(TypeMethod {
1100 explicit_self: explicit_self,
1101 id: ast::DUMMY_NODE_ID,
1106 debug!("parse_trait_methods(): parsing provided method");
1107 let (inner_attrs, body) =
1108 p.parse_inner_attrs_and_block();
1109 let attrs = vec::append(attrs, inner_attrs.as_slice());
1110 Provided(@ast::Method {
1114 explicit_self: explicit_self,
1118 id: ast::DUMMY_NODE_ID,
1119 span: mk_sp(lo, hi),
1125 let token_str = p.this_token_to_str();
1126 p.fatal(format!("expected `;` or `\\{` but found `{}`",
1133 // parse a possibly mutable type
1134 pub fn parse_mt(&mut self) -> MutTy {
1135 let mutbl = self.parse_mutability();
1136 let t = self.parse_ty(false);
1137 MutTy { ty: t, mutbl: mutbl }
1140 // parse [mut/const/imm] ID : TY
1141 // now used only by obsolete record syntax parser...
1142 pub fn parse_ty_field(&mut self) -> TypeField {
1143 let lo = self.span.lo;
1144 let mutbl = self.parse_mutability();
1145 let id = self.parse_ident();
1146 self.expect(&token::COLON);
1147 let ty = self.parse_ty(false);
1148 let hi = ty.span.hi;
1151 mt: MutTy { ty: ty, mutbl: mutbl },
1152 span: mk_sp(lo, hi),
1156 // parse optional return type [ -> TY ] in function decl
1157 pub fn parse_ret_ty(&mut self) -> (RetStyle, P<Ty>) {
1158 return if self.eat(&token::RARROW) {
1159 let lo = self.span.lo;
1160 if self.eat(&token::NOT) {
1164 id: ast::DUMMY_NODE_ID,
1166 span: mk_sp(lo, self.last_span.hi)
1170 (Return, self.parse_ty(false))
1173 let pos = self.span.lo;
1177 id: ast::DUMMY_NODE_ID,
1179 span: mk_sp(pos, pos),
1186 // Useless second parameter for compatibility with quasiquote macros.
1188 pub fn parse_ty(&mut self, _: bool) -> P<Ty> {
1189 maybe_whole!(no_clone self, NtTy);
1191 let lo = self.span.lo;
1193 let t = if self.token == token::LPAREN {
1195 if self.token == token::RPAREN {
1199 // (t) is a parenthesized ty
1200 // (t,) is the type of a tuple with only one field,
1202 let mut ts = vec!(self.parse_ty(false));
1203 let mut one_tuple = false;
1204 while self.token == token::COMMA {
1206 if self.token != token::RPAREN {
1207 ts.push(self.parse_ty(false));
1214 if ts.len() == 1 && !one_tuple {
1215 self.expect(&token::RPAREN);
1220 self.expect(&token::RPAREN);
1223 } else if self.token == token::AT {
1226 self.parse_box_or_uniq_pointee(ManagedSigil)
1227 } else if self.token == token::TILDE {
1230 self.parse_box_or_uniq_pointee(OwnedSigil)
1231 } else if self.token == token::BINOP(token::STAR) {
1232 // STAR POINTER (bare pointer?)
1234 TyPtr(self.parse_mt())
1235 } else if self.token == token::LBRACKET {
1237 self.expect(&token::LBRACKET);
1238 let t = self.parse_ty(false);
1240 // Parse the `, ..e` in `[ int, ..e ]`
1241 // where `e` is a const expression
1242 let t = match self.maybe_parse_fixed_vstore() {
1244 Some(suffix) => TyFixedLengthVec(t, suffix)
1246 self.expect(&token::RBRACKET);
1248 } else if self.token == token::BINOP(token::AND) {
1251 self.parse_borrowed_pointee()
1252 } else if self.is_keyword(keywords::Extern) ||
1253 self.token_is_bare_fn_keyword() {
1255 self.parse_ty_bare_fn()
1256 } else if self.token_is_closure_keyword() ||
1257 self.token == token::BINOP(token::OR) ||
1258 self.token == token::OROR ||
1259 self.token == token::LT ||
1260 Parser::token_is_lifetime(&self.token) {
1263 // FIXME(pcwalton): Eventually `token::LT` will not unambiguously
1264 // introduce a closure, once procs can have lifetime bounds. We
1265 // will need to refactor the grammar a little bit at that point.
1267 let lifetime = self.parse_opt_lifetime();
1268 let result = self.parse_ty_closure(None, lifetime);
1270 } else if self.eat_keyword(keywords::Typeof) {
1272 // In order to not be ambiguous, the type must be surrounded by parens.
1273 self.expect(&token::LPAREN);
1274 let e = self.parse_expr();
1275 self.expect(&token::RPAREN);
1277 } else if self.eat_keyword(keywords::Proc) {
1278 self.parse_proc_type()
1279 } else if self.token == token::MOD_SEP
1280 || is_ident_or_path(&self.token) {
1285 } = self.parse_path(LifetimeAndTypesAndBounds);
1286 TyPath(path, bounds, ast::DUMMY_NODE_ID)
1287 } else if self.eat(&token::UNDERSCORE) {
1288 // TYPE TO BE INFERRED
1291 let msg = format!("expected type, found token {:?}", self.token);
1295 let sp = mk_sp(lo, self.last_span.hi);
1296 P(Ty {id: ast::DUMMY_NODE_ID, node: t, span: sp})
1299 // parse the type following a @ or a ~
1300 pub fn parse_box_or_uniq_pointee(&mut self,
1303 // ~'foo fn() or ~fn() are parsed directly as obsolete fn types:
1305 token::LIFETIME(..) => {
1306 let lifetime = self.parse_lifetime();
1307 self.obsolete(self.last_span, ObsoleteBoxedClosure);
1308 return self.parse_ty_closure(Some(sigil), Some(lifetime));
1311 token::IDENT(..) => {
1312 if self.token_is_old_style_closure_keyword() {
1313 self.obsolete(self.last_span, ObsoleteBoxedClosure);
1314 return self.parse_ty_closure(Some(sigil), None);
1320 // other things are parsed as @/~ + a type. Note that constructs like
1321 // ~[] and ~str will be resolved during typeck to slices and so forth,
1322 // rather than boxed ptrs. But the special casing of str/vec is not
1323 // reflected in the AST type.
1324 if sigil == OwnedSigil {
1325 TyUniq(self.parse_ty(false))
1327 TyBox(self.parse_ty(false))
1331 pub fn parse_borrowed_pointee(&mut self) -> Ty_ {
1332 // look for `&'lt` or `&'foo ` and interpret `foo` as the region name:
1333 let opt_lifetime = self.parse_opt_lifetime();
1335 if self.token_is_old_style_closure_keyword() {
1336 self.obsolete(self.last_span, ObsoleteClosureType);
1337 return self.parse_ty_closure(Some(BorrowedSigil), opt_lifetime);
1340 let mt = self.parse_mt();
1341 return TyRptr(opt_lifetime, mt);
1344 pub fn is_named_argument(&mut self) -> bool {
1345 let offset = match self.token {
1346 token::BINOP(token::AND) => 1,
1348 _ if token::is_keyword(keywords::Mut, &self.token) => 1,
1352 debug!("parser is_named_argument offset:{}", offset);
1355 is_plain_ident_or_underscore(&self.token)
1356 && self.look_ahead(1, |t| *t == token::COLON)
1358 self.look_ahead(offset, |t| is_plain_ident_or_underscore(t))
1359 && self.look_ahead(offset + 1, |t| *t == token::COLON)
1363 // This version of parse arg doesn't necessarily require
1364 // identifier names.
1365 pub fn parse_arg_general(&mut self, require_name: bool) -> Arg {
1366 let pat = if require_name || self.is_named_argument() {
1367 debug!("parse_arg_general parse_pat (require_name:{:?})",
1369 let pat = self.parse_pat();
1371 self.expect(&token::COLON);
1374 debug!("parse_arg_general ident_to_pat");
1375 ast_util::ident_to_pat(ast::DUMMY_NODE_ID,
1377 special_idents::invalid)
1380 let t = self.parse_ty(false);
1385 id: ast::DUMMY_NODE_ID,
1389 // parse a single function argument
1390 pub fn parse_arg(&mut self) -> Arg {
1391 self.parse_arg_general(true)
1394 // parse an argument in a lambda header e.g. |arg, arg|
1395 pub fn parse_fn_block_arg(&mut self) -> Arg {
1396 let pat = self.parse_pat();
1397 let t = if self.eat(&token::COLON) {
1398 self.parse_ty(false)
1401 id: ast::DUMMY_NODE_ID,
1403 span: mk_sp(self.span.lo, self.span.hi),
1409 id: ast::DUMMY_NODE_ID
1413 pub fn maybe_parse_fixed_vstore(&mut self) -> Option<@ast::Expr> {
1414 if self.token == token::COMMA &&
1415 self.look_ahead(1, |t| *t == token::DOTDOT) {
1418 Some(self.parse_expr())
1424 // matches token_lit = LIT_INT | ...
1425 pub fn lit_from_token(&mut self, tok: &token::Token) -> Lit_ {
1427 token::LIT_CHAR(i) => LitChar(i),
1428 token::LIT_INT(i, it) => LitInt(i, it),
1429 token::LIT_UINT(u, ut) => LitUint(u, ut),
1430 token::LIT_INT_UNSUFFIXED(i) => LitIntUnsuffixed(i),
1431 token::LIT_FLOAT(s, ft) => {
1432 LitFloat(self.id_to_interned_str(s), ft)
1434 token::LIT_FLOAT_UNSUFFIXED(s) => {
1435 LitFloatUnsuffixed(self.id_to_interned_str(s))
1437 token::LIT_STR(s) => {
1438 LitStr(self.id_to_interned_str(s), ast::CookedStr)
1440 token::LIT_STR_RAW(s, n) => {
1441 LitStr(self.id_to_interned_str(s), ast::RawStr(n))
1443 token::LPAREN => { self.expect(&token::RPAREN); LitNil },
1444 _ => { self.unexpected_last(tok); }
1448 // matches lit = true | false | token_lit
1449 pub fn parse_lit(&mut self) -> Lit {
1450 let lo = self.span.lo;
1451 let lit = if self.eat_keyword(keywords::True) {
1453 } else if self.eat_keyword(keywords::False) {
1456 let token = self.bump_and_get();
1457 let lit = self.lit_from_token(&token);
1460 codemap::Spanned { node: lit, span: mk_sp(lo, self.last_span.hi) }
1463 // matches '-' lit | lit
1464 pub fn parse_literal_maybe_minus(&mut self) -> @Expr {
1465 let minus_lo = self.span.lo;
1466 let minus_present = self.eat(&token::BINOP(token::MINUS));
1468 let lo = self.span.lo;
1469 let literal = @self.parse_lit();
1470 let hi = self.span.hi;
1471 let expr = self.mk_expr(lo, hi, ExprLit(literal));
1474 let minus_hi = self.span.hi;
1475 let unary = self.mk_unary(UnNeg, expr);
1476 self.mk_expr(minus_lo, minus_hi, unary)
1482 /// Parses a path and optional type parameter bounds, depending on the
1483 /// mode. The `mode` parameter determines whether lifetimes, types, and/or
1484 /// bounds are permitted and whether `::` must precede type parameter
1486 pub fn parse_path(&mut self, mode: PathParsingMode) -> PathAndBounds {
1487 // Check for a whole path...
1488 let found = match self.token {
1489 INTERPOLATED(token::NtPath(_)) => Some(self.bump_and_get()),
1493 Some(INTERPOLATED(token::NtPath(~path))) => {
1494 return PathAndBounds {
1502 let lo = self.span.lo;
1503 let is_global = self.eat(&token::MOD_SEP);
1505 // Parse any number of segments and bound sets. A segment is an
1506 // identifier followed by an optional lifetime and a set of types.
1507 // A bound set is a set of type parameter bounds.
1508 let mut segments = Vec::new();
1510 // First, parse an identifier.
1511 let identifier = self.parse_ident();
1513 // Parse the '::' before type parameters if it's required. If
1514 // it is required and wasn't present, then we're done.
1515 if mode == LifetimeAndTypesWithColons &&
1516 !self.eat(&token::MOD_SEP) {
1517 segments.push(ast::PathSegment {
1518 identifier: identifier,
1519 lifetimes: Vec::new(),
1520 types: OwnedSlice::empty(),
1525 // Parse the `<` before the lifetime and types, if applicable.
1526 let (any_lifetime_or_types, lifetimes, types) = {
1527 if mode != NoTypesAllowed && self.eat(&token::LT) {
1528 let (lifetimes, types) =
1529 self.parse_generic_values_after_lt();
1530 (true, lifetimes, OwnedSlice::from_vec(types))
1532 (false, Vec::new(), OwnedSlice::empty())
1536 // Assemble and push the result.
1537 segments.push(ast::PathSegment {
1538 identifier: identifier,
1539 lifetimes: lifetimes,
1543 // We're done if we don't see a '::', unless the mode required
1544 // a double colon to get here in the first place.
1545 if !(mode == LifetimeAndTypesWithColons &&
1546 !any_lifetime_or_types) {
1547 if !self.eat(&token::MOD_SEP) {
1553 // Next, parse a colon and bounded type parameters, if applicable.
1554 let bounds = if mode == LifetimeAndTypesAndBounds {
1555 self.parse_optional_ty_param_bounds()
1560 // Assemble the span.
1561 let span = mk_sp(lo, self.last_span.hi);
1563 // Assemble the result.
1574 /// parses 0 or 1 lifetime
1575 pub fn parse_opt_lifetime(&mut self) -> Option<ast::Lifetime> {
1577 token::LIFETIME(..) => {
1578 Some(self.parse_lifetime())
1586 /// Parses a single lifetime
1587 // matches lifetime = LIFETIME
1588 pub fn parse_lifetime(&mut self) -> ast::Lifetime {
1590 token::LIFETIME(i) => {
1591 let span = self.span;
1593 return ast::Lifetime {
1594 id: ast::DUMMY_NODE_ID,
1600 self.fatal(format!("expected a lifetime name"));
1605 // matches lifetimes = ( lifetime ) | ( lifetime , lifetimes )
1606 // actually, it matches the empty one too, but putting that in there
1607 // messes up the grammar....
1608 pub fn parse_lifetimes(&mut self) -> Vec<ast::Lifetime> {
1611 * Parses zero or more comma separated lifetimes.
1612 * Expects each lifetime to be followed by either
1613 * a comma or `>`. Used when parsing type parameter
1614 * lists, where we expect something like `<'a, 'b, T>`.
1617 let mut res = Vec::new();
1620 token::LIFETIME(_) => {
1621 res.push(self.parse_lifetime());
1629 token::COMMA => { self.bump();}
1630 token::GT => { return res; }
1631 token::BINOP(token::SHR) => { return res; }
1633 let msg = format!("expected `,` or `>` after lifetime \
1642 pub fn token_is_mutability(tok: &token::Token) -> bool {
1643 token::is_keyword(keywords::Mut, tok) ||
1644 token::is_keyword(keywords::Const, tok)
1647 // parse mutability declaration (mut/const/imm)
1648 pub fn parse_mutability(&mut self) -> Mutability {
1649 if self.eat_keyword(keywords::Mut) {
1651 } else if self.eat_keyword(keywords::Const) {
1652 self.obsolete(self.last_span, ObsoleteConstPointer);
1659 // parse ident COLON expr
1660 pub fn parse_field(&mut self) -> Field {
1661 let lo = self.span.lo;
1662 let i = self.parse_ident();
1663 let hi = self.last_span.hi;
1664 self.expect(&token::COLON);
1665 let e = self.parse_expr();
1667 ident: spanned(lo, hi, i),
1669 span: mk_sp(lo, e.span.hi),
1673 pub fn mk_expr(&mut self, lo: BytePos, hi: BytePos, node: Expr_) -> @Expr {
1675 id: ast::DUMMY_NODE_ID,
1677 span: mk_sp(lo, hi),
1681 pub fn mk_unary(&mut self, unop: ast::UnOp, expr: @Expr) -> ast::Expr_ {
1682 ExprUnary(unop, expr)
1685 pub fn mk_binary(&mut self, binop: ast::BinOp, lhs: @Expr, rhs: @Expr) -> ast::Expr_ {
1686 ExprBinary(binop, lhs, rhs)
1689 pub fn mk_call(&mut self, f: @Expr, args: Vec<@Expr> ) -> ast::Expr_ {
1693 fn mk_method_call(&mut self, ident: Ident, tps: Vec<P<Ty>> , args: Vec<@Expr> ) -> ast::Expr_ {
1694 ExprMethodCall(ident, tps, args)
1697 pub fn mk_index(&mut self, expr: @Expr, idx: @Expr) -> ast::Expr_ {
1698 ExprIndex(expr, idx)
1701 pub fn mk_field(&mut self, expr: @Expr, ident: Ident, tys: Vec<P<Ty>> ) -> ast::Expr_ {
1702 ExprField(expr, ident, tys)
1705 pub fn mk_assign_op(&mut self, binop: ast::BinOp, lhs: @Expr, rhs: @Expr) -> ast::Expr_ {
1706 ExprAssignOp(binop, lhs, rhs)
1709 pub fn mk_mac_expr(&mut self, lo: BytePos, hi: BytePos, m: Mac_) -> @Expr {
1711 id: ast::DUMMY_NODE_ID,
1712 node: ExprMac(codemap::Spanned {node: m, span: mk_sp(lo, hi)}),
1713 span: mk_sp(lo, hi),
1717 pub fn mk_lit_u32(&mut self, i: u32) -> @Expr {
1718 let span = &self.span;
1719 let lv_lit = @codemap::Spanned {
1720 node: LitUint(i as u64, TyU32),
1725 id: ast::DUMMY_NODE_ID,
1726 node: ExprLit(lv_lit),
1731 // at the bottom (top?) of the precedence hierarchy,
1732 // parse things like parenthesized exprs,
1733 // macros, return, etc.
1734 pub fn parse_bottom_expr(&mut self) -> @Expr {
1735 maybe_whole_expr!(self);
1737 let lo = self.span.lo;
1738 let mut hi = self.span.hi;
1742 if self.token == token::LPAREN {
1744 // (e) is parenthesized e
1745 // (e,) is a tuple with only one field, e
1746 let mut trailing_comma = false;
1747 if self.token == token::RPAREN {
1750 let lit = @spanned(lo, hi, LitNil);
1751 return self.mk_expr(lo, hi, ExprLit(lit));
1753 let mut es = vec!(self.parse_expr());
1754 self.commit_expr(*es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]);
1755 while self.token == token::COMMA {
1757 if self.token != token::RPAREN {
1758 es.push(self.parse_expr());
1759 self.commit_expr(*es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]);
1762 trailing_comma = true;
1766 self.commit_expr_expecting(*es.last().unwrap(), token::RPAREN);
1768 return if es.len() == 1 && !trailing_comma {
1769 self.mk_expr(lo, hi, ExprParen(*es.get(0)))
1772 self.mk_expr(lo, hi, ExprTup(es))
1774 } else if self.token == token::LBRACE {
1776 let blk = self.parse_block_tail(lo, DefaultBlock);
1777 return self.mk_expr(blk.span.lo, blk.span.hi,
1779 } else if token::is_bar(&self.token) {
1780 return self.parse_lambda_expr();
1781 } else if self.eat_keyword(keywords::Proc) {
1782 let decl = self.parse_proc_decl();
1783 let body = self.parse_expr();
1784 let fakeblock = P(ast::Block {
1785 view_items: Vec::new(),
1788 id: ast::DUMMY_NODE_ID,
1789 rules: DefaultBlock,
1793 return self.mk_expr(lo, body.span.hi, ExprProc(decl, fakeblock));
1794 } else if self.eat_keyword(keywords::Self) {
1795 let path = ast_util::ident_to_path(mk_sp(lo, hi), special_idents::self_);
1796 ex = ExprPath(path);
1797 hi = self.last_span.hi;
1798 } else if self.eat_keyword(keywords::If) {
1799 return self.parse_if_expr();
1800 } else if self.eat_keyword(keywords::For) {
1801 return self.parse_for_expr(None);
1802 } else if self.eat_keyword(keywords::While) {
1803 return self.parse_while_expr();
1804 } else if Parser::token_is_lifetime(&self.token) {
1805 let lifetime = self.get_lifetime();
1807 self.expect(&token::COLON);
1808 if self.eat_keyword(keywords::For) {
1809 return self.parse_for_expr(Some(lifetime))
1810 } else if self.eat_keyword(keywords::Loop) {
1811 return self.parse_loop_expr(Some(lifetime))
1813 self.fatal("expected `for` or `loop` after a label")
1815 } else if self.eat_keyword(keywords::Loop) {
1816 return self.parse_loop_expr(None);
1817 } else if self.eat_keyword(keywords::Continue) {
1818 let lo = self.span.lo;
1819 let ex = if Parser::token_is_lifetime(&self.token) {
1820 let lifetime = self.get_lifetime();
1822 ExprAgain(Some(lifetime))
1826 let hi = self.span.hi;
1827 return self.mk_expr(lo, hi, ex);
1828 } else if self.eat_keyword(keywords::Match) {
1829 return self.parse_match_expr();
1830 } else if self.eat_keyword(keywords::Unsafe) {
1831 return self.parse_block_expr(lo, UnsafeBlock(ast::UserProvided));
1832 } else if self.token == token::LBRACKET {
1834 let mutbl = MutImmutable;
1836 if self.token == token::RBRACKET {
1839 ex = ExprVec(Vec::new(), mutbl);
1842 let first_expr = self.parse_expr();
1843 if self.token == token::COMMA &&
1844 self.look_ahead(1, |t| *t == token::DOTDOT) {
1845 // Repeating vector syntax: [ 0, ..512 ]
1848 let count = self.parse_expr();
1849 self.expect(&token::RBRACKET);
1850 ex = ExprRepeat(first_expr, count, mutbl);
1851 } else if self.token == token::COMMA {
1852 // Vector with two or more elements.
1854 let remaining_exprs = self.parse_seq_to_end(
1856 seq_sep_trailing_allowed(token::COMMA),
1859 let mut exprs = vec!(first_expr);
1860 exprs.push_all_move(remaining_exprs);
1861 ex = ExprVec(exprs, mutbl);
1863 // Vector with one element.
1864 self.expect(&token::RBRACKET);
1865 ex = ExprVec(vec!(first_expr), mutbl);
1868 hi = self.last_span.hi;
1869 } else if self.eat_keyword(keywords::Return) {
1870 // RETURN expression
1871 if can_begin_expr(&self.token) {
1872 let e = self.parse_expr();
1874 ex = ExprRet(Some(e));
1875 } else { ex = ExprRet(None); }
1876 } else if self.eat_keyword(keywords::Break) {
1878 if Parser::token_is_lifetime(&self.token) {
1879 let lifetime = self.get_lifetime();
1881 ex = ExprBreak(Some(lifetime));
1883 ex = ExprBreak(None);
1886 } else if self.token == token::MOD_SEP ||
1887 is_ident(&self.token) && !self.is_keyword(keywords::True) &&
1888 !self.is_keyword(keywords::False) {
1889 let pth = self.parse_path(LifetimeAndTypesWithColons).path;
1891 // `!`, as an operator, is prefix, so we know this isn't that
1892 if self.token == token::NOT {
1893 // MACRO INVOCATION expression
1896 token::LPAREN | token::LBRACE => {}
1897 _ => self.fatal("expected open delimiter")
1900 let ket = token::flip_delimiter(&self.token);
1903 let tts = self.parse_seq_to_end(&ket,
1905 |p| p.parse_token_tree());
1906 let hi = self.span.hi;
1908 return self.mk_mac_expr(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT));
1909 } else if self.token == token::LBRACE {
1910 // This might be a struct literal.
1911 if self.looking_at_struct_literal() {
1912 // It's a struct literal.
1914 let mut fields = Vec::new();
1915 let mut base = None;
1917 while self.token != token::RBRACE {
1918 if self.eat(&token::DOTDOT) {
1919 base = Some(self.parse_expr());
1923 fields.push(self.parse_field());
1924 self.commit_expr(fields.last().unwrap().expr,
1925 &[token::COMMA], &[token::RBRACE]);
1929 self.expect(&token::RBRACE);
1930 ex = ExprStruct(pth, fields, base);
1931 return self.mk_expr(lo, hi, ex);
1938 // other literal expression
1939 let lit = self.parse_lit();
1944 return self.mk_expr(lo, hi, ex);
1947 // parse a block or unsafe block
1948 pub fn parse_block_expr(&mut self, lo: BytePos, blk_mode: BlockCheckMode)
1950 self.expect(&token::LBRACE);
1951 let blk = self.parse_block_tail(lo, blk_mode);
1952 return self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk));
1955 // parse a.b or a(13) or a[4] or just a
1956 pub fn parse_dot_or_call_expr(&mut self) -> @Expr {
1957 let b = self.parse_bottom_expr();
1958 self.parse_dot_or_call_expr_with(b)
1961 pub fn parse_dot_or_call_expr_with(&mut self, e0: @Expr) -> @Expr {
1967 if self.eat(&token::DOT) {
1969 token::IDENT(i, _) => {
1972 let (_, tys) = if self.eat(&token::MOD_SEP) {
1973 self.expect(&token::LT);
1974 self.parse_generic_values_after_lt()
1976 (Vec::new(), Vec::new())
1979 // expr.f() method call
1982 let mut es = self.parse_unspanned_seq(
1985 seq_sep_trailing_disallowed(token::COMMA),
1988 hi = self.last_span.hi;
1991 let nd = self.mk_method_call(i, tys, es);
1992 e = self.mk_expr(lo, hi, nd);
1995 let field = self.mk_field(e, i, tys);
1996 e = self.mk_expr(lo, hi, field)
2000 _ => self.unexpected()
2004 if self.expr_is_complete(e) { break; }
2008 let es = self.parse_unspanned_seq(
2011 seq_sep_trailing_allowed(token::COMMA),
2014 hi = self.last_span.hi;
2016 let nd = self.mk_call(e, es);
2017 e = self.mk_expr(lo, hi, nd);
2021 token::LBRACKET => {
2023 let ix = self.parse_expr();
2025 self.commit_expr_expecting(ix, token::RBRACKET);
2026 let index = self.mk_index(e, ix);
2027 e = self.mk_expr(lo, hi, index)
2036 // parse an optional separator followed by a kleene-style
2037 // repetition token (+ or *).
2038 pub fn parse_sep_and_zerok(&mut self) -> (Option<token::Token>, bool) {
2039 fn parse_zerok(parser: &mut Parser) -> Option<bool> {
2040 match parser.token {
2041 token::BINOP(token::STAR) | token::BINOP(token::PLUS) => {
2042 let zerok = parser.token == token::BINOP(token::STAR);
2050 match parse_zerok(self) {
2051 Some(zerok) => return (None, zerok),
2055 let separator = self.bump_and_get();
2056 match parse_zerok(self) {
2057 Some(zerok) => (Some(separator), zerok),
2058 None => self.fatal("expected `*` or `+`")
2062 // parse a single token tree from the input.
2063 pub fn parse_token_tree(&mut self) -> TokenTree {
2064 // FIXME #6994: currently, this is too eager. It
2065 // parses token trees but also identifies TTSeq's
2066 // and TTNonterminal's; it's too early to know yet
2067 // whether something will be a nonterminal or a seq
2069 maybe_whole!(deref self, NtTT);
2071 // this is the fall-through for the 'match' below.
2072 // invariants: the current token is not a left-delimiter,
2073 // not an EOF, and not the desired right-delimiter (if
2074 // it were, parse_seq_to_before_end would have prevented
2075 // reaching this point.
2076 fn parse_non_delim_tt_tok(p: &mut Parser) -> TokenTree {
2077 maybe_whole!(deref p, NtTT);
2079 token::RPAREN | token::RBRACE | token::RBRACKET => {
2080 // This is a conservative error: only report the last unclosed delimiter. The
2081 // previous unclosed delimiters could actually be closed! The parser just hasn't
2082 // gotten to them yet.
2083 match p.open_braces.last() {
2085 Some(&sp) => p.span_note(sp, "unclosed delimiter"),
2087 let token_str = p.this_token_to_str();
2088 p.fatal(format!("incorrect close delimiter: `{}`",
2091 /* we ought to allow different depths of unquotation */
2092 token::DOLLAR if p.quote_depth > 0u => {
2096 if p.token == token::LPAREN {
2097 let seq = p.parse_seq(
2101 |p| p.parse_token_tree()
2103 let (s, z) = p.parse_sep_and_zerok();
2104 let seq = match seq {
2105 Spanned { node, .. } => node,
2107 TTSeq(mk_sp(sp.lo, p.span.hi), @seq, s, z)
2109 TTNonterminal(sp, p.parse_ident())
2118 // turn the next token into a TTTok:
2119 fn parse_any_tt_tok(p: &mut Parser) -> TokenTree {
2120 TTTok(p.span, p.bump_and_get())
2125 let open_braces = self.open_braces.clone();
2126 for sp in open_braces.iter() {
2127 self.span_note(*sp, "Did you mean to close this delimiter?");
2129 // There shouldn't really be a span, but it's easier for the test runner
2130 // if we give it one
2131 self.fatal("this file contains an un-closed delimiter ");
2133 token::LPAREN | token::LBRACE | token::LBRACKET => {
2134 let close_delim = token::flip_delimiter(&self.token);
2136 // Parse the open delimiter.
2137 self.open_braces.push(self.span);
2138 let mut result = vec!(parse_any_tt_tok(self));
2141 self.parse_seq_to_before_end(&close_delim,
2143 |p| p.parse_token_tree());
2144 result.push_all_move(trees);
2146 // Parse the close delimiter.
2147 result.push(parse_any_tt_tok(self));
2148 self.open_braces.pop().unwrap();
2152 _ => parse_non_delim_tt_tok(self)
2156 // parse a stream of tokens into a list of TokenTree's,
2158 pub fn parse_all_token_trees(&mut self) -> Vec<TokenTree> {
2159 let mut tts = Vec::new();
2160 while self.token != token::EOF {
2161 tts.push(self.parse_token_tree());
2166 pub fn parse_matchers(&mut self) -> Vec<Matcher> {
2167 // unification of Matcher's and TokenTree's would vastly improve
2168 // the interpolation of Matcher's
2169 maybe_whole!(self, NtMatchers);
2170 let mut name_idx = 0u;
2172 token::LBRACE | token::LPAREN | token::LBRACKET => {
2173 let other_delimiter = token::flip_delimiter(&self.token);
2175 self.parse_matcher_subseq_upto(&mut name_idx, &other_delimiter)
2177 _ => self.fatal("expected open delimiter")
2181 // This goofy function is necessary to correctly match parens in Matcher's.
2182 // Otherwise, `$( ( )` would be a valid Matcher, and `$( () )` would be
2183 // invalid. It's similar to common::parse_seq.
2184 pub fn parse_matcher_subseq_upto(&mut self,
2185 name_idx: &mut uint,
2188 let mut ret_val = Vec::new();
2189 let mut lparens = 0u;
2191 while self.token != *ket || lparens > 0u {
2192 if self.token == token::LPAREN { lparens += 1u; }
2193 if self.token == token::RPAREN { lparens -= 1u; }
2194 ret_val.push(self.parse_matcher(name_idx));
2202 pub fn parse_matcher(&mut self, name_idx: &mut uint) -> Matcher {
2203 let lo = self.span.lo;
2205 let m = if self.token == token::DOLLAR {
2207 if self.token == token::LPAREN {
2208 let name_idx_lo = *name_idx;
2210 let ms = self.parse_matcher_subseq_upto(name_idx,
2213 self.fatal("repetition body must be nonempty");
2215 let (sep, zerok) = self.parse_sep_and_zerok();
2216 MatchSeq(ms, sep, zerok, name_idx_lo, *name_idx)
2218 let bound_to = self.parse_ident();
2219 self.expect(&token::COLON);
2220 let nt_name = self.parse_ident();
2221 let m = MatchNonterminal(bound_to, nt_name, *name_idx);
2226 MatchTok(self.bump_and_get())
2229 return spanned(lo, self.span.hi, m);
2232 // parse a prefix-operator expr
2233 pub fn parse_prefix_expr(&mut self) -> @Expr {
2234 let lo = self.span.lo;
2241 let e = self.parse_prefix_expr();
2243 ex = self.mk_unary(UnNot, e);
2245 token::BINOP(b) => {
2249 let e = self.parse_prefix_expr();
2251 ex = self.mk_unary(UnNeg, e);
2255 let e = self.parse_prefix_expr();
2257 ex = self.mk_unary(UnDeref, e);
2261 let _lt = self.parse_opt_lifetime();
2262 let m = self.parse_mutability();
2263 let e = self.parse_prefix_expr();
2265 // HACK: turn &[...] into a &-vec
2267 ExprVec(..) if m == MutImmutable => {
2268 ExprVstore(e, ExprVstoreSlice)
2270 ExprLit(lit) if lit_is_str(lit) && m == MutImmutable => {
2271 ExprVstore(e, ExprVstoreSlice)
2273 ExprVec(..) if m == MutMutable => {
2274 ExprVstore(e, ExprVstoreMutSlice)
2276 _ => ExprAddrOf(m, e)
2279 _ => return self.parse_dot_or_call_expr()
2284 let e = self.parse_prefix_expr();
2286 // HACK: pretending @[] is a (removed) @-vec
2290 self.obsolete(e.span, ObsoleteManagedVec);
2291 // the above error means that no-one will know we're
2292 // lying... hopefully.
2293 ExprVstore(e, ExprVstoreUniq)
2295 ExprLit(lit) if lit_is_str(lit) => {
2296 self.obsolete(self.last_span, ObsoleteManagedString);
2297 ExprVstore(e, ExprVstoreUniq)
2299 _ => self.mk_unary(UnBox, e)
2305 let e = self.parse_prefix_expr();
2307 // HACK: turn ~[...] into a ~-vec
2309 ExprVec(..) | ExprRepeat(..) => ExprVstore(e, ExprVstoreUniq),
2310 ExprLit(lit) if lit_is_str(lit) => {
2311 ExprVstore(e, ExprVstoreUniq)
2313 _ => self.mk_unary(UnUniq, e)
2316 token::IDENT(_, _) if self.is_keyword(keywords::Box) => {
2319 // Check for a place: `box(PLACE) EXPR`.
2320 if self.eat(&token::LPAREN) {
2321 // Support `box() EXPR` as the default.
2322 if !self.eat(&token::RPAREN) {
2323 let place = self.parse_expr();
2324 self.expect(&token::RPAREN);
2325 let subexpression = self.parse_prefix_expr();
2326 hi = subexpression.span.hi;
2327 ex = ExprBox(place, subexpression);
2328 return self.mk_expr(lo, hi, ex);
2332 // Otherwise, we use the unique pointer default.
2333 let subexpression = self.parse_prefix_expr();
2334 hi = subexpression.span.hi;
2335 // HACK: turn `box [...]` into a boxed-vec
2336 ex = match subexpression.node {
2337 ExprVec(..) | ExprRepeat(..) => {
2338 ExprVstore(subexpression, ExprVstoreUniq)
2340 ExprLit(lit) if lit_is_str(lit) => {
2341 ExprVstore(subexpression, ExprVstoreUniq)
2343 _ => self.mk_unary(UnUniq, subexpression)
2346 _ => return self.parse_dot_or_call_expr()
2348 return self.mk_expr(lo, hi, ex);
2351 // parse an expression of binops
2352 pub fn parse_binops(&mut self) -> @Expr {
2353 let prefix_expr = self.parse_prefix_expr();
2354 self.parse_more_binops(prefix_expr, 0)
2357 // parse an expression of binops of at least min_prec precedence
2358 pub fn parse_more_binops(&mut self, lhs: @Expr, min_prec: uint) -> @Expr {
2359 if self.expr_is_complete(lhs) { return lhs; }
2361 // Prevent dynamic borrow errors later on by limiting the
2362 // scope of the borrows.
2364 let token: &token::Token = &self.token;
2365 let restriction: &restriction = &self.restriction;
2366 match (token, restriction) {
2367 (&token::BINOP(token::OR), &RESTRICT_NO_BAR_OP) => return lhs,
2368 (&token::BINOP(token::OR),
2369 &RESTRICT_NO_BAR_OR_DOUBLEBAR_OP) => return lhs,
2370 (&token::OROR, &RESTRICT_NO_BAR_OR_DOUBLEBAR_OP) => return lhs,
2375 let cur_opt = token_to_binop(&self.token);
2378 let cur_prec = operator_prec(cur_op);
2379 if cur_prec > min_prec {
2381 let expr = self.parse_prefix_expr();
2382 let rhs = self.parse_more_binops(expr, cur_prec);
2383 let binary = self.mk_binary(cur_op, lhs, rhs);
2384 let bin = self.mk_expr(lhs.span.lo, rhs.span.hi, binary);
2385 self.parse_more_binops(bin, min_prec)
2391 if as_prec > min_prec && self.eat_keyword(keywords::As) {
2392 let rhs = self.parse_ty(true);
2393 let _as = self.mk_expr(lhs.span.lo,
2395 ExprCast(lhs, rhs));
2396 self.parse_more_binops(_as, min_prec)
2404 // parse an assignment expression....
2405 // actually, this seems to be the main entry point for
2406 // parsing an arbitrary expression.
2407 pub fn parse_assign_expr(&mut self) -> @Expr {
2408 let lo = self.span.lo;
2409 let lhs = self.parse_binops();
2413 let rhs = self.parse_expr();
2414 self.mk_expr(lo, rhs.span.hi, ExprAssign(lhs, rhs))
2416 token::BINOPEQ(op) => {
2418 let rhs = self.parse_expr();
2419 let aop = match op {
2420 token::PLUS => BiAdd,
2421 token::MINUS => BiSub,
2422 token::STAR => BiMul,
2423 token::SLASH => BiDiv,
2424 token::PERCENT => BiRem,
2425 token::CARET => BiBitXor,
2426 token::AND => BiBitAnd,
2427 token::OR => BiBitOr,
2428 token::SHL => BiShl,
2431 let assign_op = self.mk_assign_op(aop, lhs, rhs);
2432 self.mk_expr(lo, rhs.span.hi, assign_op)
2435 self.obsolete(self.span, ObsoleteSwap);
2437 // Ignore what we get, this is an error anyway
2439 self.mk_expr(lo, self.span.hi, ExprBreak(None))
2447 // parse an 'if' expression ('if' token already eaten)
2448 pub fn parse_if_expr(&mut self) -> @Expr {
2449 let lo = self.last_span.lo;
2450 let cond = self.parse_expr();
2451 let thn = self.parse_block();
2452 let mut els: Option<@Expr> = None;
2453 let mut hi = thn.span.hi;
2454 if self.eat_keyword(keywords::Else) {
2455 let elexpr = self.parse_else_expr();
2457 hi = elexpr.span.hi;
2459 self.mk_expr(lo, hi, ExprIf(cond, thn, els))
2462 // `|args| { ... }` or `{ ...}` like in `do` expressions
2463 pub fn parse_lambda_block_expr(&mut self) -> @Expr {
2464 self.parse_lambda_expr_(
2467 token::BINOP(token::OR) | token::OROR => {
2468 p.parse_fn_block_decl()
2471 // No argument list - `do foo {`
2475 id: ast::DUMMY_NODE_ID,
2486 let blk = p.parse_block();
2487 p.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk))
2492 pub fn parse_lambda_expr(&mut self) -> @Expr {
2493 self.parse_lambda_expr_(|p| p.parse_fn_block_decl(),
2497 // parse something of the form |args| expr
2498 // this is used both in parsing a lambda expr
2499 // and in parsing a block expr as e.g. in for...
2500 pub fn parse_lambda_expr_(&mut self,
2501 parse_decl: |&mut Parser| -> P<FnDecl>,
2502 parse_body: |&mut Parser| -> @Expr)
2504 let lo = self.span.lo;
2505 let decl = parse_decl(self);
2506 let body = parse_body(self);
2507 let fakeblock = P(ast::Block {
2508 view_items: Vec::new(),
2511 id: ast::DUMMY_NODE_ID,
2512 rules: DefaultBlock,
2516 return self.mk_expr(lo, body.span.hi, ExprFnBlock(decl, fakeblock));
2519 pub fn parse_else_expr(&mut self) -> @Expr {
2520 if self.eat_keyword(keywords::If) {
2521 return self.parse_if_expr();
2523 let blk = self.parse_block();
2524 return self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk));
2528 // parse a 'for' .. 'in' expression ('for' token already eaten)
2529 pub fn parse_for_expr(&mut self, opt_ident: Option<ast::Ident>) -> @Expr {
2530 // Parse: `for <src_pat> in <src_expr> <src_loop_block>`
2532 let lo = self.last_span.lo;
2533 let pat = self.parse_pat();
2534 self.expect_keyword(keywords::In);
2535 let expr = self.parse_expr();
2536 let loop_block = self.parse_block();
2537 let hi = self.span.hi;
2539 self.mk_expr(lo, hi, ExprForLoop(pat, expr, loop_block, opt_ident))
2542 pub fn parse_while_expr(&mut self) -> @Expr {
2543 let lo = self.last_span.lo;
2544 let cond = self.parse_expr();
2545 let body = self.parse_block();
2546 let hi = body.span.hi;
2547 return self.mk_expr(lo, hi, ExprWhile(cond, body));
2550 pub fn parse_loop_expr(&mut self, opt_ident: Option<ast::Ident>) -> @Expr {
2551 // loop headers look like 'loop {' or 'loop unsafe {'
2552 let is_loop_header =
2553 self.token == token::LBRACE
2554 || (is_ident(&self.token)
2555 && self.look_ahead(1, |t| *t == token::LBRACE));
2558 // This is a loop body
2559 let lo = self.last_span.lo;
2560 let body = self.parse_block();
2561 let hi = body.span.hi;
2562 return self.mk_expr(lo, hi, ExprLoop(body, opt_ident));
2564 // This is an obsolete 'continue' expression
2565 if opt_ident.is_some() {
2566 self.span_err(self.last_span,
2567 "a label may not be used with a `loop` expression");
2570 self.obsolete(self.last_span, ObsoleteLoopAsContinue);
2571 let lo = self.span.lo;
2572 let ex = if Parser::token_is_lifetime(&self.token) {
2573 let lifetime = self.get_lifetime();
2575 ExprAgain(Some(lifetime))
2579 let hi = self.span.hi;
2580 return self.mk_expr(lo, hi, ex);
2584 // For distingishing between struct literals and blocks
2585 fn looking_at_struct_literal(&mut self) -> bool {
2586 self.token == token::LBRACE &&
2587 ((self.look_ahead(1, |t| token::is_plain_ident(t)) &&
2588 self.look_ahead(2, |t| *t == token::COLON))
2589 || self.look_ahead(1, |t| *t == token::DOTDOT))
2592 fn parse_match_expr(&mut self) -> @Expr {
2593 let lo = self.last_span.lo;
2594 let discriminant = self.parse_expr();
2595 self.commit_expr_expecting(discriminant, token::LBRACE);
2596 let mut arms: Vec<Arm> = Vec::new();
2597 while self.token != token::RBRACE {
2598 let pats = self.parse_pats();
2599 let mut guard = None;
2600 if self.eat_keyword(keywords::If) {
2601 guard = Some(self.parse_expr());
2603 self.expect(&token::FAT_ARROW);
2604 let expr = self.parse_expr_res(RESTRICT_STMT_EXPR);
2607 !classify::expr_is_simple_block(expr)
2608 && self.token != token::RBRACE;
2611 self.commit_expr(expr, &[token::COMMA], &[token::RBRACE]);
2613 self.eat(&token::COMMA);
2616 arms.push(ast::Arm { pats: pats, guard: guard, body: expr });
2618 let hi = self.span.hi;
2620 return self.mk_expr(lo, hi, ExprMatch(discriminant, arms));
2623 // parse an expression
2624 pub fn parse_expr(&mut self) -> @Expr {
2625 return self.parse_expr_res(UNRESTRICTED);
2628 // parse an expression, subject to the given restriction
2629 fn parse_expr_res(&mut self, r: restriction) -> @Expr {
2630 let old = self.restriction;
2631 self.restriction = r;
2632 let e = self.parse_assign_expr();
2633 self.restriction = old;
2637 // parse the RHS of a local variable declaration (e.g. '= 14;')
2638 fn parse_initializer(&mut self) -> Option<@Expr> {
2639 if self.token == token::EQ {
2641 Some(self.parse_expr())
2647 // parse patterns, separated by '|' s
2648 fn parse_pats(&mut self) -> Vec<@Pat> {
2649 let mut pats = Vec::new();
2651 pats.push(self.parse_pat());
2652 if self.token == token::BINOP(token::OR) { self.bump(); }
2653 else { return pats; }
2657 fn parse_pat_vec_elements(
2659 ) -> (Vec<@Pat> , Option<@Pat>, Vec<@Pat> ) {
2660 let mut before = Vec::new();
2661 let mut slice = None;
2662 let mut after = Vec::new();
2663 let mut first = true;
2664 let mut before_slice = true;
2666 while self.token != token::RBRACKET {
2667 if first { first = false; }
2668 else { self.expect(&token::COMMA); }
2670 let mut is_slice = false;
2672 if self.token == token::DOTDOT {
2675 before_slice = false;
2680 if self.token == token::COMMA || self.token == token::RBRACKET {
2681 slice = Some(@ast::Pat {
2682 id: ast::DUMMY_NODE_ID,
2687 let subpat = self.parse_pat();
2689 ast::Pat { id, node: PatWild, span } => {
2690 self.obsolete(self.span, ObsoleteVecDotDotWildcard);
2691 slice = Some(@ast::Pat {
2697 ast::Pat { node: PatIdent(_, _, _), .. } => {
2698 slice = Some(subpat);
2700 ast::Pat { span, .. } => self.span_fatal(
2701 span, "expected an identifier or nothing"
2706 let subpat = self.parse_pat();
2708 before.push(subpat);
2715 (before, slice, after)
2718 // parse the fields of a struct-like pattern
2719 fn parse_pat_fields(&mut self) -> (Vec<ast::FieldPat> , bool) {
2720 let mut fields = Vec::new();
2721 let mut etc = false;
2722 let mut first = true;
2723 while self.token != token::RBRACE {
2727 self.expect(&token::COMMA);
2728 // accept trailing commas
2729 if self.token == token::RBRACE { break }
2732 etc = self.token == token::UNDERSCORE || self.token == token::DOTDOT;
2733 if self.token == token::UNDERSCORE {
2734 self.obsolete(self.span, ObsoleteStructWildcard);
2738 if self.token != token::RBRACE {
2739 let token_str = self.this_token_to_str();
2740 self.fatal(format!("expected `\\}`, found `{}`",
2747 let bind_type = if self.eat_keyword(keywords::Mut) {
2748 BindByValue(MutMutable)
2749 } else if self.eat_keyword(keywords::Ref) {
2750 BindByRef(self.parse_mutability())
2752 BindByValue(MutImmutable)
2755 let fieldname = self.parse_ident();
2757 let subpat = if self.token == token::COLON {
2759 BindByRef(..) | BindByValue(MutMutable) => {
2760 let token_str = self.this_token_to_str();
2761 self.fatal(format!("unexpected `{}`", token_str))
2769 let fieldpath = ast_util::ident_to_path(self.last_span,
2772 id: ast::DUMMY_NODE_ID,
2773 node: PatIdent(bind_type, fieldpath, None),
2774 span: self.last_span
2777 fields.push(ast::FieldPat { ident: fieldname, pat: subpat });
2779 return (fields, etc);
2783 pub fn parse_pat(&mut self) -> @Pat {
2784 maybe_whole!(self, NtPat);
2786 let lo = self.span.lo;
2791 token::UNDERSCORE => {
2794 hi = self.last_span.hi;
2796 id: ast::DUMMY_NODE_ID,
2804 let sub = self.parse_pat();
2805 self.obsolete(self.span, ObsoleteManagedPattern);
2806 let hi = self.last_span.hi;
2808 id: ast::DUMMY_NODE_ID,
2816 let sub = self.parse_pat();
2818 hi = self.last_span.hi;
2820 id: ast::DUMMY_NODE_ID,
2825 token::BINOP(token::AND) => {
2827 let lo = self.span.lo;
2829 let sub = self.parse_pat();
2831 // HACK: parse &"..." as a literal of a borrowed str
2832 pat = match sub.node {
2835 ExprLit(lit) if lit_is_str(lit) => {
2837 id: ast::DUMMY_NODE_ID,
2838 node: ExprVstore(e, ExprVstoreSlice),
2843 _ => PatRegion(sub),
2846 _ => PatRegion(sub),
2848 hi = self.last_span.hi;
2850 id: ast::DUMMY_NODE_ID,
2856 // parse (pat,pat,pat,...) as tuple
2858 if self.token == token::RPAREN {
2861 let lit = @codemap::Spanned {
2863 span: mk_sp(lo, hi)};
2864 let expr = self.mk_expr(lo, hi, ExprLit(lit));
2867 let mut fields = vec!(self.parse_pat());
2868 if self.look_ahead(1, |t| *t != token::RPAREN) {
2869 while self.token == token::COMMA {
2871 if self.token == token::RPAREN { break; }
2872 fields.push(self.parse_pat());
2875 if fields.len() == 1 { self.expect(&token::COMMA); }
2876 self.expect(&token::RPAREN);
2877 pat = PatTup(fields);
2879 hi = self.last_span.hi;
2881 id: ast::DUMMY_NODE_ID,
2886 token::LBRACKET => {
2887 // parse [pat,pat,...] as vector pattern
2889 let (before, slice, after) =
2890 self.parse_pat_vec_elements();
2892 self.expect(&token::RBRACKET);
2893 pat = ast::PatVec(before, slice, after);
2894 hi = self.last_span.hi;
2896 id: ast::DUMMY_NODE_ID,
2904 if !is_ident_or_path(&self.token)
2905 || self.is_keyword(keywords::True)
2906 || self.is_keyword(keywords::False) {
2907 // Parse an expression pattern or exp .. exp.
2909 // These expressions are limited to literals (possibly
2910 // preceded by unary-minus) or identifiers.
2911 let val = self.parse_literal_maybe_minus();
2912 if self.eat(&token::DOTDOT) {
2913 let end = if is_ident_or_path(&self.token) {
2914 let path = self.parse_path(LifetimeAndTypesWithColons)
2916 let hi = self.span.hi;
2917 self.mk_expr(lo, hi, ExprPath(path))
2919 self.parse_literal_maybe_minus()
2921 pat = PatRange(val, end);
2925 } else if self.eat_keyword(keywords::Mut) {
2926 pat = self.parse_pat_ident(BindByValue(MutMutable));
2927 } else if self.eat_keyword(keywords::Ref) {
2929 let mutbl = self.parse_mutability();
2930 pat = self.parse_pat_ident(BindByRef(mutbl));
2932 let can_be_enum_or_struct = self.look_ahead(1, |t| {
2934 token::LPAREN | token::LBRACKET | token::LT |
2935 token::LBRACE | token::MOD_SEP => true,
2940 if self.look_ahead(1, |t| *t == token::DOTDOT) {
2941 let start = self.parse_expr_res(RESTRICT_NO_BAR_OP);
2942 self.eat(&token::DOTDOT);
2943 let end = self.parse_expr_res(RESTRICT_NO_BAR_OP);
2944 pat = PatRange(start, end);
2945 } else if is_plain_ident(&self.token) && !can_be_enum_or_struct {
2946 let name = self.parse_path(NoTypesAllowed).path;
2948 if self.eat(&token::AT) {
2950 sub = Some(self.parse_pat());
2955 pat = PatIdent(BindByValue(MutImmutable), name, sub);
2957 // parse an enum pat
2958 let enum_path = self.parse_path(LifetimeAndTypesWithColons)
2964 self.parse_pat_fields();
2966 pat = PatStruct(enum_path, fields, etc);
2969 let mut args: Vec<@Pat> = Vec::new();
2972 let is_star = self.look_ahead(1, |t| {
2974 token::BINOP(token::STAR) => true,
2978 let is_dotdot = self.look_ahead(1, |t| {
2980 token::DOTDOT => true,
2984 if is_star | is_dotdot {
2985 // This is a "top constructor only" pat
2988 self.obsolete(self.span, ObsoleteEnumWildcard);
2991 self.expect(&token::RPAREN);
2992 pat = PatEnum(enum_path, None);
2994 args = self.parse_enum_variant_seq(
2997 seq_sep_trailing_disallowed(token::COMMA),
3000 pat = PatEnum(enum_path, Some(args));
3004 if enum_path.segments.len() == 1 {
3005 // it could still be either an enum
3006 // or an identifier pattern, resolve
3007 // will sort it out:
3008 pat = PatIdent(BindByValue(MutImmutable),
3012 pat = PatEnum(enum_path, Some(args));
3020 hi = self.last_span.hi;
3022 id: ast::DUMMY_NODE_ID,
3024 span: mk_sp(lo, hi),
3028 // parse ident or ident @ pat
3029 // used by the copy foo and ref foo patterns to give a good
3030 // error message when parsing mistakes like ref foo(a,b)
3031 fn parse_pat_ident(&mut self,
3032 binding_mode: ast::BindingMode)
3034 if !is_plain_ident(&self.token) {
3035 self.span_fatal(self.last_span,
3036 "expected identifier, found path");
3038 // why a path here, and not just an identifier?
3039 let name = self.parse_path(NoTypesAllowed).path;
3040 let sub = if self.eat(&token::AT) {
3041 Some(self.parse_pat())
3046 // just to be friendly, if they write something like
3048 // we end up here with ( as the current token. This shortly
3049 // leads to a parse error. Note that if there is no explicit
3050 // binding mode then we do not end up here, because the lookahead
3051 // will direct us over to parse_enum_variant()
3052 if self.token == token::LPAREN {
3055 "expected identifier, found enum pattern");
3058 PatIdent(binding_mode, name, sub)
3061 // parse a local variable declaration
3062 fn parse_local(&mut self) -> @Local {
3063 let lo = self.span.lo;
3064 let pat = self.parse_pat();
3067 id: ast::DUMMY_NODE_ID,
3069 span: mk_sp(lo, lo),
3071 if self.eat(&token::COLON) { ty = self.parse_ty(false); }
3072 let init = self.parse_initializer();
3077 id: ast::DUMMY_NODE_ID,
3078 span: mk_sp(lo, self.last_span.hi),
3082 // parse a "let" stmt
3083 fn parse_let(&mut self) -> @Decl {
3084 let lo = self.span.lo;
3085 let local = self.parse_local();
3086 while self.eat(&token::COMMA) {
3087 let _ = self.parse_local();
3088 self.obsolete(self.span, ObsoleteMultipleLocalDecl);
3090 return @spanned(lo, self.last_span.hi, DeclLocal(local));
3093 // parse a structure field
3094 fn parse_name_and_ty(&mut self, pr: Visibility,
3095 attrs: Vec<Attribute> ) -> StructField {
3096 let lo = self.span.lo;
3097 if !is_plain_ident(&self.token) {
3098 self.fatal("expected ident");
3100 let name = self.parse_ident();
3101 self.expect(&token::COLON);
3102 let ty = self.parse_ty(false);
3103 spanned(lo, self.last_span.hi, ast::StructField_ {
3104 kind: NamedField(name, pr),
3105 id: ast::DUMMY_NODE_ID,
3111 // parse a statement. may include decl.
3112 // precondition: any attributes are parsed already
3113 pub fn parse_stmt(&mut self, item_attrs: Vec<Attribute> ) -> @Stmt {
3114 maybe_whole!(self, NtStmt);
3116 fn check_expected_item(p: &mut Parser, found_attrs: bool) {
3117 // If we have attributes then we should have an item
3119 p.span_err(p.last_span, "expected item after attributes");
3123 let lo = self.span.lo;
3124 if self.is_keyword(keywords::Let) {
3125 check_expected_item(self, !item_attrs.is_empty());
3126 self.expect_keyword(keywords::Let);
3127 let decl = self.parse_let();
3128 return @spanned(lo, decl.span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID));
3129 } else if is_ident(&self.token)
3130 && !token::is_any_keyword(&self.token)
3131 && self.look_ahead(1, |t| *t == token::NOT) {
3132 // parse a macro invocation. Looks like there's serious
3133 // overlap here; if this clause doesn't catch it (and it
3134 // won't, for brace-delimited macros) it will fall through
3135 // to the macro clause of parse_item_or_view_item. This
3136 // could use some cleanup, it appears to me.
3138 // whoops! I now have a guess: I'm guessing the "parens-only"
3139 // rule here is deliberate, to allow macro users to use parens
3140 // for things that should be parsed as stmt_mac, and braces
3141 // for things that should expand into items. Tricky, and
3142 // somewhat awkward... and probably undocumented. Of course,
3143 // I could just be wrong.
3145 check_expected_item(self, !item_attrs.is_empty());
3147 // Potential trouble: if we allow macros with paths instead of
3148 // idents, we'd need to look ahead past the whole path here...
3149 let pth = self.parse_path(NoTypesAllowed).path;
3152 let id = if self.token == token::LPAREN || self.token == token::LBRACE {
3153 token::special_idents::invalid // no special identifier
3158 // check that we're pointing at delimiters (need to check
3159 // again after the `if`, because of `parse_ident`
3160 // consuming more tokens).
3161 let (bra, ket) = match self.token {
3162 token::LPAREN => (token::LPAREN, token::RPAREN),
3163 token::LBRACE => (token::LBRACE, token::RBRACE),
3165 // we only expect an ident if we didn't parse one
3167 let ident_str = if id == token::special_idents::invalid {
3172 let tok_str = self.this_token_to_str();
3173 self.fatal(format!("expected {}`(` or `\\{`, but found `{}`",
3174 ident_str, tok_str))
3178 let tts = self.parse_unspanned_seq(
3182 |p| p.parse_token_tree()
3184 let hi = self.span.hi;
3186 if id == token::special_idents::invalid {
3187 return @spanned(lo, hi, StmtMac(
3188 spanned(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT)), false));
3190 // if it has a special ident, it's definitely an item
3191 return @spanned(lo, hi, StmtDecl(
3192 @spanned(lo, hi, DeclItem(
3194 lo, hi, id /*id is good here*/,
3195 ItemMac(spanned(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT))),
3196 Inherited, Vec::new(/*no attrs*/)))),
3197 ast::DUMMY_NODE_ID));
3201 let found_attrs = !item_attrs.is_empty();
3202 match self.parse_item_or_view_item(item_attrs, false) {
3205 let decl = @spanned(lo, hi, DeclItem(i));
3206 return @spanned(lo, hi, StmtDecl(decl, ast::DUMMY_NODE_ID));
3208 IoviViewItem(vi) => {
3209 self.span_fatal(vi.span,
3210 "view items must be declared at the top of the block");
3212 IoviForeignItem(_) => {
3213 self.fatal("foreign items are not allowed here");
3215 IoviNone(_) => { /* fallthrough */ }
3218 check_expected_item(self, found_attrs);
3220 // Remainder are line-expr stmts.
3221 let e = self.parse_expr_res(RESTRICT_STMT_EXPR);
3222 return @spanned(lo, e.span.hi, StmtExpr(e, ast::DUMMY_NODE_ID));
3226 // is this expression a successfully-parsed statement?
3227 fn expr_is_complete(&mut self, e: @Expr) -> bool {
3228 return self.restriction == RESTRICT_STMT_EXPR &&
3229 !classify::expr_requires_semi_to_be_stmt(e);
3232 // parse a block. No inner attrs are allowed.
3233 pub fn parse_block(&mut self) -> P<Block> {
3234 maybe_whole!(no_clone self, NtBlock);
3236 let lo = self.span.lo;
3237 if self.eat_keyword(keywords::Unsafe) {
3238 self.obsolete(self.span, ObsoleteUnsafeBlock);
3240 self.expect(&token::LBRACE);
3242 return self.parse_block_tail_(lo, DefaultBlock, Vec::new());
3245 // parse a block. Inner attrs are allowed.
3246 fn parse_inner_attrs_and_block(&mut self)
3247 -> (Vec<Attribute> , P<Block>) {
3249 maybe_whole!(pair_empty self, NtBlock);
3251 let lo = self.span.lo;
3252 if self.eat_keyword(keywords::Unsafe) {
3253 self.obsolete(self.span, ObsoleteUnsafeBlock);
3255 self.expect(&token::LBRACE);
3256 let (inner, next) = self.parse_inner_attrs_and_next();
3258 (inner, self.parse_block_tail_(lo, DefaultBlock, next))
3261 // Precondition: already parsed the '{' or '#{'
3262 // I guess that also means "already parsed the 'impure'" if
3263 // necessary, and this should take a qualifier.
3264 // some blocks start with "#{"...
3265 fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> P<Block> {
3266 self.parse_block_tail_(lo, s, Vec::new())
3269 // parse the rest of a block expression or function body
3270 fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
3271 first_item_attrs: Vec<Attribute> ) -> P<Block> {
3272 let mut stmts = Vec::new();
3273 let mut expr = None;
3275 // wouldn't it be more uniform to parse view items only, here?
3276 let ParsedItemsAndViewItems {
3277 attrs_remaining: attrs_remaining,
3278 view_items: view_items,
3281 } = self.parse_items_and_view_items(first_item_attrs,
3284 for item in items.iter() {
3285 let decl = @spanned(item.span.lo, item.span.hi, DeclItem(*item));
3286 stmts.push(@spanned(item.span.lo, item.span.hi,
3287 StmtDecl(decl, ast::DUMMY_NODE_ID)));
3290 let mut attributes_box = attrs_remaining;
3292 while self.token != token::RBRACE {
3293 // parsing items even when they're not allowed lets us give
3294 // better error messages and recover more gracefully.
3295 attributes_box.push_all(self.parse_outer_attributes().as_slice());
3298 if !attributes_box.is_empty() {
3299 self.span_err(self.last_span, "expected item after attributes");
3300 attributes_box = Vec::new();
3302 self.bump(); // empty
3305 // fall through and out.
3308 let stmt = self.parse_stmt(attributes_box);
3309 attributes_box = Vec::new();
3311 StmtExpr(e, stmt_id) => {
3312 // expression without semicolon
3313 if classify::stmt_ends_with_semi(stmt) {
3314 // Just check for errors and recover; do not eat semicolon yet.
3315 self.commit_stmt(stmt, &[], &[token::SEMI, token::RBRACE]);
3321 stmts.push(@codemap::Spanned {
3322 node: StmtSemi(e, stmt_id),
3334 StmtMac(ref m, _) => {
3335 // statement macro; might be an expr
3342 // if a block ends in `m!(arg)` without
3343 // a `;`, it must be an expr
3346 self.mk_mac_expr(stmt.span.lo,
3358 stmts.push(@codemap::Spanned {
3359 node: StmtMac((*m).clone(), true),
3364 _ => { // all other kinds of statements:
3367 if classify::stmt_ends_with_semi(stmt) {
3368 self.commit_stmt_expecting(stmt, token::SEMI);
3376 if !attributes_box.is_empty() {
3377 self.span_err(self.last_span, "expected item after attributes");
3380 let hi = self.span.hi;
3383 view_items: view_items,
3386 id: ast::DUMMY_NODE_ID,
3388 span: mk_sp(lo, hi),
3392 // matches optbounds = ( ( : ( boundseq )? )? )
3393 // where boundseq = ( bound + boundseq ) | bound
3394 // and bound = 'static | ty
3395 // Returns "None" if there's no colon (e.g. "T");
3396 // Returns "Some(Empty)" if there's a colon but nothing after (e.g. "T:")
3397 // Returns "Some(stuff)" otherwise (e.g. "T:stuff").
3398 // NB: The None/Some distinction is important for issue #7264.
3399 fn parse_optional_ty_param_bounds(&mut self) -> Option<OwnedSlice<TyParamBound>> {
3400 if !self.eat(&token::COLON) {
3404 let mut result = vec!();
3407 token::LIFETIME(lifetime) => {
3408 let lifetime_interned_string = token::get_ident(lifetime);
3409 if lifetime_interned_string.equiv(&("static")) {
3410 result.push(RegionTyParamBound);
3412 self.span_err(self.span,
3413 "`'static` is the only permissible region bound here");
3417 token::MOD_SEP | token::IDENT(..) => {
3418 let tref = self.parse_trait_ref();
3419 result.push(TraitTyParamBound(tref));
3424 if !self.eat(&token::BINOP(token::PLUS)) {
3429 return Some(OwnedSlice::from_vec(result));
3432 // matches typaram = IDENT optbounds ( EQ ty )?
3433 fn parse_ty_param(&mut self) -> TyParam {
3434 let ident = self.parse_ident();
3435 let opt_bounds = self.parse_optional_ty_param_bounds();
3436 // For typarams we don't care about the difference b/w "<T>" and "<T:>".
3437 let bounds = opt_bounds.unwrap_or_default();
3439 let default = if self.token == token::EQ {
3441 Some(self.parse_ty(false))
3447 id: ast::DUMMY_NODE_ID,
3453 // parse a set of optional generic type parameter declarations
3454 // matches generics = ( ) | ( < > ) | ( < typaramseq ( , )? > ) | ( < lifetimes ( , )? > )
3455 // | ( < lifetimes , typaramseq ( , )? > )
3456 // where typaramseq = ( typaram ) | ( typaram , typaramseq )
3457 pub fn parse_generics(&mut self) -> ast::Generics {
3458 if self.eat(&token::LT) {
3459 let lifetimes = self.parse_lifetimes();
3460 let mut seen_default = false;
3461 let ty_params = self.parse_seq_to_gt(Some(token::COMMA), |p| {
3462 let ty_param = p.parse_ty_param();
3463 if ty_param.default.is_some() {
3464 seen_default = true;
3465 } else if seen_default {
3466 p.span_err(p.last_span,
3467 "type parameters with a default must be trailing");
3471 ast::Generics { lifetimes: lifetimes, ty_params: ty_params }
3473 ast_util::empty_generics()
3477 fn parse_generic_values_after_lt(&mut self) -> (Vec<ast::Lifetime>, Vec<P<Ty>> ) {
3478 let lifetimes = self.parse_lifetimes();
3479 let result = self.parse_seq_to_gt(
3481 |p| p.parse_ty(false));
3482 (lifetimes, result.into_vec())
3485 fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool)
3486 -> (Vec<Arg> , bool) {
3488 let mut args: Vec<Option<Arg>> =
3489 self.parse_unspanned_seq(
3492 seq_sep_trailing_allowed(token::COMMA),
3494 if p.token == token::DOTDOTDOT {
3497 if p.token != token::RPAREN {
3498 p.span_fatal(p.span,
3499 "`...` must be last in argument list for variadic function");
3502 p.span_fatal(p.span,
3503 "only foreign functions are allowed to be variadic");
3507 Some(p.parse_arg_general(named_args))
3512 let variadic = match args.pop() {
3515 // Need to put back that last arg
3522 if variadic && args.is_empty() {
3524 "variadic function must be declared with at least one named argument");
3527 let args = args.move_iter().map(|x| x.unwrap()).collect();
3532 // parse the argument list and result type of a function declaration
3533 pub fn parse_fn_decl(&mut self, allow_variadic: bool) -> P<FnDecl> {
3535 let (args, variadic) = self.parse_fn_args(true, allow_variadic);
3536 let (ret_style, ret_ty) = self.parse_ret_ty();
3546 fn is_self_ident(&mut self) -> bool {
3548 token::IDENT(id, false) => id.name == special_idents::self_.name,
3553 fn expect_self_ident(&mut self) {
3554 if !self.is_self_ident() {
3555 let token_str = self.this_token_to_str();
3556 self.fatal(format!("expected `self` but found `{}`", token_str))
3561 // parse the argument list and result type of a function
3562 // that may have a self type.
3563 fn parse_fn_decl_with_self(&mut self, parse_arg_fn: |&mut Parser| -> Arg)
3564 -> (ExplicitSelf, P<FnDecl>) {
3565 fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
3566 -> ast::ExplicitSelf_ {
3567 // The following things are possible to see here:
3572 // fn(&'lt mut self)
3574 // We already know that the current token is `&`.
3576 if this.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) {
3578 this.expect_self_ident();
3579 SelfRegion(None, MutImmutable)
3580 } else if this.look_ahead(1, |t| Parser::token_is_mutability(t)) &&
3582 |t| token::is_keyword(keywords::Self,
3585 let mutability = this.parse_mutability();
3586 this.expect_self_ident();
3587 SelfRegion(None, mutability)
3588 } else if this.look_ahead(1, |t| Parser::token_is_lifetime(t)) &&
3590 |t| token::is_keyword(keywords::Self,
3593 let lifetime = this.parse_lifetime();
3594 this.expect_self_ident();
3595 SelfRegion(Some(lifetime), MutImmutable)
3596 } else if this.look_ahead(1, |t| Parser::token_is_lifetime(t)) &&
3597 this.look_ahead(2, |t| {
3598 Parser::token_is_mutability(t)
3600 this.look_ahead(3, |t| token::is_keyword(keywords::Self,
3603 let lifetime = this.parse_lifetime();
3604 let mutability = this.parse_mutability();
3605 this.expect_self_ident();
3606 SelfRegion(Some(lifetime), mutability)
3612 self.expect(&token::LPAREN);
3614 // A bit of complexity and lookahead is needed here in order to be
3615 // backwards compatible.
3616 let lo = self.span.lo;
3617 let mut mutbl_self = MutImmutable;
3618 let explicit_self = match self.token {
3619 token::BINOP(token::AND) => {
3620 maybe_parse_borrowed_explicit_self(self)
3623 // We need to make sure it isn't a type
3624 if self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) {
3626 self.expect_self_ident();
3632 token::IDENT(..) if self.is_self_ident() => {
3636 token::BINOP(token::STAR) => {
3637 // Possibly "*self" or "*mut self" -- not supported. Try to avoid
3638 // emitting cryptic "unexpected token" errors.
3640 let _mutability = if Parser::token_is_mutability(&self.token) {
3641 self.parse_mutability()
3642 } else { MutImmutable };
3643 if self.is_self_ident() {
3644 self.span_err(self.span, "cannot pass self by unsafe pointer");
3649 _ if Parser::token_is_mutability(&self.token) &&
3650 self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) => {
3651 mutbl_self = self.parse_mutability();
3652 self.expect_self_ident();
3655 _ if Parser::token_is_mutability(&self.token) &&
3656 self.look_ahead(1, |t| *t == token::TILDE) &&
3657 self.look_ahead(2, |t| token::is_keyword(keywords::Self, t)) => {
3658 mutbl_self = self.parse_mutability();
3660 self.expect_self_ident();
3666 let explicit_self_sp = mk_sp(lo, self.span.hi);
3668 // If we parsed a self type, expect a comma before the argument list.
3669 let fn_inputs = if explicit_self != SelfStatic {
3673 let sep = seq_sep_trailing_disallowed(token::COMMA);
3674 let mut fn_inputs = self.parse_seq_to_before_end(
3679 fn_inputs.unshift(Arg::new_self(explicit_self_sp, mutbl_self));
3683 vec!(Arg::new_self(explicit_self_sp, mutbl_self))
3686 let token_str = self.this_token_to_str();
3687 self.fatal(format!("expected `,` or `)`, found `{}`",
3692 let sep = seq_sep_trailing_disallowed(token::COMMA);
3693 self.parse_seq_to_before_end(&token::RPAREN, sep, parse_arg_fn)
3696 self.expect(&token::RPAREN);
3698 let hi = self.span.hi;
3700 let (ret_style, ret_ty) = self.parse_ret_ty();
3702 let fn_decl = P(FnDecl {
3709 (spanned(lo, hi, explicit_self), fn_decl)
3712 // parse the |arg, arg| header on a lambda
3713 fn parse_fn_block_decl(&mut self) -> P<FnDecl> {
3714 let inputs_captures = {
3715 if self.eat(&token::OROR) {
3718 self.parse_unspanned_seq(
3719 &token::BINOP(token::OR),
3720 &token::BINOP(token::OR),
3721 seq_sep_trailing_disallowed(token::COMMA),
3722 |p| p.parse_fn_block_arg()
3726 let output = if self.eat(&token::RARROW) {
3727 self.parse_ty(false)
3730 id: ast::DUMMY_NODE_ID,
3737 inputs: inputs_captures,
3744 // Parses the `(arg, arg) -> return_type` header on a procedure.
3745 fn parse_proc_decl(&mut self) -> P<FnDecl> {
3747 self.parse_unspanned_seq(&token::LPAREN,
3749 seq_sep_trailing_allowed(token::COMMA),
3750 |p| p.parse_fn_block_arg());
3752 let output = if self.eat(&token::RARROW) {
3753 self.parse_ty(false)
3756 id: ast::DUMMY_NODE_ID,
3770 // parse the name and optional generic types of a function header.
3771 fn parse_fn_header(&mut self) -> (Ident, ast::Generics) {
3772 let id = self.parse_ident();
3773 let generics = self.parse_generics();
3777 fn mk_item(&mut self, lo: BytePos, hi: BytePos, ident: Ident,
3778 node: Item_, vis: Visibility,
3779 attrs: Vec<Attribute> ) -> @Item {
3783 id: ast::DUMMY_NODE_ID,
3790 // parse an item-position function declaration.
3791 fn parse_item_fn(&mut self, purity: Purity, abis: AbiSet) -> ItemInfo {
3792 let (ident, generics) = self.parse_fn_header();
3793 let decl = self.parse_fn_decl(false);
3794 let (inner_attrs, body) = self.parse_inner_attrs_and_block();
3795 (ident, ItemFn(decl, purity, abis, generics, body), Some(inner_attrs))
3798 // parse a method in a trait impl, starting with `attrs` attributes.
3799 fn parse_method(&mut self, already_parsed_attrs: Option<Vec<Attribute> >) -> @Method {
3800 let next_attrs = self.parse_outer_attributes();
3801 let attrs = match already_parsed_attrs {
3802 Some(mut a) => { a.push_all_move(next_attrs); a }
3806 let lo = self.span.lo;
3808 let visa = self.parse_visibility();
3809 let pur = self.parse_fn_purity();
3810 let ident = self.parse_ident();
3811 let generics = self.parse_generics();
3812 let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| {
3816 let (inner_attrs, body) = self.parse_inner_attrs_and_block();
3817 let hi = body.span.hi;
3818 let attrs = vec::append(attrs, inner_attrs.as_slice());
3823 explicit_self: explicit_self,
3827 id: ast::DUMMY_NODE_ID,
3828 span: mk_sp(lo, hi),
3833 // parse trait Foo { ... }
3834 fn parse_item_trait(&mut self) -> ItemInfo {
3835 let ident = self.parse_ident();
3836 let tps = self.parse_generics();
3838 // Parse traits, if necessary.
3840 if self.token == token::COLON {
3842 traits = self.parse_trait_ref_list(&token::LBRACE);
3844 traits = Vec::new();
3847 let meths = self.parse_trait_methods();
3848 (ident, ItemTrait(tps, traits, meths), None)
3851 // Parses two variants (with the region/type params always optional):
3852 // impl<T> Foo { ... }
3853 // impl<T> ToStr for ~[T] { ... }
3854 fn parse_item_impl(&mut self) -> ItemInfo {
3855 // First, parse type parameters if necessary.
3856 let generics = self.parse_generics();
3858 // Special case: if the next identifier that follows is '(', don't
3859 // allow this to be parsed as a trait.
3860 let could_be_trait = self.token != token::LPAREN;
3863 let mut ty = self.parse_ty(false);
3865 // Parse traits, if necessary.
3866 let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) {
3867 // New-style trait. Reinterpret the type as a trait.
3868 let opt_trait_ref = match ty.node {
3869 TyPath(ref path, None, node_id) => {
3871 path: /* bad */ (*path).clone(),
3876 self.span_err(ty.span,
3877 "bounded traits are only valid in type position");
3881 self.span_err(ty.span, "not a trait");
3886 ty = self.parse_ty(false);
3892 let mut meths = Vec::new();
3893 self.expect(&token::LBRACE);
3894 let (inner_attrs, next) = self.parse_inner_attrs_and_next();
3895 let mut method_attrs = Some(next);
3896 while !self.eat(&token::RBRACE) {
3897 meths.push(self.parse_method(method_attrs));
3898 method_attrs = None;
3901 let ident = ast_util::impl_pretty_name(&opt_trait, ty);
3903 (ident, ItemImpl(generics, opt_trait, ty, meths), Some(inner_attrs))
3906 // parse a::B<~str,int>
3907 fn parse_trait_ref(&mut self) -> TraitRef {
3909 path: self.parse_path(LifetimeAndTypesWithoutColons).path,
3910 ref_id: ast::DUMMY_NODE_ID,
3914 // parse B + C<~str,int> + D
3915 fn parse_trait_ref_list(&mut self, ket: &token::Token) -> Vec<TraitRef> {
3916 self.parse_seq_to_before_end(
3918 seq_sep_trailing_disallowed(token::BINOP(token::PLUS)),
3919 |p| p.parse_trait_ref()
3923 // parse struct Foo { ... }
3924 fn parse_item_struct(&mut self) -> ItemInfo {
3925 let class_name = self.parse_ident();
3926 let generics = self.parse_generics();
3928 let mut fields: Vec<StructField> ;
3931 if self.eat(&token::LBRACE) {
3932 // It's a record-like struct.
3933 is_tuple_like = false;
3934 fields = Vec::new();
3935 while self.token != token::RBRACE {
3936 fields.push(self.parse_struct_decl_field());
3938 if fields.len() == 0 {
3939 self.fatal(format!("unit-like struct definition should be written as `struct {};`",
3940 token::get_ident(class_name)));
3943 } else if self.token == token::LPAREN {
3944 // It's a tuple-like struct.
3945 is_tuple_like = true;
3946 fields = self.parse_unspanned_seq(
3949 seq_sep_trailing_allowed(token::COMMA),
3951 let attrs = p.parse_outer_attributes();
3953 let struct_field_ = ast::StructField_ {
3954 kind: UnnamedField(p.parse_visibility()),
3955 id: ast::DUMMY_NODE_ID,
3956 ty: p.parse_ty(false),
3959 spanned(lo, p.span.hi, struct_field_)
3961 self.expect(&token::SEMI);
3962 } else if self.eat(&token::SEMI) {
3963 // It's a unit-like struct.
3964 is_tuple_like = true;
3965 fields = Vec::new();
3967 let token_str = self.this_token_to_str();
3968 self.fatal(format!("expected `\\{`, `(`, or `;` after struct \
3969 name but found `{}`",
3973 let _ = ast::DUMMY_NODE_ID; // FIXME: Workaround for crazy bug.
3974 let new_id = ast::DUMMY_NODE_ID;
3976 ItemStruct(@ast::StructDef {
3978 ctor_id: if is_tuple_like { Some(new_id) } else { None }
3983 // parse a structure field declaration
3984 pub fn parse_single_struct_field(&mut self,
3986 attrs: Vec<Attribute> )
3988 let a_var = self.parse_name_and_ty(vis, attrs);
3995 let token_str = self.this_token_to_str();
3996 self.span_fatal(self.span,
3997 format!("expected `,`, or `\\}` but found `{}`",
4004 // parse an element of a struct definition
4005 fn parse_struct_decl_field(&mut self) -> StructField {
4007 let attrs = self.parse_outer_attributes();
4009 if self.eat_keyword(keywords::Priv) {
4010 return self.parse_single_struct_field(Private, attrs);
4013 if self.eat_keyword(keywords::Pub) {
4014 return self.parse_single_struct_field(Public, attrs);
4017 return self.parse_single_struct_field(Inherited, attrs);
4020 // parse visiility: PUB, PRIV, or nothing
4021 fn parse_visibility(&mut self) -> Visibility {
4022 if self.eat_keyword(keywords::Pub) { Public }
4023 else if self.eat_keyword(keywords::Priv) { Private }
4027 // given a termination token and a vector of already-parsed
4028 // attributes (of length 0 or 1), parse all of the items in a module
4029 fn parse_mod_items(&mut self,
4031 first_item_attrs: Vec<Attribute> )
4033 // parse all of the items up to closing or an attribute.
4034 // view items are legal here.
4035 let ParsedItemsAndViewItems {
4036 attrs_remaining: attrs_remaining,
4037 view_items: view_items,
4038 items: starting_items,
4040 } = self.parse_items_and_view_items(first_item_attrs, true, true);
4041 let mut items: Vec<@Item> = starting_items;
4042 let attrs_remaining_len = attrs_remaining.len();
4044 // don't think this other loop is even necessary....
4046 let mut first = true;
4047 while self.token != term {
4048 let mut attrs = self.parse_outer_attributes();
4050 attrs = vec::append(attrs_remaining.clone(),
4054 debug!("parse_mod_items: parse_item_or_view_item(attrs={:?})",
4056 match self.parse_item_or_view_item(attrs,
4057 true /* macros allowed */) {
4058 IoviItem(item) => items.push(item),
4059 IoviViewItem(view_item) => {
4060 self.span_fatal(view_item.span,
4061 "view items must be declared at the top of \
4065 let token_str = self.this_token_to_str();
4066 self.fatal(format!("expected item but found `{}`",
4072 if first && attrs_remaining_len > 0u {
4073 // We parsed attributes for the first item but didn't find it
4074 self.span_err(self.last_span, "expected item after attributes");
4077 ast::Mod { view_items: view_items, items: items }
4080 fn parse_item_const(&mut self) -> ItemInfo {
4081 let m = if self.eat_keyword(keywords::Mut) {MutMutable} else {MutImmutable};
4082 let id = self.parse_ident();
4083 self.expect(&token::COLON);
4084 let ty = self.parse_ty(false);
4085 self.expect(&token::EQ);
4086 let e = self.parse_expr();
4087 self.commit_expr_expecting(e, token::SEMI);
4088 (id, ItemStatic(ty, m, e), None)
4091 // parse a `mod <foo> { ... }` or `mod <foo>;` item
4092 fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> ItemInfo {
4093 let id_span = self.span;
4094 let id = self.parse_ident();
4095 if self.token == token::SEMI {
4097 // This mod is in an external file. Let's go get it!
4098 let (m, attrs) = self.eval_src_mod(id, outer_attrs, id_span);
4099 (id, m, Some(attrs))
4101 self.push_mod_path(id, outer_attrs);
4102 self.expect(&token::LBRACE);
4103 let (inner, next) = self.parse_inner_attrs_and_next();
4104 let m = self.parse_mod_items(token::RBRACE, next);
4105 self.expect(&token::RBRACE);
4106 self.pop_mod_path();
4107 (id, ItemMod(m), Some(inner))
4111 fn push_mod_path(&mut self, id: Ident, attrs: &[Attribute]) {
4112 let default_path = self.id_to_interned_str(id);
4113 let file_path = match ::attr::first_attr_value_str_by_name(attrs,
4116 None => default_path,
4118 self.mod_path_stack.push(file_path)
4121 fn pop_mod_path(&mut self) {
4122 self.mod_path_stack.pop().unwrap();
4125 // read a module from a source file.
4126 fn eval_src_mod(&mut self,
4128 outer_attrs: &[ast::Attribute],
4130 -> (ast::Item_, Vec<ast::Attribute> ) {
4131 let mut prefix = Path::new(self.sess.span_diagnostic.cm.span_to_filename(self.span));
4133 let mod_path = Path::new(".").join_many(self.mod_path_stack.as_slice());
4134 let dir_path = prefix.join(&mod_path);
4135 let file_path = match ::attr::first_attr_value_str_by_name(
4136 outer_attrs, "path") {
4137 Some(d) => dir_path.join(d),
4139 let mod_string = token::get_ident(id);
4140 let mod_name = mod_string.get().to_owned();
4141 let default_path_str = mod_name + ".rs";
4142 let secondary_path_str = mod_name + "/mod.rs";
4143 let default_path = dir_path.join(default_path_str.as_slice());
4144 let secondary_path = dir_path.join(secondary_path_str.as_slice());
4145 let default_exists = default_path.exists();
4146 let secondary_exists = secondary_path.exists();
4147 match (default_exists, secondary_exists) {
4148 (true, false) => default_path,
4149 (false, true) => secondary_path,
4151 self.span_fatal(id_sp, format!("file not found for module `{}`", mod_name));
4154 self.span_fatal(id_sp,
4155 format!("file for module `{}` found at both {} and {}",
4156 mod_name, default_path_str, secondary_path_str));
4162 self.eval_src_mod_from_path(file_path,
4163 outer_attrs.iter().map(|x| *x).collect(),
4167 fn eval_src_mod_from_path(&mut self,
4169 outer_attrs: Vec<ast::Attribute> ,
4170 id_sp: Span) -> (ast::Item_, Vec<ast::Attribute> ) {
4171 let mut included_mod_stack = self.sess.included_mod_stack.borrow_mut();
4172 match included_mod_stack.iter().position(|p| *p == path) {
4174 let mut err = ~"circular modules: ";
4175 let len = included_mod_stack.len();
4176 for p in included_mod_stack.slice(i, len).iter() {
4177 err.push_str(p.display().as_maybe_owned().as_slice());
4178 err.push_str(" -> ");
4180 err.push_str(path.display().as_maybe_owned().as_slice());
4181 self.span_fatal(id_sp, err);
4185 included_mod_stack.push(path.clone());
4186 drop(included_mod_stack);
4189 new_sub_parser_from_file(self.sess,
4193 let (inner, next) = p0.parse_inner_attrs_and_next();
4194 let mod_attrs = vec::append(outer_attrs, inner.as_slice());
4195 let first_item_outer_attrs = next;
4196 let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs);
4197 self.sess.included_mod_stack.borrow_mut().pop();
4198 return (ast::ItemMod(m0), mod_attrs);
4201 // parse a function declaration from a foreign module
4202 fn parse_item_foreign_fn(&mut self, vis: ast::Visibility,
4203 attrs: Vec<Attribute> ) -> @ForeignItem {
4204 let lo = self.span.lo;
4206 // Parse obsolete purity.
4207 let purity = self.parse_fn_purity();
4208 if purity != ImpureFn {
4209 self.obsolete(self.last_span, ObsoleteUnsafeExternFn);
4212 let (ident, generics) = self.parse_fn_header();
4213 let decl = self.parse_fn_decl(true);
4214 let hi = self.span.hi;
4215 self.expect(&token::SEMI);
4216 @ast::ForeignItem { ident: ident,
4218 node: ForeignItemFn(decl, generics),
4219 id: ast::DUMMY_NODE_ID,
4220 span: mk_sp(lo, hi),
4224 // parse a static item from a foreign module
4225 fn parse_item_foreign_static(&mut self, vis: ast::Visibility,
4226 attrs: Vec<Attribute> ) -> @ForeignItem {
4227 let lo = self.span.lo;
4229 self.expect_keyword(keywords::Static);
4230 let mutbl = self.eat_keyword(keywords::Mut);
4232 let ident = self.parse_ident();
4233 self.expect(&token::COLON);
4234 let ty = self.parse_ty(false);
4235 let hi = self.span.hi;
4236 self.expect(&token::SEMI);
4237 @ast::ForeignItem { ident: ident,
4239 node: ForeignItemStatic(ty, mutbl),
4240 id: ast::DUMMY_NODE_ID,
4241 span: mk_sp(lo, hi),
4245 // parse safe/unsafe and fn
4246 fn parse_fn_purity(&mut self) -> Purity {
4247 if self.eat_keyword(keywords::Fn) { ImpureFn }
4248 else if self.eat_keyword(keywords::Unsafe) {
4249 self.expect_keyword(keywords::Fn);
4252 else { self.unexpected(); }
4256 // at this point, this is essentially a wrapper for
4257 // parse_foreign_items.
4258 fn parse_foreign_mod_items(&mut self,
4260 first_item_attrs: Vec<Attribute> )
4262 let ParsedItemsAndViewItems {
4263 attrs_remaining: attrs_remaining,
4264 view_items: view_items,
4266 foreign_items: foreign_items
4267 } = self.parse_foreign_items(first_item_attrs, true);
4268 if ! attrs_remaining.is_empty() {
4269 self.span_err(self.last_span,
4270 "expected item after attributes");
4272 assert!(self.token == token::RBRACE);
4275 view_items: view_items,
4276 items: foreign_items
4280 /// Parse extern crate links
4284 /// extern crate url;
4285 /// extern crate foo = "bar";
4286 fn parse_item_extern_crate(&mut self,
4288 visibility: Visibility,
4289 attrs: Vec<Attribute> )
4292 let (maybe_path, ident) = match self.token {
4293 token::IDENT(..) => {
4294 let the_ident = self.parse_ident();
4295 self.expect_one_of(&[], &[token::EQ, token::SEMI]);
4296 let path = if self.token == token::EQ {
4298 Some(self.parse_str())
4301 self.expect(&token::SEMI);
4305 let token_str = self.this_token_to_str();
4306 self.span_fatal(self.span,
4307 format!("expected extern crate name but found `{}`",
4312 IoviViewItem(ast::ViewItem {
4313 node: ViewItemExternCrate(ident, maybe_path, ast::DUMMY_NODE_ID),
4316 span: mk_sp(lo, self.last_span.hi)
4320 /// Parse `extern` for foreign ABIs
4323 /// `extern` is expected to have been
4324 /// consumed before calling this method
4330 fn parse_item_foreign_mod(&mut self,
4332 opt_abis: Option<AbiSet>,
4333 visibility: Visibility,
4334 attrs: Vec<Attribute> )
4337 self.expect(&token::LBRACE);
4339 let abis = opt_abis.unwrap_or(AbiSet::C());
4341 let (inner, next) = self.parse_inner_attrs_and_next();
4342 let m = self.parse_foreign_mod_items(abis, next);
4343 self.expect(&token::RBRACE);
4345 let item = self.mk_item(lo,
4347 special_idents::invalid,
4350 maybe_append(attrs, Some(inner)));
4351 return IoviItem(item);
4354 // parse type Foo = Bar;
4355 fn parse_item_type(&mut self) -> ItemInfo {
4356 let ident = self.parse_ident();
4357 let tps = self.parse_generics();
4358 self.expect(&token::EQ);
4359 let ty = self.parse_ty(false);
4360 self.expect(&token::SEMI);
4361 (ident, ItemTy(ty, tps), None)
4364 // parse a structure-like enum variant definition
4365 // this should probably be renamed or refactored...
4366 fn parse_struct_def(&mut self) -> @StructDef {
4367 let mut fields: Vec<StructField> = Vec::new();
4368 while self.token != token::RBRACE {
4369 fields.push(self.parse_struct_decl_field());
4373 return @ast::StructDef {
4379 // parse the part of an "enum" decl following the '{'
4380 fn parse_enum_def(&mut self, _generics: &ast::Generics) -> EnumDef {
4381 let mut variants = Vec::new();
4382 let mut all_nullary = true;
4383 let mut have_disr = false;
4384 while self.token != token::RBRACE {
4385 let variant_attrs = self.parse_outer_attributes();
4386 let vlo = self.span.lo;
4388 let vis = self.parse_visibility();
4392 let mut args = Vec::new();
4393 let mut disr_expr = None;
4394 ident = self.parse_ident();
4395 if self.eat(&token::LBRACE) {
4396 // Parse a struct variant.
4397 all_nullary = false;
4398 kind = StructVariantKind(self.parse_struct_def());
4399 } else if self.token == token::LPAREN {
4400 all_nullary = false;
4401 let arg_tys = self.parse_enum_variant_seq(
4404 seq_sep_trailing_disallowed(token::COMMA),
4405 |p| p.parse_ty(false)
4407 for ty in arg_tys.move_iter() {
4408 args.push(ast::VariantArg {
4410 id: ast::DUMMY_NODE_ID,
4413 kind = TupleVariantKind(args);
4414 } else if self.eat(&token::EQ) {
4416 disr_expr = Some(self.parse_expr());
4417 kind = TupleVariantKind(args);
4419 kind = TupleVariantKind(Vec::new());
4422 let vr = ast::Variant_ {
4424 attrs: variant_attrs,
4426 id: ast::DUMMY_NODE_ID,
4427 disr_expr: disr_expr,
4430 variants.push(P(spanned(vlo, self.last_span.hi, vr)));
4432 if !self.eat(&token::COMMA) { break; }
4434 self.expect(&token::RBRACE);
4435 if have_disr && !all_nullary {
4436 self.fatal("discriminator values can only be used with a c-like \
4440 ast::EnumDef { variants: variants }
4443 // parse an "enum" declaration
4444 fn parse_item_enum(&mut self) -> ItemInfo {
4445 let id = self.parse_ident();
4446 let generics = self.parse_generics();
4447 self.expect(&token::LBRACE);
4449 let enum_definition = self.parse_enum_def(&generics);
4450 (id, ItemEnum(enum_definition, generics), None)
4453 fn fn_expr_lookahead(tok: &token::Token) -> bool {
4455 token::LPAREN | token::AT | token::TILDE | token::BINOP(_) => true,
4460 // Parses a string as an ABI spec on an extern type or module. Consumes
4461 // the `extern` keyword, if one is found.
4462 fn parse_opt_abis(&mut self) -> Option<AbiSet> {
4465 | token::LIT_STR_RAW(s, _) => {
4467 let identifier_string = token::get_ident(s);
4468 let the_string = identifier_string.get();
4469 let mut abis = AbiSet::empty();
4470 for word in the_string.words() {
4471 match abi::lookup(word) {
4473 if abis.contains(abi) {
4476 format!("ABI `{}` appears twice",
4486 format!("illegal ABI: \
4487 expected one of [{}], \
4489 abi::all_names().connect(", "),
4503 // parse one of the items or view items allowed by the
4504 // flags; on failure, return IoviNone.
4505 // NB: this function no longer parses the items inside an
4507 fn parse_item_or_view_item(&mut self,
4508 attrs: Vec<Attribute> ,
4509 macros_allowed: bool)
4512 INTERPOLATED(token::NtItem(item)) => {
4514 let new_attrs = vec::append(attrs, item.attrs.as_slice());
4515 return IoviItem(@Item {
4523 let lo = self.span.lo;
4525 let visibility = self.parse_visibility();
4527 // must be a view item:
4528 if self.eat_keyword(keywords::Use) {
4529 // USE ITEM (IoviViewItem)
4530 let view_item = self.parse_use();
4531 self.expect(&token::SEMI);
4532 return IoviViewItem(ast::ViewItem {
4536 span: mk_sp(lo, self.last_span.hi)
4539 // either a view item or an item:
4540 if self.eat_keyword(keywords::Extern) {
4541 let next_is_mod = self.eat_keyword(keywords::Mod);
4543 if next_is_mod || self.eat_keyword(keywords::Crate) {
4545 self.span_err(mk_sp(lo, self.last_span.hi),
4546 format!("`extern mod` is obsolete, use \
4547 `extern crate` instead \
4548 to refer to external crates."))
4550 return self.parse_item_extern_crate(lo, visibility, attrs);
4553 let opt_abis = self.parse_opt_abis();
4555 if self.eat_keyword(keywords::Fn) {
4556 // EXTERN FUNCTION ITEM
4557 let abis = opt_abis.unwrap_or(AbiSet::C());
4558 let (ident, item_, extra_attrs) =
4559 self.parse_item_fn(ExternFn, abis);
4560 let item = self.mk_item(lo,
4565 maybe_append(attrs, extra_attrs));
4566 return IoviItem(item);
4567 } else if self.token == token::LBRACE {
4568 return self.parse_item_foreign_mod(lo, opt_abis, visibility, attrs);
4571 let token_str = self.this_token_to_str();
4572 self.span_fatal(self.span,
4573 format!("expected `\\{` or `fn` but found `{}`", token_str));
4576 // the rest are all guaranteed to be items:
4577 if self.is_keyword(keywords::Static) {
4580 let (ident, item_, extra_attrs) = self.parse_item_const();
4581 let item = self.mk_item(lo,
4586 maybe_append(attrs, extra_attrs));
4587 return IoviItem(item);
4589 if self.is_keyword(keywords::Fn) &&
4590 self.look_ahead(1, |f| !Parser::fn_expr_lookahead(f)) {
4593 let (ident, item_, extra_attrs) =
4594 self.parse_item_fn(ImpureFn, AbiSet::Rust());
4595 let item = self.mk_item(lo,
4600 maybe_append(attrs, extra_attrs));
4601 return IoviItem(item);
4603 if self.is_keyword(keywords::Unsafe)
4604 && self.look_ahead(1u, |t| *t != token::LBRACE) {
4605 // UNSAFE FUNCTION ITEM
4607 self.expect_keyword(keywords::Fn);
4608 let (ident, item_, extra_attrs) =
4609 self.parse_item_fn(UnsafeFn, AbiSet::Rust());
4610 let item = self.mk_item(lo,
4615 maybe_append(attrs, extra_attrs));
4616 return IoviItem(item);
4618 if self.eat_keyword(keywords::Mod) {
4620 let (ident, item_, extra_attrs) =
4621 self.parse_item_mod(attrs.as_slice());
4622 let item = self.mk_item(lo,
4627 maybe_append(attrs, extra_attrs));
4628 return IoviItem(item);
4630 if self.eat_keyword(keywords::Type) {
4632 let (ident, item_, extra_attrs) = self.parse_item_type();
4633 let item = self.mk_item(lo,
4638 maybe_append(attrs, extra_attrs));
4639 return IoviItem(item);
4641 if self.eat_keyword(keywords::Enum) {
4643 let (ident, item_, extra_attrs) = self.parse_item_enum();
4644 let item = self.mk_item(lo,
4649 maybe_append(attrs, extra_attrs));
4650 return IoviItem(item);
4652 if self.eat_keyword(keywords::Trait) {
4654 let (ident, item_, extra_attrs) = self.parse_item_trait();
4655 let item = self.mk_item(lo,
4660 maybe_append(attrs, extra_attrs));
4661 return IoviItem(item);
4663 if self.eat_keyword(keywords::Impl) {
4665 let (ident, item_, extra_attrs) = self.parse_item_impl();
4666 let item = self.mk_item(lo,
4671 maybe_append(attrs, extra_attrs));
4672 return IoviItem(item);
4674 if self.eat_keyword(keywords::Struct) {
4676 let (ident, item_, extra_attrs) = self.parse_item_struct();
4677 let item = self.mk_item(lo,
4682 maybe_append(attrs, extra_attrs));
4683 return IoviItem(item);
4685 self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
4688 // parse a foreign item; on failure, return IoviNone.
4689 fn parse_foreign_item(&mut self,
4690 attrs: Vec<Attribute> ,
4691 macros_allowed: bool)
4693 maybe_whole!(iovi self, NtItem);
4694 let lo = self.span.lo;
4696 let visibility = self.parse_visibility();
4698 if self.is_keyword(keywords::Static) {
4699 // FOREIGN STATIC ITEM
4700 let item = self.parse_item_foreign_static(visibility, attrs);
4701 return IoviForeignItem(item);
4703 if self.is_keyword(keywords::Fn) || self.is_keyword(keywords::Unsafe) {
4704 // FOREIGN FUNCTION ITEM
4705 let item = self.parse_item_foreign_fn(visibility, attrs);
4706 return IoviForeignItem(item);
4708 self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
4711 // this is the fall-through for parsing items.
4712 fn parse_macro_use_or_failure(
4714 attrs: Vec<Attribute> ,
4715 macros_allowed: bool,
4717 visibility: Visibility
4718 ) -> ItemOrViewItem {
4719 if macros_allowed && !token::is_any_keyword(&self.token)
4720 && self.look_ahead(1, |t| *t == token::NOT)
4721 && (self.look_ahead(2, |t| is_plain_ident(t))
4722 || self.look_ahead(2, |t| *t == token::LPAREN)
4723 || self.look_ahead(2, |t| *t == token::LBRACE)) {
4724 // MACRO INVOCATION ITEM
4727 let pth = self.parse_path(NoTypesAllowed).path;
4728 self.expect(&token::NOT);
4730 // a 'special' identifier (like what `macro_rules!` uses)
4731 // is optional. We should eventually unify invoc syntax
4733 let id = if is_plain_ident(&self.token) {
4736 token::special_idents::invalid // no special identifier
4738 // eat a matched-delimiter token tree:
4739 let tts = match self.token {
4740 token::LPAREN | token::LBRACE => {
4741 let ket = token::flip_delimiter(&self.token);
4743 self.parse_seq_to_end(&ket,
4745 |p| p.parse_token_tree())
4747 _ => self.fatal("expected open delimiter")
4749 // single-variant-enum... :
4750 let m = ast::MacInvocTT(pth, tts, EMPTY_CTXT);
4751 let m: ast::Mac = codemap::Spanned { node: m,
4752 span: mk_sp(self.span.lo,
4754 let item_ = ItemMac(m);
4755 let item = self.mk_item(lo,
4761 return IoviItem(item);
4764 // FAILURE TO PARSE ITEM
4765 if visibility != Inherited {
4766 let mut s = ~"unmatched visibility `";
4767 if visibility == Public {
4773 self.span_fatal(self.last_span, s);
4775 return IoviNone(attrs);
4778 pub fn parse_item(&mut self, attrs: Vec<Attribute> ) -> Option<@Item> {
4779 match self.parse_item_or_view_item(attrs, true) {
4780 IoviNone(_) => None,
4782 self.fatal("view items are not allowed here"),
4783 IoviForeignItem(_) =>
4784 self.fatal("foreign items are not allowed here"),
4785 IoviItem(item) => Some(item)
4789 // parse, e.g., "use a::b::{z,y}"
4790 fn parse_use(&mut self) -> ViewItem_ {
4791 return ViewItemUse(self.parse_view_paths());
4795 // matches view_path : MOD? IDENT EQ non_global_path
4796 // | MOD? non_global_path MOD_SEP LBRACE RBRACE
4797 // | MOD? non_global_path MOD_SEP LBRACE ident_seq RBRACE
4798 // | MOD? non_global_path MOD_SEP STAR
4799 // | MOD? non_global_path
4800 fn parse_view_path(&mut self) -> @ViewPath {
4801 let lo = self.span.lo;
4803 if self.token == token::LBRACE {
4805 let idents = self.parse_unspanned_seq(
4806 &token::LBRACE, &token::RBRACE,
4807 seq_sep_trailing_allowed(token::COMMA),
4808 |p| p.parse_path_list_ident());
4809 let path = ast::Path {
4810 span: mk_sp(lo, self.span.hi),
4812 segments: Vec::new()
4814 return @spanned(lo, self.span.hi,
4815 ViewPathList(path, idents, ast::DUMMY_NODE_ID));
4818 let first_ident = self.parse_ident();
4819 let mut path = vec!(first_ident);
4824 let path_lo = self.span.lo;
4825 path = vec!(self.parse_ident());
4826 while self.token == token::MOD_SEP {
4828 let id = self.parse_ident();
4831 let path = ast::Path {
4832 span: mk_sp(path_lo, self.span.hi),
4834 segments: path.move_iter().map(|identifier| {
4836 identifier: identifier,
4837 lifetimes: Vec::new(),
4838 types: OwnedSlice::empty(),
4842 return @spanned(lo, self.span.hi,
4843 ViewPathSimple(first_ident, path,
4844 ast::DUMMY_NODE_ID));
4848 // foo::bar or foo::{a,b,c} or foo::*
4849 while self.token == token::MOD_SEP {
4853 token::IDENT(i, _) => {
4858 // foo::bar::{a,b,c}
4860 let idents = self.parse_unspanned_seq(
4863 seq_sep_trailing_allowed(token::COMMA),
4864 |p| p.parse_path_list_ident()
4866 let path = ast::Path {
4867 span: mk_sp(lo, self.span.hi),
4869 segments: path.move_iter().map(|identifier| {
4871 identifier: identifier,
4872 lifetimes: Vec::new(),
4873 types: OwnedSlice::empty(),
4877 return @spanned(lo, self.span.hi,
4878 ViewPathList(path, idents, ast::DUMMY_NODE_ID));
4882 token::BINOP(token::STAR) => {
4884 let path = ast::Path {
4885 span: mk_sp(lo, self.span.hi),
4887 segments: path.move_iter().map(|identifier| {
4889 identifier: identifier,
4890 lifetimes: Vec::new(),
4891 types: OwnedSlice::empty(),
4895 return @spanned(lo, self.span.hi,
4896 ViewPathGlob(path, ast::DUMMY_NODE_ID));
4905 let last = *path.get(path.len() - 1u);
4906 let path = ast::Path {
4907 span: mk_sp(lo, self.span.hi),
4909 segments: path.move_iter().map(|identifier| {
4911 identifier: identifier,
4912 lifetimes: Vec::new(),
4913 types: OwnedSlice::empty(),
4919 ViewPathSimple(last, path, ast::DUMMY_NODE_ID));
4922 // matches view_paths = view_path | view_path , view_paths
4923 fn parse_view_paths(&mut self) -> Vec<@ViewPath> {
4924 let mut vp = vec!(self.parse_view_path());
4925 while self.token == token::COMMA {
4927 self.obsolete(self.last_span, ObsoleteMultipleImport);
4928 vp.push(self.parse_view_path());
4933 // Parses a sequence of items. Stops when it finds program
4934 // text that can't be parsed as an item
4935 // - mod_items uses extern_mod_allowed = true
4936 // - block_tail_ uses extern_mod_allowed = false
4937 fn parse_items_and_view_items(&mut self,
4938 first_item_attrs: Vec<Attribute> ,
4939 mut extern_mod_allowed: bool,
4940 macros_allowed: bool)
4941 -> ParsedItemsAndViewItems {
4942 let mut attrs = vec::append(first_item_attrs,
4943 self.parse_outer_attributes()
4945 // First, parse view items.
4946 let mut view_items : Vec<ast::ViewItem> = Vec::new();
4947 let mut items = Vec::new();
4949 // I think this code would probably read better as a single
4950 // loop with a mutable three-state-variable (for extern crates,
4951 // view items, and regular items) ... except that because
4952 // of macros, I'd like to delay that entire check until later.
4954 match self.parse_item_or_view_item(attrs, macros_allowed) {
4955 IoviNone(attrs) => {
4956 return ParsedItemsAndViewItems {
4957 attrs_remaining: attrs,
4958 view_items: view_items,
4960 foreign_items: Vec::new()
4963 IoviViewItem(view_item) => {
4964 match view_item.node {
4965 ViewItemUse(..) => {
4966 // `extern crate` must precede `use`.
4967 extern_mod_allowed = false;
4969 ViewItemExternCrate(..) if !extern_mod_allowed => {
4970 self.span_err(view_item.span,
4971 "\"extern crate\" declarations are not allowed here");
4973 ViewItemExternCrate(..) => {}
4975 view_items.push(view_item);
4979 attrs = self.parse_outer_attributes();
4982 IoviForeignItem(_) => {
4986 attrs = self.parse_outer_attributes();
4989 // Next, parse items.
4991 match self.parse_item_or_view_item(attrs, macros_allowed) {
4992 IoviNone(returned_attrs) => {
4993 attrs = returned_attrs;
4996 IoviViewItem(view_item) => {
4997 attrs = self.parse_outer_attributes();
4998 self.span_err(view_item.span,
4999 "`use` and `extern crate` declarations must precede items");
5002 attrs = self.parse_outer_attributes();
5005 IoviForeignItem(_) => {
5011 ParsedItemsAndViewItems {
5012 attrs_remaining: attrs,
5013 view_items: view_items,
5015 foreign_items: Vec::new()
5019 // Parses a sequence of foreign items. Stops when it finds program
5020 // text that can't be parsed as an item
5021 fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute> ,
5022 macros_allowed: bool)
5023 -> ParsedItemsAndViewItems {
5024 let mut attrs = vec::append(first_item_attrs,
5025 self.parse_outer_attributes()
5027 let mut foreign_items = Vec::new();
5029 match self.parse_foreign_item(attrs, macros_allowed) {
5030 IoviNone(returned_attrs) => {
5031 if self.token == token::RBRACE {
5032 attrs = returned_attrs;
5037 IoviViewItem(view_item) => {
5038 // I think this can't occur:
5039 self.span_err(view_item.span,
5040 "`use` and `extern crate` declarations must precede items");
5043 // FIXME #5668: this will occur for a macro invocation:
5044 self.span_fatal(item.span, "macros cannot expand to foreign items");
5046 IoviForeignItem(foreign_item) => {
5047 foreign_items.push(foreign_item);
5050 attrs = self.parse_outer_attributes();
5053 ParsedItemsAndViewItems {
5054 attrs_remaining: attrs,
5055 view_items: Vec::new(),
5057 foreign_items: foreign_items
5061 // Parses a source module as a crate. This is the main
5062 // entry point for the parser.
5063 pub fn parse_crate_mod(&mut self) -> Crate {
5064 let lo = self.span.lo;
5065 // parse the crate's inner attrs, maybe (oops) one
5066 // of the attrs of an item:
5067 let (inner, next) = self.parse_inner_attrs_and_next();
5068 let first_item_outer_attrs = next;
5069 // parse the items inside the crate:
5070 let m = self.parse_mod_items(token::EOF, first_item_outer_attrs);
5075 config: self.cfg.clone(),
5076 span: mk_sp(lo, self.span.lo)
5080 pub fn parse_optional_str(&mut self)
5081 -> Option<(InternedString, ast::StrStyle)> {
5082 let (s, style) = match self.token {
5083 token::LIT_STR(s) => (self.id_to_interned_str(s), ast::CookedStr),
5084 token::LIT_STR_RAW(s, n) => {
5085 (self.id_to_interned_str(s), ast::RawStr(n))
5093 pub fn parse_str(&mut self) -> (InternedString, StrStyle) {
5094 match self.parse_optional_str() {
5096 _ => self.fatal("expected string literal")