From ccd8498afbb371939b7decdbee712f726ccbded3 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Sat, 13 Sep 2014 19:06:01 +0300 Subject: syntax: fix fallout from using ptr::P. --- src/libsyntax/parse/attr.rs | 36 +-- src/libsyntax/parse/classify.rs | 17 +- src/libsyntax/parse/mod.rs | 58 ++--- src/libsyntax/parse/obsolete.rs | 9 +- src/libsyntax/parse/parser.rs | 487 +++++++++++++++++++++------------------- src/libsyntax/parse/token.rs | 20 +- 6 files changed, 323 insertions(+), 304 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index eca02d06ca9..74b93e75e64 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -15,8 +15,7 @@ use parse::common::*; //resolve bug? use parse::token; use parse::parser::Parser; use parse::token::INTERPOLATED; - -use std::gc::{Gc, GC}; +use ptr::P; /// A parser that can parse attributes. pub trait ParserAttr { @@ -24,9 +23,9 @@ pub trait ParserAttr { fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute; fn parse_inner_attrs_and_next(&mut self) -> (Vec, Vec); - fn parse_meta_item(&mut self) -> Gc; - fn parse_meta_seq(&mut self) -> Vec>; - fn parse_optional_meta(&mut self) -> Vec>; + fn parse_meta_item(&mut self) -> P; + fn parse_meta_seq(&mut self) -> Vec>; + fn parse_optional_meta(&mut self) -> Vec>; } impl<'a> ParserAttr for Parser<'a> { @@ -160,13 +159,20 @@ impl<'a> ParserAttr for Parser<'a> { /// matches meta_item = IDENT /// | IDENT = lit /// | IDENT meta_seq - fn parse_meta_item(&mut self) -> Gc { - match self.token { - token::INTERPOLATED(token::NtMeta(e)) => { + fn parse_meta_item(&mut self) -> P { + let nt_meta = match self.token { + token::INTERPOLATED(token::NtMeta(ref e)) => { + Some(e.clone()) + } + _ => None + }; + + match nt_meta { + Some(meta) => { self.bump(); - return e + return meta; } - _ => {} + None => {} } let lo = self.span.lo; @@ -187,29 +193,29 @@ impl<'a> ParserAttr for Parser<'a> { } } let hi = self.span.hi; - box(GC) spanned(lo, hi, ast::MetaNameValue(name, lit)) + P(spanned(lo, hi, ast::MetaNameValue(name, lit))) } token::LPAREN => { let inner_items = self.parse_meta_seq(); let hi = self.span.hi; - box(GC) spanned(lo, hi, ast::MetaList(name, inner_items)) + P(spanned(lo, hi, ast::MetaList(name, inner_items))) } _ => { let hi = self.last_span.hi; - box(GC) spanned(lo, hi, ast::MetaWord(name)) + P(spanned(lo, hi, ast::MetaWord(name))) } } } /// matches meta_seq = ( COMMASEP(meta_item) ) - fn parse_meta_seq(&mut self) -> Vec> { + fn parse_meta_seq(&mut self) -> Vec> { self.parse_seq(&token::LPAREN, &token::RPAREN, seq_sep_trailing_disallowed(token::COMMA), |p| p.parse_meta_item()).node } - fn parse_optional_meta(&mut self) -> Vec> { + fn parse_optional_meta(&mut self) -> Vec> { match self.token { token::LPAREN => self.parse_meta_seq(), _ => Vec::new() diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/parse/classify.rs index 516f22cdf4d..cdd221aca7c 100644 --- a/src/libsyntax/parse/classify.rs +++ b/src/libsyntax/parse/classify.rs @@ -13,7 +13,6 @@ // Predicates on exprs and stmts that the pretty-printer and parser use use ast; -use std::gc::Gc; /// Does this expression require a semicolon to be treated /// as a statement? The negation of this: 'can this expression @@ -22,7 +21,7 @@ use std::gc::Gc; /// if true {...} else {...} /// |x| 5 /// isn't parsed as (if true {...} else {...} | x) | 5 -pub fn expr_requires_semi_to_be_stmt(e: Gc) -> bool { +pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool { match e.node { ast::ExprIf(..) | ast::ExprMatch(..) @@ -34,25 +33,25 @@ pub fn expr_requires_semi_to_be_stmt(e: Gc) -> bool { } } -pub fn expr_is_simple_block(e: Gc) -> bool { +pub fn expr_is_simple_block(e: &ast::Expr) -> bool { match e.node { - ast::ExprBlock(block) => block.rules == ast::DefaultBlock, - _ => false + ast::ExprBlock(ref block) => block.rules == ast::DefaultBlock, + _ => false } } /// this statement requires a semicolon after it. /// note that in one case (stmt_semi), we've already /// seen the semicolon, and thus don't need another. -pub fn stmt_ends_with_semi(stmt: &ast::Stmt) -> bool { - return match stmt.node { - ast::StmtDecl(d, _) => { +pub fn stmt_ends_with_semi(stmt: &ast::Stmt_) -> bool { + match *stmt { + ast::StmtDecl(ref d, _) => { match d.node { ast::DeclLocal(_) => true, ast::DeclItem(_) => false } } - ast::StmtExpr(e, _) => { expr_requires_semi_to_be_stmt(e) } + ast::StmtExpr(ref e, _) => { expr_requires_semi_to_be_stmt(&**e) } ast::StmtSemi(..) => { false } ast::StmtMac(..) => { false } } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 585b98925cc..c4ee1b60da4 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -15,9 +15,9 @@ use codemap::{Span, CodeMap, FileMap}; use diagnostic::{SpanHandler, mk_span_handler, default_handler, Auto}; use parse::attr::ParserAttr; use parse::parser::Parser; +use ptr::P; use std::cell::RefCell; -use std::gc::Gc; use std::io::File; use std::rc::Rc; use std::str; @@ -106,7 +106,7 @@ pub fn parse_expr_from_source_str(name: String, source: String, cfg: ast::CrateConfig, sess: &ParseSess) - -> Gc { + -> P { let mut p = new_parser_from_source_str(sess, cfg, name, source); maybe_aborted(p.parse_expr(), p) } @@ -115,7 +115,7 @@ pub fn parse_item_from_source_str(name: String, source: String, cfg: ast::CrateConfig, sess: &ParseSess) - -> Option> { + -> Option> { let mut p = new_parser_from_source_str(sess, cfg, name, source); maybe_aborted(p.parse_item_with_outer_attributes(),p) } @@ -124,7 +124,7 @@ pub fn parse_meta_from_source_str(name: String, source: String, cfg: ast::CrateConfig, sess: &ParseSess) - -> Gc { + -> P { let mut p = new_parser_from_source_str(sess, cfg, name, source); maybe_aborted(p.parse_meta_item(),p) } @@ -134,7 +134,7 @@ pub fn parse_stmt_from_source_str(name: String, cfg: ast::CrateConfig, attrs: Vec , sess: &ParseSess) - -> Gc { + -> P { let mut p = new_parser_from_source_str( sess, cfg, @@ -722,7 +722,7 @@ mod test { #[test] fn path_exprs_1() { assert!(string_to_expr("a".to_string()) == - box(GC) ast::Expr{ + P(ast::Expr{ id: ast::DUMMY_NODE_ID, node: ast::ExprPath(ast::Path { span: sp(0, 1), @@ -736,12 +736,12 @@ mod test { ), }), span: sp(0, 1) - }) + })) } #[test] fn path_exprs_2 () { assert!(string_to_expr("::a::b".to_string()) == - box(GC) ast::Expr { + P(ast::Expr { id: ast::DUMMY_NODE_ID, node: ast::ExprPath(ast::Path { span: sp(0, 6), @@ -760,7 +760,7 @@ mod test { ) }), span: sp(0, 6) - }) + })) } #[should_fail] @@ -953,9 +953,9 @@ mod test { #[test] fn ret_expr() { assert!(string_to_expr("return d".to_string()) == - box(GC) ast::Expr{ + P(ast::Expr{ id: ast::DUMMY_NODE_ID, - node:ast::ExprRet(Some(box(GC) ast::Expr{ + node:ast::ExprRet(Some(P(ast::Expr{ id: ast::DUMMY_NODE_ID, node:ast::ExprPath(ast::Path{ span: sp(7, 8), @@ -969,15 +969,15 @@ mod test { ), }), span:sp(7,8) - })), + }))), span:sp(0,8) - }) + })) } #[test] fn parse_stmt_1 () { assert!(string_to_stmt("b;".to_string()) == - box(GC) Spanned{ - node: ast::StmtExpr(box(GC) ast::Expr { + P(Spanned{ + node: ast::StmtExpr(P(ast::Expr { id: ast::DUMMY_NODE_ID, node: ast::ExprPath(ast::Path { span:sp(0,1), @@ -990,9 +990,9 @@ mod test { } ), }), - span: sp(0,1)}, + span: sp(0,1)}), ast::DUMMY_NODE_ID), - span: sp(0,1)}) + span: sp(0,1)})) } @@ -1004,14 +1004,14 @@ mod test { let sess = new_parse_sess(); let mut parser = string_to_parser(&sess, "b".to_string()); assert!(parser.parse_pat() - == box(GC) ast::Pat{ + == P(ast::Pat{ id: ast::DUMMY_NODE_ID, node: ast::PatIdent(ast::BindByValue(ast::MutImmutable), Spanned{ span:sp(0, 1), node: str_to_ident("b") }, None), - span: sp(0,1)}); + span: sp(0,1)})); parser_done(parser); } @@ -1020,7 +1020,7 @@ mod test { // this test depends on the intern order of "fn" and "int" assert!(string_to_item("fn a (b : int) { b; }".to_string()) == Some( - box(GC) ast::Item{ident:str_to_ident("a"), + P(ast::Item{ident:str_to_ident("a"), attrs:Vec::new(), id: ast::DUMMY_NODE_ID, node: ast::ItemFn(ast::P(ast::FnDecl { @@ -1040,7 +1040,7 @@ mod test { }, None, ast::DUMMY_NODE_ID), span:sp(10,13) }), - pat: box(GC) ast::Pat { + pat: P(ast::Pat { id: ast::DUMMY_NODE_ID, node: ast::PatIdent( ast::BindByValue(ast::MutImmutable), @@ -1050,7 +1050,7 @@ mod test { None ), span: sp(6,7) - }, + }), id: ast::DUMMY_NODE_ID }), output: ast::P(ast::Ty{id: ast::DUMMY_NODE_ID, @@ -1071,8 +1071,8 @@ mod test { }, ast::P(ast::Block { view_items: Vec::new(), - stmts: vec!(box(GC) Spanned{ - node: ast::StmtSemi(box(GC) ast::Expr{ + stmts: vec!(P(Spanned{ + node: ast::StmtSemi(P(ast::Expr{ id: ast::DUMMY_NODE_ID, node: ast::ExprPath( ast::Path{ @@ -1090,28 +1090,28 @@ mod test { } ), }), - span: sp(17,18)}, + span: sp(17,18)}), ast::DUMMY_NODE_ID), - span: sp(17,19)}), + span: sp(17,19)})), expr: None, id: ast::DUMMY_NODE_ID, rules: ast::DefaultBlock, // no idea span: sp(15,21), })), vis: ast::Inherited, - span: sp(0,21)})); + span: sp(0,21)}))); } #[test] fn parse_exprs () { // just make sure that they parse.... string_to_expr("3 + 4".to_string()); - string_to_expr("a::z.froob(b,box(GC)(987+3))".to_string()); + string_to_expr("a::z.froob(b,&(987+3))".to_string()); } #[test] fn attrs_fix_bug () { string_to_item("pub fn mk_file_writer(path: &Path, flags: &[FileFlag]) - -> Result, String> { + -> Result, String> { #[cfg(windows)] fn wb() -> c_int { (O_WRONLY | libc::consts::os::extra::O_BINARY) as c_int diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 9ed9e626c3d..d47231bc3e2 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -21,8 +21,7 @@ use ast::{Expr, ExprLit, LitNil}; use codemap::{Span, respan}; use parse::parser; use parse::token; - -use std::gc::{Gc, GC}; +use ptr::P; /// The specific types of unsupported syntax #[deriving(PartialEq, Eq, Hash)] @@ -44,7 +43,7 @@ pub trait ParserObsoleteMethods { fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax); /// Reports an obsolete syntax non-fatal error, and returns /// a placeholder expression - fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> Gc; + fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> P; fn report(&mut self, sp: Span, kind: ObsoleteSyntax, @@ -105,9 +104,9 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> { /// Reports an obsolete syntax non-fatal error, and returns /// a placeholder expression - fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> Gc { + fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> P { self.obsolete(sp, kind); - self.mk_expr(sp.lo, sp.hi, ExprLit(box(GC) respan(sp, LitNil))) + self.mk_expr(sp.lo, sp.hi, ExprLit(P(respan(sp, LitNil)))) } fn report(&mut self, 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), - IoviItem(Gc), - IoviForeignItem(Gc), + IoviItem(P), + IoviForeignItem(P), 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 , rhs: Option >) struct ParsedItemsAndViewItems { attrs_remaining: Vec, view_items: Vec, - items: Vec>, - foreign_items: Vec> + items: Vec> , + foreign_items: Vec> } /* 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, 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, 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, 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, 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> { + pub fn maybe_parse_fixed_vstore(&mut self) -> Option> { 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 { + pub fn parse_literal_maybe_minus(&mut self) -> P { 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 { - box(GC) Expr { + pub fn mk_expr(&mut self, lo: BytePos, hi: BytePos, node: Expr_) -> P { + 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) -> ast::Expr_ { + pub fn mk_unary(&mut self, unop: ast::UnOp, expr: P) -> ast::Expr_ { ExprUnary(unop, expr) } - pub fn mk_binary(&mut self, binop: ast::BinOp, - lhs: Gc, rhs: Gc) -> ast::Expr_ { + pub fn mk_binary(&mut self, binop: ast::BinOp, lhs: P, rhs: P) -> ast::Expr_ { ExprBinary(binop, lhs, rhs) } - pub fn mk_call(&mut self, f: Gc, args: Vec>) -> ast::Expr_ { + pub fn mk_call(&mut self, f: P, args: Vec>) -> ast::Expr_ { ExprCall(f, args) } fn mk_method_call(&mut self, ident: ast::SpannedIdent, tps: Vec>, - args: Vec>) + args: Vec>) -> ast::Expr_ { ExprMethodCall(ident, tps, args) } - pub fn mk_index(&mut self, expr: Gc, idx: Gc) -> ast::Expr_ { + pub fn mk_index(&mut self, expr: P, idx: P) -> ast::Expr_ { ExprIndex(expr, idx) } - pub fn mk_field(&mut self, expr: Gc, ident: ast::SpannedIdent, + pub fn mk_field(&mut self, expr: P, ident: ast::SpannedIdent, tys: Vec>) -> ast::Expr_ { ExprField(expr, ident, tys) } - pub fn mk_tup_field(&mut self, expr: Gc, idx: codemap::Spanned, + pub fn mk_tup_field(&mut self, expr: P, idx: codemap::Spanned, tys: Vec>) -> ast::Expr_ { ExprTupField(expr, idx, tys) } pub fn mk_assign_op(&mut self, binop: ast::BinOp, - lhs: Gc, rhs: Gc) -> ast::Expr_ { + lhs: P, rhs: P) -> ast::Expr_ { ExprAssignOp(binop, lhs, rhs) } - pub fn mk_mac_expr(&mut self, lo: BytePos, hi: BytePos, m: Mac_) -> Gc { - box(GC) Expr { + pub fn mk_mac_expr(&mut self, lo: BytePos, hi: BytePos, m: Mac_) -> P { + 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 { + pub fn mk_lit_u32(&mut self, i: u32) -> P { 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 { + pub fn parse_bottom_expr(&mut self) -> P { 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 { + -> P { 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 { + pub fn parse_dot_or_call_expr(&mut self) -> P { 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) -> Gc { + pub fn parse_dot_or_call_expr_with(&mut self, e0: P) -> P { 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 { + pub fn parse_prefix_expr(&mut self) -> P { 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 { + pub fn parse_binops(&mut self) -> P { 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, - min_prec: uint) -> Gc { - if self.expr_is_complete(lhs) { return lhs; } + pub fn parse_more_binops(&mut self, lhs: P, min_prec: uint) -> P { + 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 { + pub fn parse_assign_expr(&mut self) -> P { 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 { + pub fn parse_if_expr(&mut self) -> P { 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> = None; + let mut els: Option> = 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 { + -> P { 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 { + pub fn parse_else_expr(&mut self) -> P { 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) -> Gc { + pub fn parse_for_expr(&mut self, opt_ident: Option) -> P { // Parse: `for in ` 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) -> Gc { + pub fn parse_while_expr(&mut self, opt_ident: Option) -> P { 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) -> Gc { + pub fn parse_loop_expr(&mut self, opt_ident: Option) -> P { 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 { + fn parse_match_expr(&mut self) -> P { 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 = 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 { + pub fn parse_expr(&mut self) -> P { return self.parse_expr_res(UNRESTRICTED); } /// Parse an expression, subject to the given restriction - pub fn parse_expr_res(&mut self, r: restriction) -> Gc { + pub fn parse_expr_res(&mut self, r: restriction) -> P { 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> { + fn parse_initializer(&mut self) -> Option> { 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> { + fn parse_pats(&mut self) -> Vec> { 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> , Option>, Vec> ) { + ) -> (Vec>, Option>, Vec>) { 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 { + pub fn parse_pat(&mut self) -> P { 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> = Vec::new(); + let mut args: Vec> = 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 { + fn parse_local(&mut self) -> P { 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 { + fn parse_let(&mut self) -> P { 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) -> Gc { + pub fn parse_stmt(&mut self, item_attrs: Vec) -> P { 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) -> 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) -> Gc { - box(GC) Item { + attrs: Vec) -> P { + 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>) - -> Gc { + -> P { 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> = starting_items; + let mut items: Vec> = 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) -> Gc { + attrs: Vec) -> P { 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 ) -> Gc { + attrs: Vec) -> P { 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 { + fn parse_struct_def(&mut self) -> P { let mut fields: Vec = 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 , 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> { + pub fn parse_item_with_outer_attributes(&mut self) -> Option> { let attrs = self.parse_outer_attributes(); self.parse_item(attrs) } - pub fn parse_item(&mut self, attrs: Vec ) -> Option> { + pub fn parse_item(&mut self, attrs: Vec) -> Option> { 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 { + fn parse_view_path(&mut self) -> P { 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 diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index cce14be1ba5..f113e0e6cff 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -9,15 +9,15 @@ // except according to those terms. use ast; -use ast::{P, Ident, Name, Mrk}; +use ast::{Ident, Name, Mrk}; use ext::mtwt; use parse::token; +use ptr::P; use util::interner::{RcStr, StrInterner}; use util::interner; use serialize::{Decodable, Decoder, Encodable, Encoder}; use std::fmt; -use std::gc::Gc; use std::mem; use std::path::BytesContainer; use std::rc::Rc; @@ -115,19 +115,19 @@ pub enum Token { #[deriving(Clone, Encodable, Decodable, PartialEq, Eq, Hash)] /// For interpolation during macro expansion. pub enum Nonterminal { - NtItem(Gc), + NtItem( P), NtBlock(P), - NtStmt(Gc), - NtPat( Gc), - NtExpr(Gc), - NtTy( P), + NtStmt( P), + NtPat( P), + NtExpr( P), + NtTy( P), /// See IDENT, above, for meaning of bool in NtIdent: NtIdent(Box, bool), /// Stuff inside brackets for attributes - NtMeta(Gc), + NtMeta( P), NtPath(Box), - NtTT( Gc), // needs Gc'd to break a circularity - NtMatchers(Vec ) + NtTT( P), // needs P'ed to break a circularity + NtMatchers(Vec) } impl fmt::Show for Nonterminal { -- cgit 1.4.1-3-g733a5