diff options
Diffstat (limited to 'src/libsyntax/parse/parser.rs')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 487 |
1 files changed, 251 insertions, 236 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 328bdf88335..f41362cad41 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -39,9 +39,8 @@ use ast::{LitBool, LitChar, LitByte, LitBinary}; use ast::{LitNil, LitStr, LitInt, Local, LocalLet}; use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, Matcher, MatchNonterminal}; use ast::{MatchSeq, MatchTok, Method, MutTy, BiMul, Mutability}; -use ast::{MethodImplItem}; -use ast::{NamedField, UnNeg, NoReturn, UnNot, P, Pat, PatEnum}; -use ast::{PatIdent, PatLit, PatRange, PatRegion, PatStruct}; +use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, UnNot}; +use ast::{Pat, PatEnum, PatIdent, PatLit, PatRange, PatRegion, PatStruct}; use ast::{PatTup, PatBox, PatWild, PatWildMulti, PatWildSingle}; use ast::{BiRem, RequiredMethod}; use ast::{RetStyle, Return, BiShl, BiShr, Stmt, StmtDecl}; @@ -79,12 +78,13 @@ use parse::token::{is_ident, is_ident_or_path, is_plain_ident}; use parse::token::{keywords, special_idents, token_to_binop}; use parse::token; use parse::{new_sub_parser_from_file, ParseSess}; +use ptr::P; use owned_slice::OwnedSlice; use std::collections::HashSet; use std::mem::replace; +use std::mem; use std::rc::Rc; -use std::gc::{Gc, GC}; use std::iter; #[allow(non_camel_case_types)] @@ -127,8 +127,8 @@ enum ItemOrViewItem { /// Indicates a failure to parse any kind of item. The attributes are /// returned. IoviNone(Vec<Attribute>), - IoviItem(Gc<Item>), - IoviForeignItem(Gc<ForeignItem>), + IoviItem(P<Item>), + IoviForeignItem(P<ForeignItem>), IoviViewItem(ViewItem) } @@ -143,8 +143,8 @@ macro_rules! maybe_whole_expr ( ($p:expr) => ( { let found = match $p.token { - INTERPOLATED(token::NtExpr(e)) => { - Some(e) + INTERPOLATED(token::NtExpr(ref e)) => { + Some((*e).clone()) } INTERPOLATED(token::NtPath(_)) => { // FIXME: The following avoids an issue with lexical borrowck scopes, @@ -156,7 +156,13 @@ macro_rules! maybe_whole_expr ( let span = $p.span; Some($p.mk_expr(span.lo, span.hi, ExprPath(pt))) } - INTERPOLATED(token::NtBlock(b)) => { + INTERPOLATED(token::NtBlock(_)) => { + // FIXME: The following avoids an issue with lexical borrowck scopes, + // but the clone is unfortunate. + let b = match $p.token { + INTERPOLATED(token::NtBlock(ref b)) => (*b).clone(), + _ => unreachable!() + }; let span = $p.span; Some($p.mk_expr(span.lo, span.hi, ExprBlock(b))) } @@ -286,8 +292,8 @@ fn maybe_append(lhs: Vec<Attribute> , rhs: Option<Vec<Attribute> >) struct ParsedItemsAndViewItems { attrs_remaining: Vec<Attribute>, view_items: Vec<ViewItem>, - items: Vec<Gc<Item>>, - foreign_items: Vec<Gc<ForeignItem>> + items: Vec<P<Item>> , + foreign_items: Vec<P<ForeignItem>> } /* ident is handled by common.rs */ @@ -484,8 +490,7 @@ impl<'a> Parser<'a> { /// Commit to parsing a complete expression `e` expected to be /// followed by some token from the set edible + inedible. Recover /// from anticipated input errors, discarding erroneous characters. - pub fn commit_expr(&mut self, e: Gc<Expr>, edible: &[token::Token], - inedible: &[token::Token]) { + pub fn commit_expr(&mut self, e: &Expr, edible: &[token::Token], inedible: &[token::Token]) { debug!("commit_expr {:?}", e); match e.node { ExprPath(..) => { @@ -500,17 +505,14 @@ impl<'a> Parser<'a> { self.expect_one_of(edible, inedible) } - pub fn commit_expr_expecting(&mut self, e: Gc<Expr>, edible: token::Token) { + pub fn commit_expr_expecting(&mut self, e: &Expr, edible: token::Token) { self.commit_expr(e, &[edible], &[]) } /// Commit to parsing a complete statement `s`, which expects to be /// followed by some token from the set edible + inedible. Check /// for recoverable input errors, discarding erroneous characters. - pub fn commit_stmt(&mut self, s: Gc<Stmt>, edible: &[token::Token], - inedible: &[token::Token]) { - debug!("commit_stmt {:?}", s); - let _s = s; // unused, but future checks might want to inspect `s`. + pub fn commit_stmt(&mut self, edible: &[token::Token], inedible: &[token::Token]) { if self.last_token .as_ref() .map_or(false, |t| is_ident_or_path(&**t)) { @@ -522,8 +524,8 @@ impl<'a> Parser<'a> { self.expect_one_of(edible, inedible) } - pub fn commit_stmt_expecting(&mut self, s: Gc<Stmt>, edible: token::Token) { - self.commit_stmt(s, &[edible], &[]) + pub fn commit_stmt_expecting(&mut self, edible: token::Token) { + self.commit_stmt(&[edible], &[]) } pub fn parse_ident(&mut self) -> ast::Ident { @@ -1043,12 +1045,12 @@ impl<'a> Parser<'a> { self.expect_keyword(keywords::Fn); let (decl, lifetimes) = self.parse_ty_fn_decl(true); - return TyBareFn(box(GC) BareFnTy { + TyBareFn(P(BareFnTy { abi: abi, fn_style: fn_style, lifetimes: lifetimes, decl: decl - }); + })) } /// Parses a procedure type (`proc`). The initial `proc` keyword must @@ -1084,13 +1086,13 @@ impl<'a> Parser<'a> { cf: ret_style, variadic: variadic }); - TyProc(box(GC) ClosureTy { + TyProc(P(ClosureTy { fn_style: NormalFn, onceness: Once, bounds: bounds, decl: decl, lifetimes: lifetime_defs, - }) + })) } /// Parses an optional unboxed closure kind (`&:`, `&mut:`, or `:`). @@ -1176,19 +1178,19 @@ impl<'a> Parser<'a> { match optional_unboxed_closure_kind { Some(unboxed_closure_kind) => { - TyUnboxedFn(box(GC) UnboxedFnTy { + TyUnboxedFn(P(UnboxedFnTy { kind: unboxed_closure_kind, decl: decl, - }) + })) } None => { - TyClosure(box(GC) ClosureTy { + TyClosure(P(ClosureTy { fn_style: fn_style, onceness: onceness, bounds: bounds, decl: decl, lifetimes: lifetime_defs, - }) + })) } } } @@ -1291,8 +1293,9 @@ impl<'a> Parser<'a> { debug!("parse_trait_methods(): parsing provided method"); let (inner_attrs, body) = p.parse_inner_attrs_and_block(); - let attrs = attrs.append(inner_attrs.as_slice()); - ProvidedMethod(box(GC) ast::Method { + let mut attrs = attrs; + attrs.extend(inner_attrs.move_iter()); + ProvidedMethod(P(ast::Method { attrs: attrs, id: ast::DUMMY_NODE_ID, span: mk_sp(lo, hi), @@ -1304,7 +1307,7 @@ impl<'a> Parser<'a> { d, body, vis) - }) + })) } _ => { @@ -1400,7 +1403,7 @@ impl<'a> Parser<'a> { if ts.len() == 1 && !one_tuple { self.expect(&token::RPAREN); - TyParen(*ts.get(0)) + TyParen(ts.move_iter().nth(0).unwrap()) } else { let t = TyTup(ts); self.expect(&token::RPAREN); @@ -1588,7 +1591,7 @@ impl<'a> Parser<'a> { } } - pub fn maybe_parse_fixed_vstore(&mut self) -> Option<Gc<ast::Expr>> { + pub fn maybe_parse_fixed_vstore(&mut self) -> Option<P<ast::Expr>> { if self.token == token::COMMA && self.look_ahead(1, |t| *t == token::DOTDOT) { self.bump(); @@ -1640,12 +1643,12 @@ impl<'a> Parser<'a> { } /// matches '-' lit | lit - pub fn parse_literal_maybe_minus(&mut self) -> Gc<Expr> { + pub fn parse_literal_maybe_minus(&mut self) -> P<Expr> { let minus_lo = self.span.lo; let minus_present = self.eat(&token::BINOP(token::MINUS)); let lo = self.span.lo; - let literal = box(GC) self.parse_lit(); + let literal = P(self.parse_lit()); let hi = self.span.hi; let expr = self.mk_expr(lo, hi, ExprLit(literal)); @@ -1894,85 +1897,84 @@ impl<'a> Parser<'a> { let e = self.parse_expr(); ast::Field { ident: spanned(lo, hi, i), - expr: e, span: mk_sp(lo, e.span.hi), + expr: e, } } - pub fn mk_expr(&mut self, lo: BytePos, hi: BytePos, node: Expr_) -> Gc<Expr> { - box(GC) Expr { + pub fn mk_expr(&mut self, lo: BytePos, hi: BytePos, node: Expr_) -> P<Expr> { + P(Expr { id: ast::DUMMY_NODE_ID, node: node, span: mk_sp(lo, hi), - } + }) } - pub fn mk_unary(&mut self, unop: ast::UnOp, expr: Gc<Expr>) -> ast::Expr_ { + pub fn mk_unary(&mut self, unop: ast::UnOp, expr: P<Expr>) -> ast::Expr_ { ExprUnary(unop, expr) } - pub fn mk_binary(&mut self, binop: ast::BinOp, - lhs: Gc<Expr>, rhs: Gc<Expr>) -> ast::Expr_ { + pub fn mk_binary(&mut self, binop: ast::BinOp, lhs: P<Expr>, rhs: P<Expr>) -> ast::Expr_ { ExprBinary(binop, lhs, rhs) } - pub fn mk_call(&mut self, f: Gc<Expr>, args: Vec<Gc<Expr>>) -> ast::Expr_ { + pub fn mk_call(&mut self, f: P<Expr>, args: Vec<P<Expr>>) -> ast::Expr_ { ExprCall(f, args) } fn mk_method_call(&mut self, ident: ast::SpannedIdent, tps: Vec<P<Ty>>, - args: Vec<Gc<Expr>>) + args: Vec<P<Expr>>) -> ast::Expr_ { ExprMethodCall(ident, tps, args) } - pub fn mk_index(&mut self, expr: Gc<Expr>, idx: Gc<Expr>) -> ast::Expr_ { + pub fn mk_index(&mut self, expr: P<Expr>, idx: P<Expr>) -> ast::Expr_ { ExprIndex(expr, idx) } - pub fn mk_field(&mut self, expr: Gc<Expr>, ident: ast::SpannedIdent, + pub fn mk_field(&mut self, expr: P<Expr>, ident: ast::SpannedIdent, tys: Vec<P<Ty>>) -> ast::Expr_ { ExprField(expr, ident, tys) } - pub fn mk_tup_field(&mut self, expr: Gc<Expr>, idx: codemap::Spanned<uint>, + pub fn mk_tup_field(&mut self, expr: P<Expr>, idx: codemap::Spanned<uint>, tys: Vec<P<Ty>>) -> ast::Expr_ { ExprTupField(expr, idx, tys) } pub fn mk_assign_op(&mut self, binop: ast::BinOp, - lhs: Gc<Expr>, rhs: Gc<Expr>) -> ast::Expr_ { + lhs: P<Expr>, rhs: P<Expr>) -> ast::Expr_ { ExprAssignOp(binop, lhs, rhs) } - pub fn mk_mac_expr(&mut self, lo: BytePos, hi: BytePos, m: Mac_) -> Gc<Expr> { - box(GC) Expr { + pub fn mk_mac_expr(&mut self, lo: BytePos, hi: BytePos, m: Mac_) -> P<Expr> { + P(Expr { id: ast::DUMMY_NODE_ID, node: ExprMac(codemap::Spanned {node: m, span: mk_sp(lo, hi)}), span: mk_sp(lo, hi), - } + }) } - pub fn mk_lit_u32(&mut self, i: u32) -> Gc<Expr> { + pub fn mk_lit_u32(&mut self, i: u32) -> P<Expr> { let span = &self.span; - let lv_lit = box(GC) codemap::Spanned { + let lv_lit = P(codemap::Spanned { node: LitInt(i as u64, ast::UnsignedIntLit(TyU32)), span: *span - }; + }); - box(GC) Expr { + P(Expr { id: ast::DUMMY_NODE_ID, node: ExprLit(lv_lit), span: *span, - } + }) } /// At the bottom (top?) of the precedence hierarchy, /// parse things like parenthesized exprs, /// macros, return, etc. - pub fn parse_bottom_expr(&mut self) -> Gc<Expr> { + pub fn parse_bottom_expr(&mut self) -> P<Expr> { maybe_whole_expr!(self); let lo = self.span.lo; @@ -1989,28 +1991,27 @@ impl<'a> Parser<'a> { if self.token == token::RPAREN { hi = self.span.hi; self.bump(); - let lit = box(GC) spanned(lo, hi, LitNil); + let lit = P(spanned(lo, hi, LitNil)); return self.mk_expr(lo, hi, ExprLit(lit)); } let mut es = vec!(self.parse_expr()); - self.commit_expr(*es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]); + self.commit_expr(&**es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]); while self.token == token::COMMA { self.bump(); if self.token != token::RPAREN { es.push(self.parse_expr()); - self.commit_expr(*es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]); - } - else { + self.commit_expr(&**es.last().unwrap(), &[], + &[token::COMMA, token::RPAREN]); + } else { trailing_comma = true; } } hi = self.span.hi; - self.commit_expr_expecting(*es.last().unwrap(), token::RPAREN); + self.commit_expr_expecting(&**es.last().unwrap(), token::RPAREN); return if es.len() == 1 && !trailing_comma { - self.mk_expr(lo, hi, ExprParen(*es.get(0))) - } - else { + self.mk_expr(lo, hi, ExprParen(es.move_iter().nth(0).unwrap())) + } else { self.mk_expr(lo, hi, ExprTup(es)) } }, @@ -2079,14 +2080,14 @@ impl<'a> Parser<'a> { let decl = self.parse_proc_decl(); let body = self.parse_expr(); let fakeblock = P(ast::Block { + id: ast::DUMMY_NODE_ID, view_items: Vec::new(), stmts: Vec::new(), - expr: Some(body), - id: ast::DUMMY_NODE_ID, rules: DefaultBlock, span: body.span, + expr: Some(body), }); - return self.mk_expr(lo, body.span.hi, ExprProc(decl, fakeblock)); + return self.mk_expr(lo, fakeblock.span.hi, ExprProc(decl, fakeblock)); } if self.eat_keyword(keywords::If) { return self.parse_if_expr(); @@ -2200,7 +2201,7 @@ impl<'a> Parser<'a> { } fields.push(self.parse_field()); - self.commit_expr(fields.last().unwrap().expr, + self.commit_expr(&*fields.last().unwrap().expr, &[token::COMMA], &[token::RBRACE]); } @@ -2227,7 +2228,7 @@ impl<'a> Parser<'a> { // other literal expression let lit = self.parse_lit(); hi = lit.span.hi; - ex = ExprLit(box(GC) lit); + ex = ExprLit(P(lit)); } } } @@ -2237,19 +2238,19 @@ impl<'a> Parser<'a> { /// Parse a block or unsafe block pub fn parse_block_expr(&mut self, lo: BytePos, blk_mode: BlockCheckMode) - -> Gc<Expr> { + -> P<Expr> { self.expect(&token::LBRACE); let blk = self.parse_block_tail(lo, blk_mode); return self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk)); } /// parse a.b or a(13) or a[4] or just a - pub fn parse_dot_or_call_expr(&mut self) -> Gc<Expr> { + pub fn parse_dot_or_call_expr(&mut self) -> P<Expr> { let b = self.parse_bottom_expr(); self.parse_dot_or_call_expr_with(b) } - pub fn parse_dot_or_call_expr_with(&mut self, e0: Gc<Expr>) -> Gc<Expr> { + pub fn parse_dot_or_call_expr_with(&mut self, e0: P<Expr>) -> P<Expr> { let mut e = e0; let lo = e.span.lo; let mut hi; @@ -2330,7 +2331,7 @@ impl<'a> Parser<'a> { } continue; } - if self.expr_is_complete(e) { break; } + if self.expr_is_complete(&*e) { break; } match self.token { // expr(...) token::LPAREN => { @@ -2351,7 +2352,7 @@ impl<'a> Parser<'a> { self.bump(); let ix = self.parse_expr(); hi = self.span.hi; - self.commit_expr_expecting(ix, token::RBRACKET); + self.commit_expr_expecting(&*ix, token::RBRACKET); let index = self.mk_index(e, ix); e = self.mk_expr(lo, hi, index) } @@ -2556,7 +2557,7 @@ impl<'a> Parser<'a> { } /// Parse a prefix-operator expr - pub fn parse_prefix_expr(&mut self) -> Gc<Expr> { + pub fn parse_prefix_expr(&mut self) -> P<Expr> { let lo = self.span.lo; let hi; @@ -2638,28 +2639,23 @@ impl<'a> Parser<'a> { } /// Parse an expression of binops - pub fn parse_binops(&mut self) -> Gc<Expr> { + pub fn parse_binops(&mut self) -> P<Expr> { let prefix_expr = self.parse_prefix_expr(); self.parse_more_binops(prefix_expr, 0) } /// Parse an expression of binops of at least min_prec precedence - pub fn parse_more_binops(&mut self, lhs: Gc<Expr>, - min_prec: uint) -> Gc<Expr> { - if self.expr_is_complete(lhs) { return lhs; } + pub fn parse_more_binops(&mut self, lhs: P<Expr>, min_prec: uint) -> P<Expr> { + if self.expr_is_complete(&*lhs) { return lhs; } // Prevent dynamic borrow errors later on by limiting the // scope of the borrows. - { - let token: &token::Token = &self.token; - let restriction: &restriction = &self.restriction; - match (token, restriction) { - (&token::BINOP(token::OR), &RESTRICT_NO_BAR_OP) => return lhs, - (&token::BINOP(token::OR), - &RESTRICT_NO_BAR_OR_DOUBLEBAR_OP) => return lhs, - (&token::OROR, &RESTRICT_NO_BAR_OR_DOUBLEBAR_OP) => return lhs, - _ => { } - } + match (&self.token, &self.restriction) { + (&token::BINOP(token::OR), &RESTRICT_NO_BAR_OP) => return lhs, + (&token::BINOP(token::OR), + &RESTRICT_NO_BAR_OR_DOUBLEBAR_OP) => return lhs, + (&token::OROR, &RESTRICT_NO_BAR_OR_DOUBLEBAR_OP) => return lhs, + _ => { } } let cur_opt = token_to_binop(&self.token); @@ -2670,8 +2666,10 @@ impl<'a> Parser<'a> { self.bump(); let expr = self.parse_prefix_expr(); let rhs = self.parse_more_binops(expr, cur_prec); + let lhs_span = lhs.span; + let rhs_span = rhs.span; let binary = self.mk_binary(cur_op, lhs, rhs); - let bin = self.mk_expr(lhs.span.lo, rhs.span.hi, binary); + let bin = self.mk_expr(lhs_span.lo, rhs_span.hi, binary); self.parse_more_binops(bin, min_prec) } else { lhs @@ -2694,7 +2692,7 @@ impl<'a> Parser<'a> { /// Parse an assignment expression.... /// actually, this seems to be the main entry point for /// parsing an arbitrary expression. - pub fn parse_assign_expr(&mut self) -> Gc<Expr> { + pub fn parse_assign_expr(&mut self) -> P<Expr> { let lo = self.span.lo; let lhs = self.parse_binops(); match self.token { @@ -2718,8 +2716,9 @@ impl<'a> Parser<'a> { token::SHL => BiShl, token::SHR => BiShr }; + let rhs_span = rhs.span; let assign_op = self.mk_assign_op(aop, lhs, rhs); - self.mk_expr(lo, rhs.span.hi, assign_op) + self.mk_expr(lo, rhs_span.hi, assign_op) } _ => { lhs @@ -2728,40 +2727,40 @@ impl<'a> Parser<'a> { } /// Parse an 'if' expression ('if' token already eaten) - pub fn parse_if_expr(&mut self) -> Gc<Expr> { + pub fn parse_if_expr(&mut self) -> P<Expr> { let lo = self.last_span.lo; let cond = self.parse_expr_res(RESTRICT_NO_STRUCT_LITERAL); let thn = self.parse_block(); - let mut els: Option<Gc<Expr>> = None; + let mut els: Option<P<Expr>> = None; let mut hi = thn.span.hi; if self.eat_keyword(keywords::Else) { let elexpr = self.parse_else_expr(); - els = Some(elexpr); hi = elexpr.span.hi; + els = Some(elexpr); } self.mk_expr(lo, hi, ExprIf(cond, thn, els)) } // `|args| expr` pub fn parse_lambda_expr(&mut self, capture_clause: CaptureClause) - -> Gc<Expr> { + -> P<Expr> { let lo = self.span.lo; let (decl, optional_unboxed_closure_kind) = self.parse_fn_block_decl(); let body = self.parse_expr(); let fakeblock = P(ast::Block { + id: ast::DUMMY_NODE_ID, view_items: Vec::new(), stmts: Vec::new(), + span: body.span, expr: Some(body), - id: ast::DUMMY_NODE_ID, rules: DefaultBlock, - span: body.span, }); match optional_unboxed_closure_kind { Some(unboxed_closure_kind) => { self.mk_expr(lo, - body.span.hi, + fakeblock.span.hi, ExprUnboxedFn(capture_clause, unboxed_closure_kind, decl, @@ -2769,13 +2768,13 @@ impl<'a> Parser<'a> { } None => { self.mk_expr(lo, - body.span.hi, + fakeblock.span.hi, ExprFnBlock(capture_clause, decl, fakeblock)) } } } - pub fn parse_else_expr(&mut self) -> Gc<Expr> { + pub fn parse_else_expr(&mut self) -> P<Expr> { if self.eat_keyword(keywords::If) { return self.parse_if_expr(); } else { @@ -2785,7 +2784,7 @@ impl<'a> Parser<'a> { } /// Parse a 'for' .. 'in' expression ('for' token already eaten) - pub fn parse_for_expr(&mut self, opt_ident: Option<ast::Ident>) -> Gc<Expr> { + pub fn parse_for_expr(&mut self, opt_ident: Option<ast::Ident>) -> P<Expr> { // Parse: `for <src_pat> in <src_expr> <src_loop_block>` let lo = self.last_span.lo; @@ -2798,7 +2797,7 @@ impl<'a> Parser<'a> { self.mk_expr(lo, hi, ExprForLoop(pat, expr, loop_block, opt_ident)) } - pub fn parse_while_expr(&mut self, opt_ident: Option<ast::Ident>) -> Gc<Expr> { + pub fn parse_while_expr(&mut self, opt_ident: Option<ast::Ident>) -> P<Expr> { let lo = self.last_span.lo; let cond = self.parse_expr_res(RESTRICT_NO_STRUCT_LITERAL); let body = self.parse_block(); @@ -2806,17 +2805,17 @@ impl<'a> Parser<'a> { return self.mk_expr(lo, hi, ExprWhile(cond, body, opt_ident)); } - pub fn parse_loop_expr(&mut self, opt_ident: Option<ast::Ident>) -> Gc<Expr> { + pub fn parse_loop_expr(&mut self, opt_ident: Option<ast::Ident>) -> P<Expr> { let lo = self.last_span.lo; let body = self.parse_block(); let hi = body.span.hi; self.mk_expr(lo, hi, ExprLoop(body, opt_ident)) } - fn parse_match_expr(&mut self) -> Gc<Expr> { + fn parse_match_expr(&mut self) -> P<Expr> { let lo = self.last_span.lo; let discriminant = self.parse_expr_res(RESTRICT_NO_STRUCT_LITERAL); - self.commit_expr_expecting(discriminant, token::LBRACE); + self.commit_expr_expecting(&*discriminant, token::LBRACE); let mut arms: Vec<Arm> = Vec::new(); while self.token != token::RBRACE { arms.push(self.parse_arm()); @@ -2837,11 +2836,11 @@ impl<'a> Parser<'a> { let expr = self.parse_expr_res(RESTRICT_STMT_EXPR); let require_comma = - !classify::expr_is_simple_block(expr) + !classify::expr_is_simple_block(&*expr) && self.token != token::RBRACE; if require_comma { - self.commit_expr(expr, &[token::COMMA], &[token::RBRACE]); + self.commit_expr(&*expr, &[token::COMMA], &[token::RBRACE]); } else { self.eat(&token::COMMA); } @@ -2855,12 +2854,12 @@ impl<'a> Parser<'a> { } /// Parse an expression - pub fn parse_expr(&mut self) -> Gc<Expr> { + pub fn parse_expr(&mut self) -> P<Expr> { return self.parse_expr_res(UNRESTRICTED); } /// Parse an expression, subject to the given restriction - pub fn parse_expr_res(&mut self, r: restriction) -> Gc<Expr> { + pub fn parse_expr_res(&mut self, r: restriction) -> P<Expr> { let old = self.restriction; self.restriction = r; let e = self.parse_assign_expr(); @@ -2869,7 +2868,7 @@ impl<'a> Parser<'a> { } /// Parse the RHS of a local variable declaration (e.g. '= 14;') - fn parse_initializer(&mut self) -> Option<Gc<Expr>> { + fn parse_initializer(&mut self) -> Option<P<Expr>> { if self.token == token::EQ { self.bump(); Some(self.parse_expr()) @@ -2879,7 +2878,7 @@ impl<'a> Parser<'a> { } /// Parse patterns, separated by '|' s - fn parse_pats(&mut self) -> Vec<Gc<Pat>> { + fn parse_pats(&mut self) -> Vec<P<Pat>> { let mut pats = Vec::new(); loop { pats.push(self.parse_pat()); @@ -2890,7 +2889,7 @@ impl<'a> Parser<'a> { fn parse_pat_vec_elements( &mut self, - ) -> (Vec<Gc<Pat>> , Option<Gc<Pat>>, Vec<Gc<Pat>> ) { + ) -> (Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>) { let mut before = Vec::new(); let mut slice = None; let mut after = Vec::new(); @@ -2910,11 +2909,11 @@ impl<'a> Parser<'a> { if self.token == token::COMMA || self.token == token::RBRACKET { - slice = Some(box(GC) ast::Pat { + slice = Some(P(ast::Pat { id: ast::DUMMY_NODE_ID, node: PatWild(PatWildMulti), span: self.span, - }); + })); before_slice = false; } else { let _ = self.parse_pat(); @@ -2989,11 +2988,11 @@ impl<'a> Parser<'a> { self.parse_pat() } else { let fieldpath = codemap::Spanned{span:self.last_span, node: fieldname}; - box(GC) ast::Pat { + P(ast::Pat { id: ast::DUMMY_NODE_ID, node: PatIdent(bind_type, fieldpath, None), span: self.last_span - } + }) }; fields.push(ast::FieldPat { ident: fieldname, pat: subpat }); } @@ -3001,7 +3000,7 @@ impl<'a> Parser<'a> { } /// Parse a pattern. - pub fn parse_pat(&mut self) -> Gc<Pat> { + pub fn parse_pat(&mut self) -> P<Pat> { maybe_whole!(self, NtPat); let lo = self.span.lo; @@ -3013,11 +3012,11 @@ impl<'a> Parser<'a> { self.bump(); pat = PatWild(PatWildSingle); hi = self.last_span.hi; - return box(GC) ast::Pat { + return P(ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span: mk_sp(lo, hi) - } + }) } token::TILDE => { // parse ~pat @@ -3027,11 +3026,11 @@ impl<'a> Parser<'a> { let last_span = self.last_span; hi = last_span.hi; self.obsolete(last_span, ObsoleteOwnedPattern); - return box(GC) ast::Pat { + return P(ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span: mk_sp(lo, hi) - } + }) } token::BINOP(token::AND) | token::ANDAND => { // parse &pat @@ -3040,11 +3039,11 @@ impl<'a> Parser<'a> { let sub = self.parse_pat(); pat = PatRegion(sub); hi = self.last_span.hi; - return box(GC) ast::Pat { + return P(ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span: mk_sp(lo, hi) - } + }) } token::LPAREN => { // parse (pat,pat,pat,...) as tuple @@ -3052,9 +3051,9 @@ impl<'a> Parser<'a> { if self.token == token::RPAREN { hi = self.span.hi; self.bump(); - let lit = box(GC) codemap::Spanned { + let lit = P(codemap::Spanned { node: LitNil, - span: mk_sp(lo, hi)}; + span: mk_sp(lo, hi)}); let expr = self.mk_expr(lo, hi, ExprLit(lit)); pat = PatLit(expr); } else { @@ -3071,11 +3070,11 @@ impl<'a> Parser<'a> { pat = PatTup(fields); } hi = self.last_span.hi; - return box(GC) ast::Pat { + return P(ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span: mk_sp(lo, hi) - } + }) } token::LBRACKET => { // parse [pat,pat,...] as vector pattern @@ -3086,11 +3085,11 @@ impl<'a> Parser<'a> { self.expect(&token::RBRACKET); pat = ast::PatVec(before, slice, after); hi = self.last_span.hi; - return box(GC) ast::Pat { + return P(ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span: mk_sp(lo, hi) - } + }) } _ => {} } @@ -3135,11 +3134,11 @@ impl<'a> Parser<'a> { let sub = self.parse_pat(); pat = PatBox(sub); hi = self.last_span.hi; - return box(GC) ast::Pat { + return P(ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span: mk_sp(lo, hi) - } + }) } else { let can_be_enum_or_struct = self.look_ahead(1, |t| { match *t { @@ -3196,7 +3195,7 @@ impl<'a> Parser<'a> { pat = PatStruct(enum_path, fields, etc); } _ => { - let mut args: Vec<Gc<Pat>> = Vec::new(); + let mut args: Vec<P<Pat>> = Vec::new(); match self.token { token::LPAREN => { let is_dotdot = self.look_ahead(1, |t| { @@ -3251,11 +3250,11 @@ impl<'a> Parser<'a> { } } hi = self.last_span.hi; - box(GC) ast::Pat { + P(ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span: mk_sp(lo, hi), - } + }) } /// Parse ident or ident @ pat @@ -3295,7 +3294,7 @@ impl<'a> Parser<'a> { } /// Parse a local variable declaration - fn parse_local(&mut self) -> Gc<Local> { + fn parse_local(&mut self) -> P<Local> { let lo = self.span.lo; let pat = self.parse_pat(); @@ -3308,21 +3307,21 @@ impl<'a> Parser<'a> { ty = self.parse_ty(true); } let init = self.parse_initializer(); - box(GC) ast::Local { + P(ast::Local { ty: ty, pat: pat, init: init, id: ast::DUMMY_NODE_ID, span: mk_sp(lo, self.last_span.hi), source: LocalLet, - } + }) } /// Parse a "let" stmt - fn parse_let(&mut self) -> Gc<Decl> { + fn parse_let(&mut self) -> P<Decl> { let lo = self.span.lo; let local = self.parse_local(); - box(GC) spanned(lo, self.last_span.hi, DeclLocal(local)) + P(spanned(lo, self.last_span.hi, DeclLocal(local))) } /// Parse a structure field @@ -3345,7 +3344,7 @@ impl<'a> Parser<'a> { /// Parse a statement. may include decl. /// Precondition: any attributes are parsed already - pub fn parse_stmt(&mut self, item_attrs: Vec<Attribute>) -> Gc<Stmt> { + pub fn parse_stmt(&mut self, item_attrs: Vec<Attribute>) -> P<Stmt> { maybe_whole!(self, NtStmt); fn check_expected_item(p: &mut Parser, found_attrs: bool) { @@ -3361,7 +3360,7 @@ impl<'a> Parser<'a> { check_expected_item(self, !item_attrs.is_empty()); self.expect_keyword(keywords::Let); let decl = self.parse_let(); - return box(GC) spanned(lo, decl.span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID)); + P(spanned(lo, decl.span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID))) } else if is_ident(&self.token) && !token::is_any_keyword(&self.token) && self.look_ahead(1, |t| *t == token::NOT) { @@ -3409,17 +3408,17 @@ impl<'a> Parser<'a> { let hi = self.span.hi; if id.name == token::special_idents::invalid.name { - return box(GC) spanned(lo, hi, StmtMac( - spanned(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT)), false)); + P(spanned(lo, hi, StmtMac( + spanned(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT)), false))) } else { // if it has a special ident, it's definitely an item - return box(GC) spanned(lo, hi, StmtDecl( - box(GC) spanned(lo, hi, DeclItem( + P(spanned(lo, hi, StmtDecl( + P(spanned(lo, hi, DeclItem( self.mk_item( lo, hi, id /*id is good here*/, ItemMac(spanned(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT))), - Inherited, Vec::new(/*no attrs*/)))), - ast::DUMMY_NODE_ID)); + Inherited, Vec::new(/*no attrs*/))))), + ast::DUMMY_NODE_ID))) } } else { @@ -3427,8 +3426,8 @@ impl<'a> Parser<'a> { match self.parse_item_or_view_item(item_attrs, false) { IoviItem(i) => { let hi = i.span.hi; - let decl = box(GC) spanned(lo, hi, DeclItem(i)); - return box(GC) spanned(lo, hi, StmtDecl(decl, ast::DUMMY_NODE_ID)); + let decl = P(spanned(lo, hi, DeclItem(i))); + P(spanned(lo, hi, StmtDecl(decl, ast::DUMMY_NODE_ID))) } IoviViewItem(vi) => { self.span_fatal(vi.span, @@ -3437,21 +3436,21 @@ impl<'a> Parser<'a> { IoviForeignItem(_) => { self.fatal("foreign items are not allowed here"); } - IoviNone(_) => { /* fallthrough */ } - } + IoviNone(_) => { + check_expected_item(self, found_attrs); - check_expected_item(self, found_attrs); - - // Remainder are line-expr stmts. - let e = self.parse_expr_res(RESTRICT_STMT_EXPR); - return box(GC) spanned(lo, e.span.hi, StmtExpr(e, ast::DUMMY_NODE_ID)); + // Remainder are line-expr stmts. + let e = self.parse_expr_res(RESTRICT_STMT_EXPR); + P(spanned(lo, e.span.hi, StmtExpr(e, ast::DUMMY_NODE_ID))) + } + } } } /// Is this expression a successfully-parsed statement? - fn expr_is_complete(&mut self, e: Gc<Expr>) -> bool { - return self.restriction == RESTRICT_STMT_EXPR && - !classify::expr_requires_semi_to_be_stmt(e); + fn expr_is_complete(&mut self, e: &Expr) -> bool { + self.restriction == RESTRICT_STMT_EXPR && + !classify::expr_requires_semi_to_be_stmt(e) } /// Parse a block. No inner attrs are allowed. @@ -3500,10 +3499,10 @@ impl<'a> Parser<'a> { } = self.parse_items_and_view_items(first_item_attrs, false, false); - for item in items.iter() { - let decl = box(GC) spanned(item.span.lo, item.span.hi, DeclItem(*item)); - stmts.push(box(GC) spanned(item.span.lo, item.span.hi, - StmtDecl(decl, ast::DUMMY_NODE_ID))); + for item in items.move_iter() { + let span = item.span; + let decl = P(spanned(span.lo, span.hi, DeclItem(item))); + stmts.push(P(spanned(span.lo, span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID)))); } let mut attributes_box = attrs_remaining; @@ -3527,66 +3526,75 @@ impl<'a> Parser<'a> { _ => { let stmt = self.parse_stmt(attributes_box); attributes_box = Vec::new(); - match stmt.node { + stmt.and_then(|Spanned {node, span}| match node { StmtExpr(e, stmt_id) => { // expression without semicolon - if classify::stmt_ends_with_semi(&*stmt) { + if classify::expr_requires_semi_to_be_stmt(&*e) { // Just check for errors and recover; do not eat semicolon yet. - self.commit_stmt(stmt, &[], &[token::SEMI, token::RBRACE]); + self.commit_stmt(&[], &[token::SEMI, token::RBRACE]); } match self.token { token::SEMI => { self.bump(); let span_with_semi = Span { - lo: stmt.span.lo, + lo: span.lo, hi: self.last_span.hi, - expn_info: stmt.span.expn_info, + expn_info: span.expn_info, }; - stmts.push(box(GC) codemap::Spanned { + stmts.push(P(Spanned { node: StmtSemi(e, stmt_id), span: span_with_semi, - }); + })); } token::RBRACE => { expr = Some(e); } _ => { - stmts.push(stmt); + stmts.push(P(Spanned { + node: StmtExpr(e, stmt_id), + span: span + })); } } } - StmtMac(ref m, _) => { + StmtMac(m, semi) => { // statement macro; might be an expr match self.token { token::SEMI => { + stmts.push(P(Spanned { + node: StmtMac(m, true), + span: span, + })); self.bump(); - stmts.push(box(GC) codemap::Spanned { - node: StmtMac((*m).clone(), true), - span: stmt.span, - }); } token::RBRACE => { // if a block ends in `m!(arg)` without // a `;`, it must be an expr expr = Some( - self.mk_mac_expr(stmt.span.lo, - stmt.span.hi, - m.node.clone())); + self.mk_mac_expr(span.lo, + span.hi, + m.node)); } _ => { - stmts.push(stmt); + stmts.push(P(Spanned { + node: StmtMac(m, semi), + span: span + })); } } } _ => { // all other kinds of statements: - stmts.push(stmt.clone()); - - if classify::stmt_ends_with_semi(&*stmt) { - self.commit_stmt_expecting(stmt, token::SEMI); + if classify::stmt_ends_with_semi(&node) { + self.commit_stmt_expecting(token::SEMI); } + + stmts.push(P(Spanned { + node: node, + span: span + })); } - } + }) } } } @@ -4187,15 +4195,15 @@ impl<'a> Parser<'a> { fn mk_item(&mut self, lo: BytePos, hi: BytePos, ident: Ident, node: Item_, vis: Visibility, - attrs: Vec<Attribute>) -> Gc<Item> { - box(GC) Item { + attrs: Vec<Attribute>) -> P<Item> { + P(Item { ident: ident, attrs: attrs, id: ast::DUMMY_NODE_ID, node: node, vis: vis, span: mk_sp(lo, hi) - } + }) } /// Parse an item-position function declaration. @@ -4210,7 +4218,7 @@ impl<'a> Parser<'a> { /// Parse a method in a trait impl, starting with `attrs` attributes. pub fn parse_method(&mut self, already_parsed_attrs: Option<Vec<Attribute>>) - -> Gc<Method> { + -> P<Method> { let next_attrs = self.parse_outer_attributes(); let attrs = match already_parsed_attrs { Some(mut a) => { a.push_all_move(next_attrs); a } @@ -4264,6 +4272,7 @@ impl<'a> Parser<'a> { }); self.parse_where_clause(&mut generics); let (inner_attrs, body) = self.parse_inner_attrs_and_block(); + let body_span = body.span; let new_attrs = attrs.append(inner_attrs.as_slice()); (ast::MethDecl(ident, generics, @@ -4273,15 +4282,15 @@ impl<'a> Parser<'a> { decl, body, visa), - body.span.hi, new_attrs) + body_span.hi, new_attrs) } }; - box(GC) ast::Method { + P(ast::Method { attrs: new_attrs, id: ast::DUMMY_NODE_ID, span: mk_sp(lo, hi), node: method_, - } + }) } /// Parse trait Foo { ... } @@ -4444,12 +4453,12 @@ impl<'a> Parser<'a> { let _ = ast::DUMMY_NODE_ID; // FIXME: Workaround for crazy bug. let new_id = ast::DUMMY_NODE_ID; (class_name, - ItemStruct(box(GC) ast::StructDef { + ItemStruct(P(ast::StructDef { fields: fields, ctor_id: if is_tuple_like { Some(new_id) } else { None }, super_struct: super_struct, is_virtual: is_virtual, - }, generics), + }), generics), None) } @@ -4524,7 +4533,7 @@ impl<'a> Parser<'a> { items: starting_items, .. } = self.parse_items_and_view_items(first_item_attrs, true, true); - let mut items: Vec<Gc<Item>> = starting_items; + let mut items: Vec<P<Item>> = starting_items; let attrs_remaining_len = attrs_remaining.len(); // don't think this other loop is even necessary.... @@ -4574,7 +4583,7 @@ impl<'a> Parser<'a> { let ty = self.parse_ty(true); self.expect(&token::EQ); let e = self.parse_expr(); - self.commit_expr_expecting(e, token::SEMI); + self.commit_expr_expecting(&*e, token::SEMI); (id, ItemStatic(ty, m, e), None) } @@ -4726,7 +4735,7 @@ impl<'a> Parser<'a> { /// Parse a function declaration from a foreign module fn parse_item_foreign_fn(&mut self, vis: ast::Visibility, - attrs: Vec<Attribute>) -> Gc<ForeignItem> { + attrs: Vec<Attribute>) -> P<ForeignItem> { let lo = self.span.lo; self.expect_keyword(keywords::Fn); @@ -4735,17 +4744,19 @@ impl<'a> Parser<'a> { self.parse_where_clause(&mut generics); let hi = self.span.hi; self.expect(&token::SEMI); - box(GC) ast::ForeignItem { ident: ident, - attrs: attrs, - node: ForeignItemFn(decl, generics), - id: ast::DUMMY_NODE_ID, - span: mk_sp(lo, hi), - vis: vis } + P(ast::ForeignItem { + ident: ident, + attrs: attrs, + node: ForeignItemFn(decl, generics), + id: ast::DUMMY_NODE_ID, + span: mk_sp(lo, hi), + vis: vis + }) } /// Parse a static item from a foreign module fn parse_item_foreign_static(&mut self, vis: ast::Visibility, - attrs: Vec<Attribute> ) -> Gc<ForeignItem> { + attrs: Vec<Attribute>) -> P<ForeignItem> { let lo = self.span.lo; self.expect_keyword(keywords::Static); @@ -4756,14 +4767,14 @@ impl<'a> Parser<'a> { let ty = self.parse_ty(true); let hi = self.span.hi; self.expect(&token::SEMI); - box(GC) ast::ForeignItem { + P(ForeignItem { ident: ident, attrs: attrs, node: ForeignItemStatic(ty, mutbl), id: ast::DUMMY_NODE_ID, span: mk_sp(lo, hi), - vis: vis, - } + vis: vis + }) } /// Parse safe/unsafe and fn @@ -4903,19 +4914,19 @@ impl<'a> Parser<'a> { /// Parse a structure-like enum variant definition /// this should probably be renamed or refactored... - fn parse_struct_def(&mut self) -> Gc<StructDef> { + fn parse_struct_def(&mut self) -> P<StructDef> { let mut fields: Vec<StructField> = Vec::new(); while self.token != token::RBRACE { fields.push(self.parse_struct_decl_field()); } self.bump(); - return box(GC) ast::StructDef { + P(StructDef { fields: fields, ctor_id: None, super_struct: None, is_virtual: false, - }; + }) } /// Parse the part of an "enum" decl following the '{' @@ -5034,16 +5045,21 @@ impl<'a> Parser<'a> { attrs: Vec<Attribute> , macros_allowed: bool) -> ItemOrViewItem { - match self.token { - INTERPOLATED(token::NtItem(item)) => { + let nt_item = match self.token { + INTERPOLATED(token::NtItem(ref item)) => { + Some((**item).clone()) + } + _ => None + }; + match nt_item { + Some(mut item) => { self.bump(); - let new_attrs = attrs.append(item.attrs.as_slice()); - return IoviItem(box(GC) Item { - attrs: new_attrs, - ..(*item).clone() - }); + let mut attrs = attrs; + mem::swap(&mut item.attrs, &mut attrs); + item.attrs.extend(attrs.move_iter()); + return IoviItem(P(item)); } - _ => {} + None => {} } let lo = self.span.lo; @@ -5328,12 +5344,12 @@ impl<'a> Parser<'a> { return IoviNone(attrs); } - pub fn parse_item_with_outer_attributes(&mut self) -> Option<Gc<Item>> { + pub fn parse_item_with_outer_attributes(&mut self) -> Option<P<Item>> { let attrs = self.parse_outer_attributes(); self.parse_item(attrs) } - pub fn parse_item(&mut self, attrs: Vec<Attribute> ) -> Option<Gc<Item>> { + pub fn parse_item(&mut self, attrs: Vec<Attribute>) -> Option<P<Item>> { match self.parse_item_or_view_item(attrs, true) { IoviNone(_) => None, IoviViewItem(_) => @@ -5355,7 +5371,7 @@ impl<'a> Parser<'a> { /// | MOD? non_global_path MOD_SEP LBRACE ident_seq RBRACE /// | MOD? non_global_path MOD_SEP STAR /// | MOD? non_global_path - fn parse_view_path(&mut self) -> Gc<ViewPath> { + fn parse_view_path(&mut self) -> P<ViewPath> { let lo = self.span.lo; if self.token == token::LBRACE { @@ -5369,8 +5385,8 @@ impl<'a> Parser<'a> { global: false, segments: Vec::new() }; - return box(GC) spanned(lo, self.span.hi, - ViewPathList(path, idents, ast::DUMMY_NODE_ID)); + return P(spanned(lo, self.span.hi, + ViewPathList(path, idents, ast::DUMMY_NODE_ID))); } let first_ident = self.parse_ident(); @@ -5399,9 +5415,9 @@ impl<'a> Parser<'a> { } }).collect() }; - return box(GC) spanned(lo, self.span.hi, - ViewPathSimple(first_ident, path, - ast::DUMMY_NODE_ID)); + return P(spanned(lo, self.span.hi, + ViewPathSimple(first_ident, path, + ast::DUMMY_NODE_ID))); } token::MOD_SEP => { @@ -5434,8 +5450,8 @@ impl<'a> Parser<'a> { } }).collect() }; - return box(GC) spanned(lo, self.span.hi, - ViewPathList(path, idents, ast::DUMMY_NODE_ID)); + return P(spanned(lo, self.span.hi, + ViewPathList(path, idents, ast::DUMMY_NODE_ID))); } // foo::bar::* @@ -5452,8 +5468,8 @@ impl<'a> Parser<'a> { } }).collect() }; - return box(GC) spanned(lo, self.span.hi, - ViewPathGlob(path, ast::DUMMY_NODE_ID)); + return P(spanned(lo, self.span.hi, + ViewPathGlob(path, ast::DUMMY_NODE_ID))); } _ => break @@ -5477,9 +5493,8 @@ impl<'a> Parser<'a> { if self.eat_keyword(keywords::As) { rename_to = self.parse_ident() } - return box(GC) spanned(lo, - self.last_span.hi, - ViewPathSimple(rename_to, path, ast::DUMMY_NODE_ID)); + P(spanned(lo, self.last_span.hi, + ViewPathSimple(rename_to, path, ast::DUMMY_NODE_ID))) } /// Parses a sequence of items. Stops when it finds program |
