X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibsyntax%2Fparse%2Fparser.rs;h=93088648e932b3d4afdf2f7bc9939dac3a317e52;hb=8290c950a8b4cdc70038736abcf29f41dede6e0c;hp=acce6ed87d00b5a25c892fba351bdf499dfddb76;hpb=43c1a173a874f5513db58b2f5321489a00087484;p=rust.git diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index acce6ed87d0..93088648e93 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -10,53 +10,44 @@ pub use self::PathParsingMode::*; -use abi; +use abi::{self, Abi}; use ast::BareFnTy; use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; use ast::{Public, Unsafety}; -use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindingMode}; -use ast::{BiBitAnd, BiBitOr, BiBitXor, BiRem, BiLt, Block}; -use ast::{BlockCheckMode, CaptureByRef, CaptureByValue, CaptureClause}; +use ast::{Mod, Arg, Arm, Attribute, BindingMode}; +use ast::Block; +use ast::{BlockCheckMode, CaptureBy}; use ast::{Constness, ConstTraitItem, Crate, CrateConfig}; -use ast::{Decl, DeclItem, DeclLocal, DefaultBlock, DefaultReturn}; -use ast::{UnDeref, BiDiv, EMPTY_CTXT, EnumDef, ExplicitSelf}; -use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain}; -use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox}; -use ast::{ExprBreak, ExprCall, ExprCast, ExprInPlace}; -use ast::{ExprField, ExprTupField, ExprClosure, ExprIf, ExprIfLet, ExprIndex}; -use ast::{ExprLit, ExprLoop, ExprMac, ExprRange}; -use ast::{ExprMethodCall, ExprParen, ExprPath}; -use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprType, ExprUnary}; -use ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl}; +use ast::{Decl, DeclKind}; +use ast::{EMPTY_CTXT, EnumDef, ExplicitSelf}; +use ast::{Expr, ExprKind}; +use ast::{Field, FnDecl}; use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, FunctionRetTy}; use ast::{Ident, Inherited, ImplItem, Item, Item_, ItemStatic}; use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl, ItemConst}; use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy, ItemDefaultImpl}; use ast::{ItemExternCrate, ItemUse}; -use ast::{Lit, Lit_}; -use ast::{LitBool, LitChar, LitByte, LitByteStr}; -use ast::{LitStr, LitInt, Local}; +use ast::{Lit, LitKind, UintTy}; +use ast::Local; use ast::{MacStmtWithBraces, MacStmtWithSemicolon, MacStmtWithoutBraces}; use ast::{MutImmutable, MutMutable, Mac_}; -use ast::{MutTy, BiMul, Mutability}; -use ast::{NamedField, UnNeg, NoReturn, UnNot}; +use ast::{MutTy, Mutability}; +use ast::NamedField; use ast::{Pat, PatBox, PatEnum, PatIdent, PatLit, PatQPath, PatMac, PatRange}; use ast::{PatRegion, PatStruct, PatTup, PatVec, PatWild}; use ast::{PolyTraitRef, QSelf}; -use ast::{Return, BiShl, BiShr, Stmt, StmtDecl}; -use ast::{StmtExpr, StmtSemi, StmtMac, VariantData, StructField}; -use ast::{BiSub, StrStyle}; -use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue}; +use ast::{Stmt, StmtKind}; +use ast::{VariantData, StructField}; +use ast::StrStyle; +use ast::SelfKind; use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef}; -use ast::{Ty, Ty_, TypeBinding, TyMac}; -use ast::{TyFixedLengthVec, TyBareFn, TyTypeof, TyInfer}; -use ast::{TyParam, TyParamBounds, TyParen, TyPath, TyPtr}; -use ast::{TyRptr, TyTup, TyU32, TyVec}; +use ast::{Ty, TyKind, TypeBinding, TyParam, TyParamBounds}; use ast::TypeTraitItem; -use ast::{UnnamedField, UnsafeBlock}; +use ast::UnnamedField; use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple}; use ast::{Visibility, WhereClause}; use attr::{ThinAttributes, ThinAttributesExt, AttributesExt}; +use ast::{BinOpKind, UnOp}; use ast; use ast_util::{self, ident_to_path}; use codemap::{self, Span, BytePos, Spanned, spanned, mk_sp, CodeMap}; @@ -139,7 +130,7 @@ macro_rules! maybe_whole_expr { _ => unreachable!() }; let span = $p.span; - Some($p.mk_expr(span.lo, span.hi, ExprPath(None, pt), None)) + Some($p.mk_expr(span.lo, span.hi, ExprKind::Path(None, pt), None)) } token::Interpolated(token::NtBlock(_)) => { // FIXME: The following avoids an issue with lexical borrowck scopes, @@ -149,7 +140,7 @@ macro_rules! maybe_whole_expr { _ => unreachable!() }; let span = $p.span; - Some($p.mk_expr(span.lo, span.hi, ExprBlock(b), None)) + Some($p.mk_expr(span.lo, span.hi, ExprKind::Block(b), None)) } _ => None }; @@ -233,7 +224,6 @@ macro_rules! maybe_whole { ) } - fn maybe_append(mut lhs: Vec, rhs: Option>) -> Vec { if let Some(ref attrs) = rhs { @@ -255,6 +245,7 @@ pub struct Parser<'a> { pub cfg: CrateConfig, /// the previous token or None (only stashed sometimes). pub last_token: Option>, + last_token_interpolated: bool, pub buffer: [TokenAndSpan; 4], pub buffer_start: isize, pub buffer_end: isize, @@ -362,6 +353,7 @@ pub fn new(sess: &'a ParseSess, span: span, last_span: span, last_token: None, + last_token_interpolated: false, buffer: [ placeholder.clone(), placeholder.clone(), @@ -506,7 +498,7 @@ pub fn check_for_erroneous_unit_struct_expecting(&mut self, pub fn commit_expr(&mut self, e: &Expr, edible: &[token::Token], inedible: &[token::Token]) -> PResult<'a, ()> { debug!("commit_expr {:?}", e); - if let ExprPath(..) = e.node { + if let ExprKind::Path(..) = e.node { // might be unit-struct construction; check for recoverableinput error. let expected = edible.iter() .cloned() @@ -542,6 +534,19 @@ pub fn commit_stmt_expecting(&mut self, edible: token::Token) -> PResult<'a, ()> self.commit_stmt(&[edible], &[]) } + /// returns the span of expr, if it was not interpolated or the span of the interpolated token + fn interpolated_or_expr_span(&self, + expr: PResult<'a, P>) + -> PResult<'a, (Span, P)> { + expr.map(|e| { + if self.last_token_interpolated { + (self.last_span, e) + } else { + (e.span, e) + } + }) + } + pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> { self.check_strict_keywords(); self.check_reserved_keywords(); @@ -668,7 +673,7 @@ fn expect_and(&mut self) -> PResult<'a, ()> { token::AndAnd => { let span = self.span; let lo = span.lo + BytePos(1); - Ok(self.replace_token(token::BinOp(token::And), lo, span.hi)) + Ok(self.bump_with(token::BinOp(token::And), lo, span.hi)) } _ => self.unexpected() } @@ -703,7 +708,7 @@ fn eat_lt(&mut self) -> bool { token::BinOp(token::Shl) => { let span = self.span; let lo = span.lo + BytePos(1); - self.replace_token(token::Lt, lo, span.hi); + self.bump_with(token::Lt, lo, span.hi); true } _ => false, @@ -731,17 +736,17 @@ pub fn expect_gt(&mut self) -> PResult<'a, ()> { token::BinOp(token::Shr) => { let span = self.span; let lo = span.lo + BytePos(1); - Ok(self.replace_token(token::Gt, lo, span.hi)) + Ok(self.bump_with(token::Gt, lo, span.hi)) } token::BinOpEq(token::Shr) => { let span = self.span; let lo = span.lo + BytePos(1); - Ok(self.replace_token(token::Ge, lo, span.hi)) + Ok(self.bump_with(token::Ge, lo, span.hi)) } token::Ge => { let span = self.span; let lo = span.lo + BytePos(1); - Ok(self.replace_token(token::Eq, lo, span.hi)) + Ok(self.bump_with(token::Eq, lo, span.hi)) } _ => { let gt_str = Parser::token_to_string(&token::Gt); @@ -933,6 +938,7 @@ pub fn bump(&mut self) { } else { None }; + self.last_token_interpolated = self.token.is_interpolated(); let next = if self.buffer_start == self.buffer_end { self.reader.real_token() } else { @@ -962,15 +968,23 @@ pub fn bump_and_get(&mut self) -> token::Token { old_token } - /// EFFECT: replace the current token and span with the given one - pub fn replace_token(&mut self, - next: token::Token, - lo: BytePos, - hi: BytePos) { + /// Advance the parser using provided token as a next one. Use this when + /// consuming a part of a token. For example a single `<` from `<<`. + pub fn bump_with(&mut self, + next: token::Token, + lo: BytePos, + hi: BytePos) { self.last_span = mk_sp(self.span.lo, lo); - self.token = next; + // It would be incorrect to just stash current token, but fortunately + // for tokens currently using `bump_with`, last_token will be of no + // use anyway. + self.last_token = None; + self.last_token_interpolated = false; self.span = mk_sp(lo, hi); + self.token = next; + self.expected_tokens.clear(); } + pub fn buffer_length(&mut self) -> isize { if self.buffer_start <= self.buffer_end { return self.buffer_end - self.buffer_start; @@ -1040,7 +1054,7 @@ pub fn get_lifetime(&mut self) -> ast::Ident { } } - pub fn parse_for_in_type(&mut self) -> PResult<'a, Ty_> { + pub fn parse_for_in_type(&mut self) -> PResult<'a, TyKind> { /* Parses whatever can come after a `for` keyword in a type. The `for` has already been consumed. @@ -1079,16 +1093,17 @@ pub fn parse_for_in_type(&mut self) -> PResult<'a, Ty_> { Some(TraitTyParamBound(poly_trait_ref, TraitBoundModifier::None)).into_iter() .chain(other_bounds.into_vec()) .collect(); - Ok(ast::TyPolyTraitRef(all_bounds)) + Ok(ast::TyKind::PolyTraitRef(all_bounds)) } } - pub fn parse_ty_path(&mut self) -> PResult<'a, Ty_> { - Ok(TyPath(None, try!(self.parse_path(LifetimeAndTypesWithoutColons)))) + pub fn parse_ty_path(&mut self) -> PResult<'a, TyKind> { + Ok(TyKind::Path(None, try!(self.parse_path(LifetimeAndTypesWithoutColons)))) } - /// parse a TyBareFn type: - pub fn parse_ty_bare_fn(&mut self, lifetime_defs: Vec) -> PResult<'a, Ty_> { + /// parse a TyKind::BareFn type: + pub fn parse_ty_bare_fn(&mut self, lifetime_defs: Vec) + -> PResult<'a, TyKind> { /* [unsafe] [extern "ABI"] fn <'lt> (S) -> T @@ -1103,9 +1118,9 @@ pub fn parse_ty_bare_fn(&mut self, lifetime_defs: Vec) -> PRes let unsafety = try!(self.parse_unsafety()); let abi = if self.eat_keyword(keywords::Extern) { - try!(self.parse_opt_abi()).unwrap_or(abi::C) + try!(self.parse_opt_abi()).unwrap_or(Abi::C) } else { - abi::Rust + Abi::Rust }; try!(self.expect_keyword(keywords::Fn)); @@ -1116,7 +1131,7 @@ pub fn parse_ty_bare_fn(&mut self, lifetime_defs: Vec) -> PRes output: ret_ty, variadic: variadic }); - Ok(TyBareFn(P(BareFnTy { + Ok(TyKind::BareFn(P(BareFnTy { abi: abi, unsafety: unsafety, lifetimes: lifetime_defs, @@ -1259,13 +1274,13 @@ pub fn parse_mt(&mut self) -> PResult<'a, MutTy> { pub fn parse_ret_ty(&mut self) -> PResult<'a, FunctionRetTy> { if self.eat(&token::RArrow) { if self.eat(&token::Not) { - Ok(NoReturn(self.last_span)) + Ok(FunctionRetTy::None(self.last_span)) } else { - Ok(Return(try!(self.parse_ty()))) + Ok(FunctionRetTy::Ty(try!(self.parse_ty()))) } } else { let pos = self.span.lo; - Ok(DefaultReturn(mk_sp(pos, pos))) + Ok(FunctionRetTy::Default(mk_sp(pos, pos))) } } @@ -1290,7 +1305,7 @@ pub fn parse_ty_sum(&mut self) -> PResult<'a, P> { } let sp = mk_sp(lo, self.last_span.hi); - let sum = ast::TyObjectSum(lhs, bounds); + let sum = ast::TyKind::ObjectSum(lhs, bounds); Ok(P(Ty {id: ast::DUMMY_NODE_ID, node: sum, span: sp})) } @@ -1321,14 +1336,14 @@ pub fn parse_ty(&mut self) -> PResult<'a, P> { try!(self.expect(&token::CloseDelim(token::Paren))); if ts.len() == 1 && !last_comma { - TyParen(ts.into_iter().nth(0).unwrap()) + TyKind::Paren(ts.into_iter().nth(0).unwrap()) } else { - TyTup(ts) + TyKind::Tup(ts) } } else if self.check(&token::BinOp(token::Star)) { // STAR POINTER (bare pointer?) self.bump(); - TyPtr(try!(self.parse_ptr())) + TyKind::Ptr(try!(self.parse_ptr())) } else if self.check(&token::OpenDelim(token::Bracket)) { // VECTOR try!(self.expect(&token::OpenDelim(token::Bracket))); @@ -1337,8 +1352,8 @@ pub fn parse_ty(&mut self) -> PResult<'a, P> { // Parse the `; e` in `[ i32; e ]` // where `e` is a const expression let t = match try!(self.maybe_parse_fixed_length_of_vec()) { - None => TyVec(t), - Some(suffix) => TyFixedLengthVec(t, suffix) + None => TyKind::Vec(t), + Some(suffix) => TyKind::FixedLengthVec(t, suffix) }; try!(self.expect(&token::CloseDelim(token::Bracket))); t @@ -1358,13 +1373,13 @@ pub fn parse_ty(&mut self) -> PResult<'a, P> { try!(self.expect(&token::OpenDelim(token::Paren))); let e = try!(self.parse_expr()); try!(self.expect(&token::CloseDelim(token::Paren))); - TyTypeof(e) + TyKind::Typeof(e) } else if self.eat_lt() { let (qself, path) = try!(self.parse_qualified_path(NoTypesAllowed)); - TyPath(Some(qself), path) + TyKind::Path(Some(qself), path) } else if self.check(&token::ModSep) || self.token.is_ident() || self.token.is_path() { @@ -1377,14 +1392,14 @@ pub fn parse_ty(&mut self) -> PResult<'a, P> { seq_sep_none(), |p| p.parse_token_tree())); let hi = self.span.hi; - TyMac(spanned(lo, hi, Mac_ { path: path, tts: tts, ctxt: EMPTY_CTXT })) + TyKind::Mac(spanned(lo, hi, Mac_ { path: path, tts: tts, ctxt: EMPTY_CTXT })) } else { // NAMED TYPE - TyPath(None, path) + TyKind::Path(None, path) } } else if self.eat(&token::Underscore) { // TYPE TO BE INFERRED - TyInfer + TyKind::Infer } else { let this_token_str = self.this_token_to_string(); let msg = format!("expected type, found `{}`", this_token_str); @@ -1395,12 +1410,12 @@ pub fn parse_ty(&mut self) -> PResult<'a, P> { Ok(P(Ty {id: ast::DUMMY_NODE_ID, node: t, span: sp})) } - pub fn parse_borrowed_pointee(&mut self) -> PResult<'a, Ty_> { + pub fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> { // look for `&'lt` or `&'foo ` and interpret `foo` as the region name: let opt_lifetime = try!(self.parse_opt_lifetime()); let mt = try!(self.parse_mt()); - return Ok(TyRptr(opt_lifetime, mt)); + return Ok(TyKind::Rptr(opt_lifetime, mt)); } pub fn parse_ptr(&mut self) -> PResult<'a, MutTy> { @@ -1480,7 +1495,7 @@ pub fn parse_fn_block_arg(&mut self) -> PResult<'a, Arg> { } else { P(Ty { id: ast::DUMMY_NODE_ID, - node: TyInfer, + node: TyKind::Infer, span: mk_sp(self.span.lo, self.span.hi), }) }; @@ -1501,18 +1516,18 @@ pub fn maybe_parse_fixed_length_of_vec(&mut self) -> PResult<'a, Option PResult<'a, Lit_> { + pub fn lit_from_token(&self, tok: &token::Token) -> PResult<'a, LitKind> { match *tok { token::Interpolated(token::NtExpr(ref v)) => { match v.node { - ExprLit(ref lit) => { Ok(lit.node.clone()) } + ExprKind::Lit(ref lit) => { Ok(lit.node.clone()) } _ => { return self.unexpected_last(tok); } } } token::Literal(lit, suf) => { let (suffix_illegal, out) = match lit { - token::Byte(i) => (true, LitByte(parse::byte_lit(&i.as_str()).0)), - token::Char(i) => (true, LitChar(parse::char_lit(&i.as_str()).0)), + token::Byte(i) => (true, LitKind::Byte(parse::byte_lit(&i.as_str()).0)), + token::Char(i) => (true, LitKind::Char(parse::char_lit(&i.as_str()).0)), // there are some valid suffixes for integer and // float literals, so all the handling is done @@ -1532,20 +1547,20 @@ pub fn lit_from_token(&self, tok: &token::Token) -> PResult<'a, Lit_> { token::Str_(s) => { (true, - LitStr(token::intern_and_get_ident(&parse::str_lit(&s.as_str())), - ast::CookedStr)) + LitKind::Str(token::intern_and_get_ident(&parse::str_lit(&s.as_str())), + ast::CookedStr)) } token::StrRaw(s, n) => { (true, - LitStr( + LitKind::Str( token::intern_and_get_ident(&parse::raw_str_lit(&s.as_str())), ast::RawStr(n))) } token::ByteStr(i) => - (true, LitByteStr(parse::byte_str_lit(&i.as_str()))), + (true, LitKind::ByteStr(parse::byte_str_lit(&i.as_str()))), token::ByteStrRaw(i, _) => (true, - LitByteStr(Rc::new(i.to_string().into_bytes()))), + LitKind::ByteStr(Rc::new(i.to_string().into_bytes()))), }; if suffix_illegal { @@ -1563,9 +1578,9 @@ pub fn lit_from_token(&self, tok: &token::Token) -> PResult<'a, Lit_> { pub fn parse_lit(&mut self) -> PResult<'a, Lit> { let lo = self.span.lo; let lit = if self.eat_keyword(keywords::True) { - LitBool(true) + LitKind::Bool(true) } else if self.eat_keyword(keywords::False) { - LitBool(false) + LitKind::Bool(false) } else { let token = self.bump_and_get(); let lit = try!(self.lit_from_token(&token)); @@ -1581,11 +1596,11 @@ pub fn parse_pat_literal_maybe_minus(&mut self) -> PResult<'a, P> { let lo = self.span.lo; let literal = P(try!(self.parse_lit())); let hi = self.last_span.hi; - let expr = self.mk_expr(lo, hi, ExprLit(literal), None); + let expr = self.mk_expr(lo, hi, ExprKind::Lit(literal), None); if minus_present { let minus_hi = self.last_span.hi; - let unary = self.mk_unary(UnNeg, expr); + let unary = self.mk_unary(UnOp::Neg, expr); Ok(self.mk_expr(minus_lo, minus_hi, unary, None)) } else { Ok(expr) @@ -1933,7 +1948,7 @@ pub fn parse_field(&mut self) -> PResult<'a, Field> { } pub fn mk_expr(&mut self, lo: BytePos, hi: BytePos, - node: Expr_, attrs: ThinAttributes) -> P { + node: ExprKind, attrs: ThinAttributes) -> P { P(Expr { id: ast::DUMMY_NODE_ID, node: node, @@ -1942,55 +1957,55 @@ pub fn mk_expr(&mut self, lo: BytePos, hi: BytePos, }) } - pub fn mk_unary(&mut self, unop: ast::UnOp, expr: P) -> ast::Expr_ { - ExprUnary(unop, expr) + pub fn mk_unary(&mut self, unop: ast::UnOp, expr: P) -> ast::ExprKind { + ExprKind::Unary(unop, expr) } - pub fn mk_binary(&mut self, binop: ast::BinOp, lhs: P, rhs: P) -> ast::Expr_ { - ExprBinary(binop, lhs, rhs) + pub fn mk_binary(&mut self, binop: ast::BinOp, lhs: P, rhs: P) -> ast::ExprKind { + ExprKind::Binary(binop, lhs, rhs) } - pub fn mk_call(&mut self, f: P, args: Vec>) -> ast::Expr_ { - ExprCall(f, args) + pub fn mk_call(&mut self, f: P, args: Vec>) -> ast::ExprKind { + ExprKind::Call(f, args) } fn mk_method_call(&mut self, ident: ast::SpannedIdent, tps: Vec>, args: Vec>) - -> ast::Expr_ { - ExprMethodCall(ident, tps, args) + -> ast::ExprKind { + ExprKind::MethodCall(ident, tps, args) } - pub fn mk_index(&mut self, expr: P, idx: P) -> ast::Expr_ { - ExprIndex(expr, idx) + pub fn mk_index(&mut self, expr: P, idx: P) -> ast::ExprKind { + ExprKind::Index(expr, idx) } pub fn mk_range(&mut self, start: Option>, end: Option>) - -> ast::Expr_ { - ExprRange(start, end) + -> ast::ExprKind { + ExprKind::Range(start, end) } - pub fn mk_field(&mut self, expr: P, ident: ast::SpannedIdent) -> ast::Expr_ { - ExprField(expr, ident) + pub fn mk_field(&mut self, expr: P, ident: ast::SpannedIdent) -> ast::ExprKind { + ExprKind::Field(expr, ident) } - pub fn mk_tup_field(&mut self, expr: P, idx: codemap::Spanned) -> ast::Expr_ { - ExprTupField(expr, idx) + pub fn mk_tup_field(&mut self, expr: P, idx: codemap::Spanned) -> ast::ExprKind { + ExprKind::TupField(expr, idx) } pub fn mk_assign_op(&mut self, binop: ast::BinOp, - lhs: P, rhs: P) -> ast::Expr_ { - ExprAssignOp(binop, lhs, rhs) + lhs: P, rhs: P) -> ast::ExprKind { + ExprKind::AssignOp(binop, lhs, rhs) } pub fn mk_mac_expr(&mut self, lo: BytePos, hi: BytePos, m: Mac_, attrs: ThinAttributes) -> P { P(Expr { id: ast::DUMMY_NODE_ID, - node: ExprMac(codemap::Spanned {node: m, span: mk_sp(lo, hi)}), + node: ExprKind::Mac(codemap::Spanned {node: m, span: mk_sp(lo, hi)}), span: mk_sp(lo, hi), attrs: attrs, }) @@ -1999,13 +2014,13 @@ pub fn mk_mac_expr(&mut self, lo: BytePos, hi: BytePos, pub fn mk_lit_u32(&mut self, i: u32, attrs: ThinAttributes) -> P { let span = &self.span; let lv_lit = P(codemap::Spanned { - node: LitInt(i as u64, ast::UnsignedIntLit(TyU32)), + node: LitKind::Int(i as u64, ast::LitIntType::Unsigned(UintTy::U32)), span: *span }); P(Expr { id: ast::DUMMY_NODE_ID, - node: ExprLit(lv_lit), + node: ExprKind::Lit(lv_lit), span: *span, attrs: attrs, }) @@ -2042,7 +2057,7 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P> { let lo = self.span.lo; let mut hi = self.span.hi; - let ex: Expr_; + let ex: ExprKind; // Note: when adding new syntax here, don't forget to adjust Token::can_begin_expr(). match self.token { @@ -2074,17 +2089,17 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P> { hi = self.last_span.hi; return if es.len() == 1 && !trailing_comma { - Ok(self.mk_expr(lo, hi, ExprParen(es.into_iter().nth(0).unwrap()), attrs)) + Ok(self.mk_expr(lo, hi, ExprKind::Paren(es.into_iter().nth(0).unwrap()), attrs)) } else { - Ok(self.mk_expr(lo, hi, ExprTup(es), attrs)) + Ok(self.mk_expr(lo, hi, ExprKind::Tup(es), attrs)) } }, token::OpenDelim(token::Brace) => { - return self.parse_block_expr(lo, DefaultBlock, attrs); + return self.parse_block_expr(lo, BlockCheckMode::Default, attrs); }, token::BinOp(token::Or) | token::OrOr => { let lo = self.span.lo; - return self.parse_lambda_expr(lo, CaptureByRef, attrs); + return self.parse_lambda_expr(lo, CaptureBy::Ref, attrs); }, token::Ident(id @ ast::Ident { name: token::SELF_KEYWORD_NAME, @@ -2092,7 +2107,7 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P> { }, token::Plain) => { self.bump(); let path = ast_util::ident_to_path(mk_sp(lo, hi), id); - ex = ExprPath(None, path); + ex = ExprKind::Path(None, path); hi = self.last_span.hi; } token::OpenDelim(token::Bracket) => { @@ -2105,7 +2120,7 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P> { if self.check(&token::CloseDelim(token::Bracket)) { // Empty vector. self.bump(); - ex = ExprVec(Vec::new()); + ex = ExprKind::Vec(Vec::new()); } else { // Nonempty vector. let first_expr = try!(self.parse_expr()); @@ -2114,7 +2129,7 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P> { self.bump(); let count = try!(self.parse_expr()); try!(self.expect(&token::CloseDelim(token::Bracket))); - ex = ExprRepeat(first_expr, count); + ex = ExprKind::Repeat(first_expr, count); } else if self.check(&token::Comma) { // Vector with two or more elements. self.bump(); @@ -2125,11 +2140,11 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P> { )); let mut exprs = vec!(first_expr); exprs.extend(remaining_exprs); - ex = ExprVec(exprs); + ex = ExprKind::Vec(exprs); } else { // Vector with one element. try!(self.expect(&token::CloseDelim(token::Bracket))); - ex = ExprVec(vec!(first_expr)); + ex = ExprKind::Vec(vec!(first_expr)); } } hi = self.last_span.hi; @@ -2139,11 +2154,11 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P> { let (qself, path) = try!(self.parse_qualified_path(LifetimeAndTypesWithColons)); hi = path.span.hi; - return Ok(self.mk_expr(lo, hi, ExprPath(Some(qself), path), attrs)); + return Ok(self.mk_expr(lo, hi, ExprKind::Path(Some(qself), path), attrs)); } if self.eat_keyword(keywords::Move) { let lo = self.last_span.lo; - return self.parse_lambda_expr(lo, CaptureByValue, attrs); + return self.parse_lambda_expr(lo, CaptureBy::Value, attrs); } if self.eat_keyword(keywords::If) { return self.parse_if_expr(attrs); @@ -2178,14 +2193,14 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P> { } if self.eat_keyword(keywords::Continue) { let ex = if self.token.is_lifetime() { - let ex = ExprAgain(Some(Spanned{ + let ex = ExprKind::Again(Some(Spanned{ node: self.get_lifetime(), span: self.span })); self.bump(); ex } else { - ExprAgain(None) + ExprKind::Again(None) }; let hi = self.last_span.hi; return Ok(self.mk_expr(lo, hi, ex, attrs)); @@ -2196,28 +2211,34 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P> { if self.eat_keyword(keywords::Unsafe) { return self.parse_block_expr( lo, - UnsafeBlock(ast::UserProvided), + BlockCheckMode::Unsafe(ast::UserProvided), attrs); } if self.eat_keyword(keywords::Return) { if self.token.can_begin_expr() { let e = try!(self.parse_expr()); hi = e.span.hi; - ex = ExprRet(Some(e)); + ex = ExprKind::Ret(Some(e)); } else { - ex = ExprRet(None); + ex = ExprKind::Ret(None); } } else if self.eat_keyword(keywords::Break) { if self.token.is_lifetime() { - ex = ExprBreak(Some(Spanned { + ex = ExprKind::Break(Some(Spanned { node: self.get_lifetime(), span: self.span })); self.bump(); } else { - ex = ExprBreak(None); + ex = ExprKind::Break(None); } hi = self.last_span.hi; + } else if self.token.is_keyword(keywords::Let) { + // Catch this syntax error here, instead of in `check_strict_keywords`, so + // that we can explicitly mention that let is not to be used as an expression + let mut db = self.fatal("expected expression, found statement (`let`)"); + db.note("variable declaration using `let` is a statement"); + return Err(db); } else if self.check(&token::ModSep) || self.token.is_ident() && !self.check_keyword(keywords::True) && @@ -2272,18 +2293,18 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P> { hi = self.span.hi; try!(self.expect(&token::CloseDelim(token::Brace))); - ex = ExprStruct(pth, fields, base); + ex = ExprKind::Struct(pth, fields, base); return Ok(self.mk_expr(lo, hi, ex, attrs)); } } hi = pth.span.hi; - ex = ExprPath(None, pth); + ex = ExprKind::Path(None, pth); } else { // other literal expression let lit = try!(self.parse_lit()); hi = lit.span.hi; - ex = ExprLit(P(lit)); + ex = ExprKind::Lit(P(lit)); } } } @@ -2313,7 +2334,7 @@ pub fn parse_block_expr(&mut self, lo: BytePos, blk_mode: BlockCheckMode, let attrs = outer_attrs.append(inner_attrs); let blk = try!(self.parse_block_tail(lo, blk_mode)); - return Ok(self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk), attrs)); + return Ok(self.mk_expr(blk.span.lo, blk.span.hi, ExprKind::Block(blk), attrs)); } /// parse a.b or a(13) or a[4] or just a @@ -2322,23 +2343,25 @@ pub fn parse_dot_or_call_expr(&mut self, -> PResult<'a, P> { let attrs = try!(self.parse_or_use_outer_attributes(already_parsed_attrs)); - let b = try!(self.parse_bottom_expr()); - self.parse_dot_or_call_expr_with(b, attrs) + let b = self.parse_bottom_expr(); + let (span, b) = try!(self.interpolated_or_expr_span(b)); + self.parse_dot_or_call_expr_with(b, span.lo, attrs) } pub fn parse_dot_or_call_expr_with(&mut self, e0: P, + lo: BytePos, attrs: ThinAttributes) -> PResult<'a, P> { // Stitch the list of outer attributes onto the return value. // A little bit ugly, but the best way given the current code // structure - self.parse_dot_or_call_expr_with_(e0) + self.parse_dot_or_call_expr_with_(e0, lo) .map(|expr| expr.map(|mut expr| { expr.attrs.update(|a| a.prepend(attrs)); match expr.node { - ExprIf(..) | ExprIfLet(..) => { + ExprKind::If(..) | ExprKind::IfLet(..) => { if !expr.attrs.as_attr_slice().is_empty() { // Just point to the first attribute in there... let span = expr.attrs.as_attr_slice()[0].span; @@ -2360,7 +2383,8 @@ pub fn parse_dot_or_call_expr_with(&mut self, fn parse_dot_suffix(&mut self, ident: Ident, ident_span: Span, - self_value: P) + self_value: P, + lo: BytePos) -> PResult<'a, P> { let (_, tys, bindings) = if self.eat(&token::ModSep) { try!(self.expect_lt()); @@ -2374,8 +2398,6 @@ fn parse_dot_suffix(&mut self, self.span_err(last_span, "type bindings are only permitted on trait paths"); } - let lo = self_value.span.lo; - Ok(match self.token { // expr.f() method call. token::OpenDelim(token::Paren) => { @@ -2408,9 +2430,8 @@ fn parse_dot_suffix(&mut self, }) } - fn parse_dot_or_call_expr_with_(&mut self, e0: P) -> PResult<'a, P> { + fn parse_dot_or_call_expr_with_(&mut self, e0: P, lo: BytePos) -> PResult<'a, P> { let mut e = e0; - let lo = e.span.lo; let mut hi; loop { // expr.f @@ -2421,7 +2442,7 @@ fn parse_dot_or_call_expr_with_(&mut self, e0: P) -> PResult<'a, P> hi = self.span.hi; self.bump(); - e = try!(self.parse_dot_suffix(i, mk_sp(dot_pos, hi), e)); + e = try!(self.parse_dot_suffix(i, mk_sp(dot_pos, hi), e, lo)); } token::Literal(token::Integer(n), suf) => { let sp = self.span; @@ -2462,8 +2483,7 @@ fn parse_dot_or_call_expr_with_(&mut self, e0: P) -> PResult<'a, P> float.trunc() as usize, format!(".{}", fstr.splitn(2, ".").last().unwrap()))); } - err.emit(); - self.abort_if_errors(); + return Err(err); } _ => { @@ -2474,7 +2494,7 @@ fn parse_dot_or_call_expr_with_(&mut self, e0: P) -> PResult<'a, P> let dot_pos = self.last_span.hi; e = try!(self.parse_dot_suffix(special_idents::invalid, mk_sp(dot_pos, dot_pos), - e)); + e, lo)); } } continue; @@ -2709,28 +2729,32 @@ pub fn parse_prefix_expr(&mut self, let ex = match self.token { token::Not => { self.bump(); - let e = try!(self.parse_prefix_expr(None)); - hi = e.span.hi; - self.mk_unary(UnNot, e) + let e = self.parse_prefix_expr(None); + let (span, e) = try!(self.interpolated_or_expr_span(e)); + hi = span.hi; + self.mk_unary(UnOp::Not, e) } token::BinOp(token::Minus) => { self.bump(); - let e = try!(self.parse_prefix_expr(None)); - hi = e.span.hi; - self.mk_unary(UnNeg, e) + let e = self.parse_prefix_expr(None); + let (span, e) = try!(self.interpolated_or_expr_span(e)); + hi = span.hi; + self.mk_unary(UnOp::Neg, e) } token::BinOp(token::Star) => { self.bump(); - let e = try!(self.parse_prefix_expr(None)); - hi = e.span.hi; - self.mk_unary(UnDeref, e) + let e = self.parse_prefix_expr(None); + let (span, e) = try!(self.interpolated_or_expr_span(e)); + hi = span.hi; + self.mk_unary(UnOp::Deref, e) } token::BinOp(token::And) | token::AndAnd => { try!(self.expect_and()); let m = try!(self.parse_mutability()); - let e = try!(self.parse_prefix_expr(None)); - hi = e.span.hi; - ExprAddrOf(m, e) + let e = self.parse_prefix_expr(None); + let (span, e) = try!(self.interpolated_or_expr_span(e)); + hi = span.hi; + ExprKind::AddrOf(m, e) } token::Ident(..) if self.token.is_keyword(keywords::In) => { self.bump(); @@ -2741,15 +2765,16 @@ pub fn parse_prefix_expr(&mut self, let blk = try!(self.parse_block()); let span = blk.span; hi = span.hi; - let blk_expr = self.mk_expr(span.lo, span.hi, ExprBlock(blk), + let blk_expr = self.mk_expr(span.lo, span.hi, ExprKind::Block(blk), None); - ExprInPlace(place, blk_expr) + ExprKind::InPlace(place, blk_expr) } token::Ident(..) if self.token.is_keyword(keywords::Box) => { self.bump(); - let subexpression = try!(self.parse_prefix_expr(None)); - hi = subexpression.span.hi; - ExprBox(subexpression) + let e = self.parse_prefix_expr(None); + let (span, e) = try!(self.interpolated_or_expr_span(e)); + hi = span.hi; + ExprKind::Box(e) } _ => return self.parse_dot_or_call_expr(Some(attrs)) }; @@ -2784,12 +2809,21 @@ pub fn parse_assoc_expr_with(&mut self, try!(self.parse_prefix_expr(attrs)) } }; + + if self.expr_is_complete(&*lhs) { // Semi-statement forms are odd. See https://github.com/rust-lang/rust/issues/29071 return Ok(lhs); } self.expected_tokens.push(TokenType::Operator); while let Some(op) = AssocOp::from_token(&self.token) { + + let lhs_span = if self.last_token_interpolated { + self.last_span + } else { + lhs.span + }; + let cur_op_span = self.span; let restrictions = if op.is_assign_like() { self.restrictions & Restrictions::RESTRICTION_NO_STRUCT_LITERAL @@ -2806,13 +2840,13 @@ pub fn parse_assoc_expr_with(&mut self, // Special cases: if op == AssocOp::As { let rhs = try!(self.parse_ty()); - lhs = self.mk_expr(lhs.span.lo, rhs.span.hi, - ExprCast(lhs, rhs), None); + lhs = self.mk_expr(lhs_span.lo, rhs.span.hi, + ExprKind::Cast(lhs, rhs), None); continue } else if op == AssocOp::Colon { let rhs = try!(self.parse_ty()); - lhs = self.mk_expr(lhs.span.lo, rhs.span.hi, - ExprType(lhs, rhs), None); + lhs = self.mk_expr(lhs_span.lo, rhs.span.hi, + ExprKind::Type(lhs, rhs), None); continue } else if op == AssocOp::DotDot { // If we didn’t have to handle `x..`, it would be pretty easy to generalise @@ -2833,7 +2867,7 @@ pub fn parse_assoc_expr_with(&mut self, } else { None }; - let (lhs_span, rhs_span) = (lhs.span, if let Some(ref x) = rhs { + let (lhs_span, rhs_span) = (lhs_span, if let Some(ref x) = rhs { x.span } else { cur_op_span @@ -2873,28 +2907,28 @@ pub fn parse_assoc_expr_with(&mut self, AssocOp::Equal | AssocOp::Less | AssocOp::LessEqual | AssocOp::NotEqual | AssocOp::Greater | AssocOp::GreaterEqual => { let ast_op = op.to_ast_binop().unwrap(); - let (lhs_span, rhs_span) = (lhs.span, rhs.span); + let (lhs_span, rhs_span) = (lhs_span, rhs.span); let binary = self.mk_binary(codemap::respan(cur_op_span, ast_op), lhs, rhs); self.mk_expr(lhs_span.lo, rhs_span.hi, binary, None) } AssocOp::Assign => - self.mk_expr(lhs.span.lo, rhs.span.hi, ExprAssign(lhs, rhs), None), + self.mk_expr(lhs_span.lo, rhs.span.hi, ExprKind::Assign(lhs, rhs), None), AssocOp::Inplace => - self.mk_expr(lhs.span.lo, rhs.span.hi, ExprInPlace(lhs, rhs), None), + self.mk_expr(lhs_span.lo, rhs.span.hi, ExprKind::InPlace(lhs, rhs), None), AssocOp::AssignOp(k) => { let aop = match k { - token::Plus => BiAdd, - token::Minus => BiSub, - token::Star => BiMul, - token::Slash => BiDiv, - token::Percent => BiRem, - token::Caret => BiBitXor, - token::And => BiBitAnd, - token::Or => BiBitOr, - token::Shl => BiShl, - token::Shr => BiShr + token::Plus => BinOpKind::Add, + token::Minus => BinOpKind::Sub, + token::Star => BinOpKind::Mul, + token::Slash => BinOpKind::Div, + token::Percent => BinOpKind::Rem, + token::Caret => BinOpKind::BitXor, + token::And => BinOpKind::BitAnd, + token::Or => BinOpKind::BitOr, + token::Shl => BinOpKind::Shl, + token::Shr => BinOpKind::Shr, }; - let (lhs_span, rhs_span) = (lhs.span, rhs.span); + let (lhs_span, rhs_span) = (lhs_span, rhs.span); let aopexpr = self.mk_assign_op(codemap::respan(cur_op_span, aop), lhs, rhs); self.mk_expr(lhs_span.lo, rhs_span.hi, aopexpr, None) } @@ -2914,12 +2948,12 @@ pub fn parse_assoc_expr_with(&mut self, fn check_no_chained_comparison(&mut self, lhs: &Expr, outer_op: &AssocOp) { debug_assert!(outer_op.is_comparison()); match lhs.node { - ExprBinary(op, _, _) if op.node.is_comparison() => { + ExprKind::Binary(op, _, _) if op.node.is_comparison() => { // respan to include both operators let op_span = mk_sp(op.span.lo, self.span.hi); let mut err = self.diagnostic().struct_span_err(op_span, "chained comparison operators require parentheses"); - if op.node == BiLt && *outer_op == AssocOp::Greater { + if op.node == BinOpKind::Lt && *outer_op == AssocOp::Greater { err.fileline_help(op_span, "use `::<...>` instead of `<...>` if you meant to specify type arguments"); } @@ -2981,7 +3015,7 @@ pub fn parse_if_expr(&mut self, attrs: ThinAttributes) -> PResult<'a, P> { hi = elexpr.span.hi; els = Some(elexpr); } - Ok(self.mk_expr(lo, hi, ExprIf(cond, thn, els), attrs)) + Ok(self.mk_expr(lo, hi, ExprKind::If(cond, thn, els), attrs)) } /// Parse an 'if let' expression ('if' token already eaten) @@ -2999,18 +3033,18 @@ pub fn parse_if_let_expr(&mut self, attrs: ThinAttributes) } else { (thn.span.hi, None) }; - Ok(self.mk_expr(lo, hi, ExprIfLet(pat, expr, thn, els), attrs)) + Ok(self.mk_expr(lo, hi, ExprKind::IfLet(pat, expr, thn, els), attrs)) } // `|args| expr` pub fn parse_lambda_expr(&mut self, lo: BytePos, - capture_clause: CaptureClause, + capture_clause: CaptureBy, attrs: ThinAttributes) -> PResult<'a, P> { let decl = try!(self.parse_fn_block_decl()); let body = match decl.output { - DefaultReturn(_) => { + FunctionRetTy::Default(_) => { // If no explicit return type is given, parse any // expr and wrap it up in a dummy block: let body_expr = try!(self.parse_expr()); @@ -3019,7 +3053,7 @@ pub fn parse_lambda_expr(&mut self, lo: BytePos, stmts: vec![], span: body_expr.span, expr: Some(body_expr), - rules: DefaultBlock, + rules: BlockCheckMode::Default, }) } _ => { @@ -3032,7 +3066,7 @@ pub fn parse_lambda_expr(&mut self, lo: BytePos, Ok(self.mk_expr( lo, body.span.hi, - ExprClosure(capture_clause, decl, body), attrs)) + ExprKind::Closure(capture_clause, decl, body), attrs)) } // `else` token already eaten @@ -3041,7 +3075,7 @@ pub fn parse_else_expr(&mut self) -> PResult<'a, P> { return self.parse_if_expr(None); } else { let blk = try!(self.parse_block()); - return Ok(self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk), None)); + return Ok(self.mk_expr(blk.span.lo, blk.span.hi, ExprKind::Block(blk), None)); } } @@ -3060,7 +3094,7 @@ pub fn parse_for_expr(&mut self, opt_ident: Option, let hi = self.last_span.hi; Ok(self.mk_expr(span_lo, hi, - ExprForLoop(pat, expr, loop_block, opt_ident), + ExprKind::ForLoop(pat, expr, loop_block, opt_ident), attrs)) } @@ -3075,7 +3109,7 @@ pub fn parse_while_expr(&mut self, opt_ident: Option, let (iattrs, body) = try!(self.parse_inner_attrs_and_block()); let attrs = attrs.append(iattrs.into_thin_attrs()); let hi = body.span.hi; - return Ok(self.mk_expr(span_lo, hi, ExprWhile(cond, body, opt_ident), + return Ok(self.mk_expr(span_lo, hi, ExprKind::While(cond, body, opt_ident), attrs)); } @@ -3090,7 +3124,7 @@ pub fn parse_while_let_expr(&mut self, opt_ident: Option, let (iattrs, body) = try!(self.parse_inner_attrs_and_block()); let attrs = attrs.append(iattrs.into_thin_attrs()); let hi = body.span.hi; - return Ok(self.mk_expr(span_lo, hi, ExprWhileLet(pat, expr, body, opt_ident), attrs)); + return Ok(self.mk_expr(span_lo, hi, ExprKind::WhileLet(pat, expr, body, opt_ident), attrs)); } // parse `loop {...}`, `loop` token already eaten @@ -3100,7 +3134,7 @@ pub fn parse_loop_expr(&mut self, opt_ident: Option, let (iattrs, body) = try!(self.parse_inner_attrs_and_block()); let attrs = attrs.append(iattrs.into_thin_attrs()); let hi = body.span.hi; - Ok(self.mk_expr(span_lo, hi, ExprLoop(body, opt_ident), attrs)) + Ok(self.mk_expr(span_lo, hi, ExprKind::Loop(body, opt_ident), attrs)) } // `match` token already eaten @@ -3124,7 +3158,7 @@ fn parse_match_expr(&mut self, attrs: ThinAttributes) -> PResult<'a, P> { } let hi = self.span.hi; self.bump(); - return Ok(self.mk_expr(lo, hi, ExprMatch(discriminant, arms), attrs)); + return Ok(self.mk_expr(lo, hi, ExprKind::Match(discriminant, arms), attrs)); } pub fn parse_arm(&mut self) -> PResult<'a, Arm> { @@ -3364,7 +3398,7 @@ fn parse_pat_range_end(&mut self) -> PResult<'a, P> { (None, try!(self.parse_path(LifetimeAndTypesWithColons))) }; let hi = self.last_span.hi; - Ok(self.mk_expr(lo, hi, ExprPath(qself, path), None)) + Ok(self.mk_expr(lo, hi, ExprKind::Path(qself, path), None)) } else { self.parse_pat_literal_maybe_minus() } @@ -3466,7 +3500,7 @@ pub fn parse_pat(&mut self) -> PResult<'a, P> { token::DotDotDot => { // Parse range let hi = self.last_span.hi; - let begin = self.mk_expr(lo, hi, ExprPath(qself, path), None); + let begin = self.mk_expr(lo, hi, ExprKind::Path(qself, path), None); self.bump(); let end = try!(self.parse_pat_range_end()); pat = PatRange(begin, end); @@ -3593,7 +3627,7 @@ fn parse_local(&mut self, attrs: ThinAttributes) -> PResult<'a, P> { fn parse_let(&mut self, attrs: ThinAttributes) -> PResult<'a, P> { let lo = self.span.lo; let local = try!(self.parse_local(attrs)); - Ok(P(spanned(lo, self.last_span.hi, DeclLocal(local)))) + Ok(P(spanned(lo, self.last_span.hi, DeclKind::Local(local)))) } /// Parse a structure field @@ -3644,7 +3678,7 @@ fn parse_stmt_(&mut self) -> PResult<'a, Option> { try!(self.expect_keyword(keywords::Let)); let decl = try!(self.parse_let(attrs.into_thin_attrs())); let hi = decl.span.hi; - let stmt = StmtDecl(decl, ast::DUMMY_NODE_ID); + let stmt = StmtKind::Decl(decl, ast::DUMMY_NODE_ID); spanned(lo, hi, stmt) } else if self.token.is_ident() && !self.token.is_any_keyword() @@ -3696,11 +3730,8 @@ fn parse_stmt_(&mut self) -> PResult<'a, Option> { }; if id.name == token::special_idents::invalid.name { - let stmt = StmtMac(P(spanned(lo, - hi, - Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT })), - style, - attrs.into_thin_attrs()); + let mac = P(spanned(lo, hi, Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT })); + let stmt = StmtKind::Mac(mac, style, attrs.into_thin_attrs()); spanned(lo, hi, stmt) } else { // if it has a special ident, it's definitely an item @@ -3715,8 +3746,8 @@ fn parse_stmt_(&mut self) -> PResult<'a, Option> { followed by a semicolon"); } } - spanned(lo, hi, StmtDecl( - P(spanned(lo, hi, DeclItem( + spanned(lo, hi, StmtKind::Decl( + P(spanned(lo, hi, DeclKind::Item( self.mk_item( lo, hi, id /*id is good here*/, ItemMac(spanned(lo, hi, @@ -3729,8 +3760,8 @@ fn parse_stmt_(&mut self) -> PResult<'a, Option> { match try!(self.parse_item_(attrs.clone(), false, true)) { Some(i) => { let hi = i.span.hi; - let decl = P(spanned(lo, hi, DeclItem(i))); - spanned(lo, hi, StmtDecl(decl, ast::DUMMY_NODE_ID)) + let decl = P(spanned(lo, hi, DeclKind::Item(i))); + spanned(lo, hi, StmtKind::Decl(decl, ast::DUMMY_NODE_ID)) } None => { let unused_attrs = |attrs: &[_], s: &mut Self| { @@ -3756,7 +3787,7 @@ fn parse_stmt_(&mut self) -> PResult<'a, Option> { let e = try!(self.parse_expr_res( Restrictions::RESTRICTION_STMT_EXPR, Some(attrs.into_thin_attrs()))); let hi = e.span.hi; - let stmt = StmtExpr(e, ast::DUMMY_NODE_ID); + let stmt = StmtKind::Expr(e, ast::DUMMY_NODE_ID); spanned(lo, hi, stmt) } } @@ -3783,7 +3814,7 @@ pub fn parse_block(&mut self) -> PResult<'a, P> { "place this code inside a block")); } - self.parse_block_tail(lo, DefaultBlock) + self.parse_block_tail(lo, BlockCheckMode::Default) } /// Parse a block. Inner attrs are allowed. @@ -3793,7 +3824,7 @@ fn parse_inner_attrs_and_block(&mut self) -> PResult<'a, (Vec, P PResult<'a, P< continue; }; match node { - StmtExpr(e, _) => { + StmtKind::Expr(e, _) => { try!(self.handle_expression_like_statement(e, span, &mut stmts, &mut expr)); } - StmtMac(mac, MacStmtWithoutBraces, attrs) => { + StmtKind::Mac(mac, MacStmtWithoutBraces, attrs) => { // statement macro without braces; might be an // expr depending on whether a semicolon follows match self.token { token::Semi => { stmts.push(P(Spanned { - node: StmtMac(mac, MacStmtWithSemicolon, attrs), + node: StmtKind::Mac(mac, MacStmtWithSemicolon, attrs), span: mk_sp(span.lo, self.span.hi), })); self.bump(); @@ -3828,7 +3859,8 @@ fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> PResult<'a, P< let e = self.mk_mac_expr(span.lo, span.hi, mac.and_then(|m| m.node), None); - let e = try!(self.parse_dot_or_call_expr_with(e, attrs)); + let lo = e.span.lo; + let e = try!(self.parse_dot_or_call_expr_with(e, lo, attrs)); let e = try!(self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))); try!(self.handle_expression_like_statement( e, @@ -3838,12 +3870,12 @@ fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> PResult<'a, P< } } } - StmtMac(m, style, attrs) => { + StmtKind::Mac(m, style, attrs) => { // statement macro; might be an expr match self.token { token::Semi => { stmts.push(P(Spanned { - node: StmtMac(m, MacStmtWithSemicolon, attrs), + node: StmtKind::Mac(m, MacStmtWithSemicolon, attrs), span: mk_sp(span.lo, self.span.hi), })); self.bump(); @@ -3857,7 +3889,7 @@ fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> PResult<'a, P< } _ => { stmts.push(P(Spanned { - node: StmtMac(m, style, attrs), + node: StmtKind::Mac(m, style, attrs), span: span })); } @@ -3909,14 +3941,14 @@ fn handle_expression_like_statement( expn_id: span.expn_id, }; stmts.push(P(Spanned { - node: StmtSemi(e, ast::DUMMY_NODE_ID), + node: StmtKind::Semi(e, ast::DUMMY_NODE_ID), span: span_with_semi, })); } token::CloseDelim(token::Brace) => *last_block_expr = Some(e), _ => { stmts.push(P(Spanned { - node: StmtExpr(e, ast::DUMMY_NODE_ID), + node: StmtKind::Expr(e, ast::DUMMY_NODE_ID), span: span })); } @@ -4081,9 +4113,7 @@ fn parse_generic_values_after_lt(&mut self) -> PResult<'a, (Vec, or did you mean the comma-separated arguments \ 'a, Type?"); err.span_note(mk_sp(span_lo, span_hi), &msg); - err.emit(); - - self.abort_if_errors() + return Err(err); } // First parse types. @@ -4369,7 +4399,7 @@ fn parse_fn_decl_with_self(&mut self, F: FnMut(&mut Parser<'a>) -> PResult<'a, Arg>, { fn maybe_parse_borrowed_explicit_self<'b>(this: &mut Parser<'b>) - -> PResult<'b, ast::ExplicitSelf_> { + -> PResult<'b, ast::SelfKind> { // The following things are possible to see here: // // fn(&mut self) @@ -4381,26 +4411,26 @@ fn maybe_parse_borrowed_explicit_self<'b>(this: &mut Parser<'b>) if this.look_ahead(1, |t| t.is_keyword(keywords::SelfValue)) { this.bump(); - Ok(SelfRegion(None, MutImmutable, try!(this.expect_self_ident()))) + Ok(SelfKind::Region(None, MutImmutable, try!(this.expect_self_ident()))) } else if this.look_ahead(1, |t| t.is_mutability()) && this.look_ahead(2, |t| t.is_keyword(keywords::SelfValue)) { this.bump(); let mutability = try!(this.parse_mutability()); - Ok(SelfRegion(None, mutability, try!(this.expect_self_ident()))) + Ok(SelfKind::Region(None, mutability, try!(this.expect_self_ident()))) } else if this.look_ahead(1, |t| t.is_lifetime()) && this.look_ahead(2, |t| t.is_keyword(keywords::SelfValue)) { this.bump(); let lifetime = try!(this.parse_lifetime()); - Ok(SelfRegion(Some(lifetime), MutImmutable, try!(this.expect_self_ident()))) + Ok(SelfKind::Region(Some(lifetime), MutImmutable, try!(this.expect_self_ident()))) } else if this.look_ahead(1, |t| t.is_lifetime()) && this.look_ahead(2, |t| t.is_mutability()) && this.look_ahead(3, |t| t.is_keyword(keywords::SelfValue)) { this.bump(); let lifetime = try!(this.parse_lifetime()); let mutability = try!(this.parse_mutability()); - Ok(SelfRegion(Some(lifetime), mutability, try!(this.expect_self_ident()))) + Ok(SelfKind::Region(Some(lifetime), mutability, try!(this.expect_self_ident()))) } else { - Ok(SelfStatic) + Ok(SelfKind::Static) } } @@ -4435,7 +4465,7 @@ fn maybe_parse_borrowed_explicit_self<'b>(this: &mut Parser<'b>) self.bump(); } // error case, making bogus self ident: - SelfValue(special_idents::self_) + SelfKind::Value(special_idents::self_) } token::Ident(..) => { if self.is_self_ident() { @@ -4444,9 +4474,9 @@ fn maybe_parse_borrowed_explicit_self<'b>(this: &mut Parser<'b>) // Determine whether this is the fully explicit form, `self: // TYPE`. if self.eat(&token::Colon) { - SelfExplicit(try!(self.parse_ty_sum()), self_ident) + SelfKind::Explicit(try!(self.parse_ty_sum()), self_ident) } else { - SelfValue(self_ident) + SelfKind::Value(self_ident) } } else if self.token.is_mutability() && self.look_ahead(1, |t| t.is_keyword(keywords::SelfValue)) { @@ -4456,15 +4486,15 @@ fn maybe_parse_borrowed_explicit_self<'b>(this: &mut Parser<'b>) // Determine whether this is the fully explicit form, // `self: TYPE`. if self.eat(&token::Colon) { - SelfExplicit(try!(self.parse_ty_sum()), self_ident) + SelfKind::Explicit(try!(self.parse_ty_sum()), self_ident) } else { - SelfValue(self_ident) + SelfKind::Value(self_ident) } } else { - SelfStatic + SelfKind::Static } } - _ => SelfStatic, + _ => SelfKind::Static, }; let explicit_self_sp = mk_sp(self_ident_lo, self_ident_hi); @@ -4500,14 +4530,14 @@ macro_rules! parse_remaining_arguments { } let fn_inputs = match explicit_self { - SelfStatic => { + SelfKind::Static => { let sep = seq_sep_trailing_allowed(token::Comma); try!(self.parse_seq_to_before_end(&token::CloseDelim(token::Paren), sep, parse_arg_fn)) } - SelfValue(id) => parse_remaining_arguments!(id), - SelfRegion(_,_,id) => parse_remaining_arguments!(id), - SelfExplicit(_,id) => parse_remaining_arguments!(id), + SelfKind::Value(id) => parse_remaining_arguments!(id), + SelfKind::Region(_,_,id) => parse_remaining_arguments!(id), + SelfKind::Explicit(_,id) => parse_remaining_arguments!(id), }; @@ -4605,12 +4635,12 @@ pub fn parse_fn_front_matter(&mut self) let is_const_fn = self.eat_keyword(keywords::Const); let unsafety = try!(self.parse_unsafety()); let (constness, unsafety, abi) = if is_const_fn { - (Constness::Const, unsafety, abi::Rust) + (Constness::Const, unsafety, Abi::Rust) } else { let abi = if self.eat_keyword(keywords::Extern) { - try!(self.parse_opt_abi()).unwrap_or(abi::C) + try!(self.parse_opt_abi()).unwrap_or(Abi::C) } else { - abi::Rust + Abi::Rust }; (Constness::NotConst, unsafety, abi) }; @@ -4773,7 +4803,7 @@ fn parse_item_impl(&mut self, unsafety: ast::Unsafety) -> PResult<'a, ItemInfo> let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) { // New-style trait. Reinterpret the type as a trait. match ty.node { - TyPath(None, ref path) => { + TyKind::Path(None, ref path) => { Some(TraitRef { path: (*path).clone(), ref_id: ty.id, @@ -5153,8 +5183,7 @@ fn submod_path(&mut self, of possibly redeclaring it", paths.name)); } - err.emit(); - self.abort_if_errors(); + return Err(err); } match paths.result { @@ -5309,7 +5338,7 @@ fn parse_item_foreign_mod(&mut self, -> PResult<'a, P> { try!(self.expect(&token::OpenDelim(token::Brace))); - let abi = opt_abi.unwrap_or(abi::C); + let abi = opt_abi.unwrap_or(Abi::C); attrs.extend(try!(self.parse_inner_attributes())); @@ -5481,7 +5510,7 @@ fn parse_item_(&mut self, attrs: Vec, if self.eat_keyword(keywords::Fn) { // EXTERN FUNCTION ITEM - let abi = opt_abi.unwrap_or(abi::C); + let abi = opt_abi.unwrap_or(Abi::C); let (ident, item_, extra_attrs) = try!(self.parse_item_fn(Unsafety::Normal, Constness::NotConst, abi)); let last_span = self.last_span; @@ -5524,7 +5553,7 @@ fn parse_item_(&mut self, attrs: Vec, }; self.bump(); let (ident, item_, extra_attrs) = - try!(self.parse_item_fn(unsafety, Constness::Const, abi::Rust)); + try!(self.parse_item_fn(unsafety, Constness::Const, Abi::Rust)); let last_span = self.last_span; let item = self.mk_item(lo, last_span.hi, @@ -5589,7 +5618,7 @@ fn parse_item_(&mut self, attrs: Vec, // FUNCTION ITEM self.bump(); let (ident, item_, extra_attrs) = - try!(self.parse_item_fn(Unsafety::Normal, Constness::NotConst, abi::Rust)); + try!(self.parse_item_fn(Unsafety::Normal, Constness::NotConst, Abi::Rust)); let last_span = self.last_span; let item = self.mk_item(lo, last_span.hi, @@ -5604,9 +5633,9 @@ fn parse_item_(&mut self, attrs: Vec, // UNSAFE FUNCTION ITEM self.bump(); let abi = if self.eat_keyword(keywords::Extern) { - try!(self.parse_opt_abi()).unwrap_or(abi::C) + try!(self.parse_opt_abi()).unwrap_or(Abi::C) } else { - abi::Rust + Abi::Rust }; try!(self.expect_keyword(keywords::Fn)); let (ident, item_, extra_attrs) =