diff options
| author | bors <bors@rust-lang.org> | 2014-09-14 03:21:07 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-09-14 03:21:07 +0000 |
| commit | 19311b6103b49232709d301af4036dbc0021082c (patch) | |
| tree | ae5c946b1c5198c5fb4f878d79a21b872b41f945 /src/libsyntax/parse | |
| parent | 931b11549f3aab00aaaaff39cce33c0f7219b3b6 (diff) | |
| parent | 8577343f9eb1024bf77f59e281ba9f4cd1ee0aaa (diff) | |
| download | rust-19311b6103b49232709d301af4036dbc0021082c.tar.gz rust-19311b6103b49232709d301af4036dbc0021082c.zip | |
auto merge of #13316 : eddyb/rust/ast-ptr, r=brson
Replaces Gc<T> in the AST with a custom owned smart pointer, P<T>. Fixes #7929. ## Benefits * **Identity** (affinity?): sharing AST nodes is bad for the various analysis passes (e.g. one could bypass borrowck with a shared `ExprAddrOf` node taking a mutable borrow), the only reason we haven't hit any serious issues with it is because of inefficient folding passes which will always deduplicate any such shared nodes. Even if we were to switch to an arena, this would still hold, i.e. we wouldn't just use `&'a T` in the AST, but rather an wrapper (`P<'a, T>`?). * **Immutability**: `P<T>` disallows mutating its inner `T` (unless that contains an `Unsafe` interior, which won't happen in the AST), unlike `~T`. * **Efficiency**: folding can reuse allocation space for `P<T>` and `Vec<T>`, the latter even when the input and output types differ (as it would be the case with arenas or an AST with type parameters to toggle macro support). Also, various algorithms have been changed from copying `Gc<T>` to using `&T` and iterators. * **Maintainability**: there is another reason I didn't just replace `Gc<T>` with `~T`: `P<T>` provides a fixed interface (`Deref`, `and_then` and `map`) which can remain fully functional even if the implementation changes (using a special thread-local heap, for example). Moreover, switching to, e.g. `P<'a, T>` (for a contextual arena) is easy and mostly automated.
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/attr.rs | 36 | ||||
| -rw-r--r-- | src/libsyntax/parse/classify.rs | 17 | ||||
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 74 | ||||
| -rw-r--r-- | src/libsyntax/parse/obsolete.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 487 | ||||
| -rw-r--r-- | src/libsyntax/parse/token.rs | 20 |
6 files changed, 331 insertions, 312 deletions
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<ast::Attribute>, Vec<ast::Attribute>); - fn parse_meta_item(&mut self) -> Gc<ast::MetaItem>; - fn parse_meta_seq(&mut self) -> Vec<Gc<ast::MetaItem>>; - fn parse_optional_meta(&mut self) -> Vec<Gc<ast::MetaItem>>; + fn parse_meta_item(&mut self) -> P<ast::MetaItem>; + fn parse_meta_seq(&mut self) -> Vec<P<ast::MetaItem>>; + fn parse_optional_meta(&mut self) -> Vec<P<ast::MetaItem>>; } 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<ast::MetaItem> { - match self.token { - token::INTERPOLATED(token::NtMeta(e)) => { + fn parse_meta_item(&mut self) -> P<ast::MetaItem> { + 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<Gc<ast::MetaItem>> { + fn parse_meta_seq(&mut self) -> Vec<P<ast::MetaItem>> { 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<Gc<ast::MetaItem>> { + fn parse_optional_meta(&mut self) -> Vec<P<ast::MetaItem>> { 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<ast::Expr>) -> 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<ast::Expr>) -> bool { } } -pub fn expr_is_simple_block(e: Gc<ast::Expr>) -> 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..e5b6359000b 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<ast::Expr> { + -> P<ast::Expr> { 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<Gc<ast::Item>> { + -> Option<P<ast::Item>> { 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<ast::MetaItem> { + -> P<ast::MetaItem> { 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<ast::Attribute> , sess: &ParseSess) - -> Gc<ast::Stmt> { + -> P<ast::Stmt> { let mut p = new_parser_from_source_str( sess, cfg, @@ -702,7 +702,6 @@ pub fn integer_lit(s: &str, sd: &SpanHandler, sp: Span) -> ast::Lit_ { mod test { use super::*; use serialize::json; - use std::gc::GC; use codemap::{Span, BytePos, Spanned}; use owned_slice::OwnedSlice; use ast; @@ -711,6 +710,7 @@ mod test { use attr::AttrMetaMethods; use parse::parser::Parser; use parse::token::{str_to_ident}; + use ptr::P; use util::parser_testing::{string_to_tts, string_to_parser}; use util::parser_testing::{string_to_expr, string_to_item}; use util::parser_testing::string_to_stmt; @@ -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,13 +1020,13 @@ 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 { + node: ast::ItemFn(P(ast::FnDecl { inputs: vec!(ast::Arg{ - ty: ast::P(ast::Ty{id: ast::DUMMY_NODE_ID, - node: ast::TyPath(ast::Path{ + ty: P(ast::Ty{id: ast::DUMMY_NODE_ID, + node: ast::TyPath(ast::Path{ span:sp(10,13), global:false, segments: vec!( @@ -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,12 +1050,12 @@ mod test { None ), span: sp(6,7) - }, + }), id: ast::DUMMY_NODE_ID }), - output: ast::P(ast::Ty{id: ast::DUMMY_NODE_ID, - node: ast::TyNil, - span:sp(15,15)}), // not sure + output: P(ast::Ty{id: ast::DUMMY_NODE_ID, + node: ast::TyNil, + span:sp(15,15)}), // not sure cf: ast::Return, variadic: false }), @@ -1069,10 +1069,10 @@ mod test { predicates: Vec::new(), } }, - ast::P(ast::Block { + 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<Gc<Writer>, String> { + -> Result<Box<Writer>, 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<Expr>; + fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> P<Expr>; 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<Expr> { + fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> P<Expr> { 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<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 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<ast::Item>), + NtItem( P<ast::Item>), NtBlock(P<ast::Block>), - NtStmt(Gc<ast::Stmt>), - NtPat( Gc<ast::Pat>), - NtExpr(Gc<ast::Expr>), - NtTy( P<ast::Ty>), + NtStmt( P<ast::Stmt>), + NtPat( P<ast::Pat>), + NtExpr( P<ast::Expr>), + NtTy( P<ast::Ty>), /// See IDENT, above, for meaning of bool in NtIdent: NtIdent(Box<Ident>, bool), /// Stuff inside brackets for attributes - NtMeta(Gc<ast::MetaItem>), + NtMeta( P<ast::MetaItem>), NtPath(Box<ast::Path>), - NtTT( Gc<ast::TokenTree>), // needs Gc'd to break a circularity - NtMatchers(Vec<ast::Matcher> ) + NtTT( P<ast::TokenTree>), // needs P'ed to break a circularity + NtMatchers(Vec<ast::Matcher>) } impl fmt::Show for Nonterminal { |
