syntax: Move the AST from @T to Gc<T>

This commit is contained in:
Alex Crichton 2014-05-16 00:16:13 -07:00
parent 531ed3d599
commit 53ad426e92
41 changed files with 1269 additions and 1158 deletions

View file

@ -21,15 +21,16 @@ use std::fmt;
use std::fmt::Show; use std::fmt::Show;
use std::option::Option; use std::option::Option;
use std::rc::Rc; use std::rc::Rc;
use std::gc::Gc;
use serialize::{Encodable, Decodable, Encoder, Decoder}; use serialize::{Encodable, Decodable, Encoder, Decoder};
/// A pointer abstraction. FIXME(eddyb) #10676 use Rc<T> in the future. /// A pointer abstraction. FIXME(eddyb) #10676 use Rc<T> in the future.
pub type P<T> = @T; pub type P<T> = Gc<T>;
#[allow(non_snake_case_functions)] #[allow(non_snake_case_functions)]
/// Construct a P<T> from a T value. /// Construct a P<T> from a T value.
pub fn P<T: 'static>(value: T) -> P<T> { pub fn P<T: 'static>(value: T) -> P<T> {
@value box(GC) value
} }
// FIXME #6993: in librustc, uses of "ident" should be replaced // FIXME #6993: in librustc, uses of "ident" should be replaced
@ -217,7 +218,7 @@ pub enum DefRegion {
// The set of MetaItems that define the compilation environment of the crate, // The set of MetaItems that define the compilation environment of the crate,
// used to drive conditional compilation // used to drive conditional compilation
pub type CrateConfig = Vec<@MetaItem> ; pub type CrateConfig = Vec<Gc<MetaItem>>;
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct Crate { pub struct Crate {
@ -232,7 +233,7 @@ pub type MetaItem = Spanned<MetaItem_>;
#[deriving(Clone, Encodable, Decodable, Eq, Hash)] #[deriving(Clone, Encodable, Decodable, Eq, Hash)]
pub enum MetaItem_ { pub enum MetaItem_ {
MetaWord(InternedString), MetaWord(InternedString),
MetaList(InternedString, Vec<@MetaItem> ), MetaList(InternedString, Vec<Gc<MetaItem>>),
MetaNameValue(InternedString, Lit), MetaNameValue(InternedString, Lit),
} }
@ -264,8 +265,8 @@ impl PartialEq for MetaItem_ {
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct Block { pub struct Block {
pub view_items: Vec<ViewItem>, pub view_items: Vec<ViewItem>,
pub stmts: Vec<@Stmt>, pub stmts: Vec<Gc<Stmt>>,
pub expr: Option<@Expr>, pub expr: Option<Gc<Expr>>,
pub id: NodeId, pub id: NodeId,
pub rules: BlockCheckMode, pub rules: BlockCheckMode,
pub span: Span, pub span: Span,
@ -281,7 +282,7 @@ pub struct Pat {
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct FieldPat { pub struct FieldPat {
pub ident: Ident, pub ident: Ident,
pub pat: @Pat, pub pat: Gc<Pat>,
} }
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
@ -301,18 +302,18 @@ pub enum Pat_ {
// which it is. The resolver determines this, and // which it is. The resolver determines this, and
// records this pattern's NodeId in an auxiliary // records this pattern's NodeId in an auxiliary
// set (of "pat_idents that refer to nullary enums") // set (of "pat_idents that refer to nullary enums")
PatIdent(BindingMode, Path, Option<@Pat>), PatIdent(BindingMode, Path, Option<Gc<Pat>>),
PatEnum(Path, Option<Vec<@Pat> >), /* "none" means a * pattern where PatEnum(Path, Option<Vec<Gc<Pat>>>), /* "none" means a * pattern where
* we don't bind the fields to names */ * we don't bind the fields to names */
PatStruct(Path, Vec<FieldPat> , bool), PatStruct(Path, Vec<FieldPat>, bool),
PatTup(Vec<@Pat> ), PatTup(Vec<Gc<Pat>>),
PatBox(@Pat), PatBox(Gc<Pat>),
PatRegion(@Pat), // reference pattern PatRegion(Gc<Pat>), // reference pattern
PatLit(@Expr), PatLit(Gc<Expr>),
PatRange(@Expr, @Expr), PatRange(Gc<Expr>, Gc<Expr>),
// [a, b, ..i, y, z] is represented as // [a, b, ..i, y, z] is represented as
// PatVec(~[a, b], Some(i), ~[y, z]) // PatVec(~[a, b], Some(i), ~[y, z])
PatVec(Vec<@Pat> , Option<@Pat>, Vec<@Pat> ), PatVec(Vec<Gc<Pat>>, Option<Gc<Pat>>, Vec<Gc<Pat>>),
PatMac(Mac), PatMac(Mac),
} }
@ -365,13 +366,13 @@ pub type Stmt = Spanned<Stmt_>;
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum Stmt_ { pub enum Stmt_ {
// could be an item or a local (let) binding: // could be an item or a local (let) binding:
StmtDecl(@Decl, NodeId), StmtDecl(Gc<Decl>, NodeId),
// expr without trailing semi-colon (must have unit type): // expr without trailing semi-colon (must have unit type):
StmtExpr(@Expr, NodeId), StmtExpr(Gc<Expr>, NodeId),
// expr with trailing semi-colon (may have any type): // expr with trailing semi-colon (may have any type):
StmtSemi(@Expr, NodeId), StmtSemi(Gc<Expr>, NodeId),
// bool: is there a trailing sem-colon? // bool: is there a trailing sem-colon?
StmtMac(Mac, bool), StmtMac(Mac, bool),
@ -391,8 +392,8 @@ pub enum LocalSource {
#[deriving(PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct Local { pub struct Local {
pub ty: P<Ty>, pub ty: P<Ty>,
pub pat: @Pat, pub pat: Gc<Pat>,
pub init: Option<@Expr>, pub init: Option<Gc<Expr>>,
pub id: NodeId, pub id: NodeId,
pub span: Span, pub span: Span,
pub source: LocalSource, pub source: LocalSource,
@ -403,23 +404,23 @@ pub type Decl = Spanned<Decl_>;
#[deriving(PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum Decl_ { pub enum Decl_ {
// a local (let) binding: // a local (let) binding:
DeclLocal(@Local), DeclLocal(Gc<Local>),
// an item binding: // an item binding:
DeclItem(@Item), DeclItem(Gc<Item>),
} }
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct Arm { pub struct Arm {
pub attrs: Vec<Attribute>, pub attrs: Vec<Attribute>,
pub pats: Vec<@Pat>, pub pats: Vec<Gc<Pat>>,
pub guard: Option<@Expr>, pub guard: Option<Gc<Expr>>,
pub body: @Expr, pub body: Gc<Expr>,
} }
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct Field { pub struct Field {
pub ident: SpannedIdent, pub ident: SpannedIdent,
pub expr: @Expr, pub expr: Gc<Expr>,
pub span: Span, pub span: Span,
} }
@ -446,56 +447,56 @@ pub struct Expr {
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum Expr_ { pub enum Expr_ {
ExprVstore(@Expr, ExprVstore), ExprVstore(Gc<Expr>, ExprVstore),
// First expr is the place; second expr is the value. // First expr is the place; second expr is the value.
ExprBox(@Expr, @Expr), ExprBox(Gc<Expr>, Gc<Expr>),
ExprVec(Vec<@Expr>), ExprVec(Vec<Gc<Expr>>),
ExprCall(@Expr, Vec<@Expr>), ExprCall(Gc<Expr>, Vec<Gc<Expr>>),
ExprMethodCall(SpannedIdent, Vec<P<Ty>>, Vec<@Expr>), ExprMethodCall(SpannedIdent, Vec<P<Ty>>, Vec<Gc<Expr>>),
ExprTup(Vec<@Expr>), ExprTup(Vec<Gc<Expr>>),
ExprBinary(BinOp, @Expr, @Expr), ExprBinary(BinOp, Gc<Expr>, Gc<Expr>),
ExprUnary(UnOp, @Expr), ExprUnary(UnOp, Gc<Expr>),
ExprLit(@Lit), ExprLit(Gc<Lit>),
ExprCast(@Expr, P<Ty>), ExprCast(Gc<Expr>, P<Ty>),
ExprIf(@Expr, P<Block>, Option<@Expr>), ExprIf(Gc<Expr>, P<Block>, Option<Gc<Expr>>),
ExprWhile(@Expr, P<Block>), ExprWhile(Gc<Expr>, P<Block>),
// FIXME #6993: change to Option<Name> // FIXME #6993: change to Option<Name>
ExprForLoop(@Pat, @Expr, P<Block>, Option<Ident>), ExprForLoop(Gc<Pat>, Gc<Expr>, P<Block>, Option<Ident>),
// Conditionless loop (can be exited with break, cont, or ret) // Conditionless loop (can be exited with break, cont, or ret)
// FIXME #6993: change to Option<Name> // FIXME #6993: change to Option<Name>
ExprLoop(P<Block>, Option<Ident>), ExprLoop(P<Block>, Option<Ident>),
ExprMatch(@Expr, Vec<Arm>), ExprMatch(Gc<Expr>, Vec<Arm>),
ExprFnBlock(P<FnDecl>, P<Block>), ExprFnBlock(P<FnDecl>, P<Block>),
ExprProc(P<FnDecl>, P<Block>), ExprProc(P<FnDecl>, P<Block>),
ExprBlock(P<Block>), ExprBlock(P<Block>),
ExprAssign(@Expr, @Expr), ExprAssign(Gc<Expr>, Gc<Expr>),
ExprAssignOp(BinOp, @Expr, @Expr), ExprAssignOp(BinOp, Gc<Expr>, Gc<Expr>),
ExprField(@Expr, Ident, Vec<P<Ty>>), ExprField(Gc<Expr>, Ident, Vec<P<Ty>>),
ExprIndex(@Expr, @Expr), ExprIndex(Gc<Expr>, Gc<Expr>),
/// Expression that looks like a "name". For example, /// Expression that looks like a "name". For example,
/// `std::slice::from_elem::<uint>` is an ExprPath that's the "name" part /// `std::slice::from_elem::<uint>` is an ExprPath that's the "name" part
/// of a function call. /// of a function call.
ExprPath(Path), ExprPath(Path),
ExprAddrOf(Mutability, @Expr), ExprAddrOf(Mutability, Gc<Expr>),
ExprBreak(Option<Ident>), ExprBreak(Option<Ident>),
ExprAgain(Option<Ident>), ExprAgain(Option<Ident>),
ExprRet(Option<@Expr>), ExprRet(Option<Gc<Expr>>),
ExprInlineAsm(InlineAsm), ExprInlineAsm(InlineAsm),
ExprMac(Mac), ExprMac(Mac),
// A struct literal expression. // A struct literal expression.
ExprStruct(Path, Vec<Field> , Option<@Expr> /* base */), ExprStruct(Path, Vec<Field> , Option<Gc<Expr>> /* base */),
// A vector literal constructed from one repeated element. // A vector literal constructed from one repeated element.
ExprRepeat(@Expr /* element */, @Expr /* count */), ExprRepeat(Gc<Expr> /* element */, Gc<Expr> /* count */),
// No-op: used solely so we can pretty-print faithfully // No-op: used solely so we can pretty-print faithfully
ExprParen(@Expr) ExprParen(Gc<Expr>)
} }
// When the main rust parser encounters a syntax-extension invocation, it // When the main rust parser encounters a syntax-extension invocation, it
@ -667,7 +668,7 @@ pub struct TypeMethod {
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum TraitMethod { pub enum TraitMethod {
Required(TypeMethod), Required(TypeMethod),
Provided(@Method), Provided(Gc<Method>),
} }
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
@ -782,16 +783,16 @@ pub enum Ty_ {
TyBox(P<Ty>), TyBox(P<Ty>),
TyUniq(P<Ty>), TyUniq(P<Ty>),
TyVec(P<Ty>), TyVec(P<Ty>),
TyFixedLengthVec(P<Ty>, @Expr), TyFixedLengthVec(P<Ty>, Gc<Expr>),
TyPtr(MutTy), TyPtr(MutTy),
TyRptr(Option<Lifetime>, MutTy), TyRptr(Option<Lifetime>, MutTy),
TyClosure(@ClosureTy, Option<Lifetime>), TyClosure(Gc<ClosureTy>, Option<Lifetime>),
TyProc(@ClosureTy), TyProc(Gc<ClosureTy>),
TyBareFn(@BareFnTy), TyBareFn(Gc<BareFnTy>),
TyUnboxedFn(@UnboxedFnTy), TyUnboxedFn(Gc<UnboxedFnTy>),
TyTup(Vec<P<Ty>> ), TyTup(Vec<P<Ty>> ),
TyPath(Path, Option<OwnedSlice<TyParamBound>>, NodeId), // for #7264; see above TyPath(Path, Option<OwnedSlice<TyParamBound>>, NodeId), // for #7264; see above
TyTypeof(@Expr), TyTypeof(Gc<Expr>),
// TyInfer means the type should be inferred instead of it having been // TyInfer means the type should be inferred instead of it having been
// specified. This can appear anywhere in a type. // specified. This can appear anywhere in a type.
TyInfer, TyInfer,
@ -808,8 +809,8 @@ pub struct InlineAsm {
pub asm: InternedString, pub asm: InternedString,
pub asm_str_style: StrStyle, pub asm_str_style: StrStyle,
pub clobbers: InternedString, pub clobbers: InternedString,
pub inputs: Vec<(InternedString, @Expr)>, pub inputs: Vec<(InternedString, Gc<Expr>)>,
pub outputs: Vec<(InternedString, @Expr)>, pub outputs: Vec<(InternedString, Gc<Expr>)>,
pub volatile: bool, pub volatile: bool,
pub alignstack: bool, pub alignstack: bool,
pub dialect: AsmDialect pub dialect: AsmDialect
@ -818,7 +819,7 @@ pub struct InlineAsm {
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct Arg { pub struct Arg {
pub ty: P<Ty>, pub ty: P<Ty>,
pub pat: @Pat, pub pat: Gc<Pat>,
pub id: NodeId, pub id: NodeId,
} }
@ -832,7 +833,7 @@ impl Arg {
node: TyInfer, node: TyInfer,
span: DUMMY_SP, span: DUMMY_SP,
}), }),
pat: @Pat { pat: box(GC) Pat {
id: DUMMY_NODE_ID, id: DUMMY_NODE_ID,
node: PatIdent(BindByValue(mutability), path, None), node: PatIdent(BindByValue(mutability), path, None),
span: span span: span
@ -903,14 +904,14 @@ pub struct Mod {
/// to the last token in the external file. /// to the last token in the external file.
pub inner: Span, pub inner: Span,
pub view_items: Vec<ViewItem>, pub view_items: Vec<ViewItem>,
pub items: Vec<@Item>, pub items: Vec<Gc<Item>>,
} }
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct ForeignMod { pub struct ForeignMod {
pub abi: Abi, pub abi: Abi,
pub view_items: Vec<ViewItem>, pub view_items: Vec<ViewItem>,
pub items: Vec<@ForeignItem>, pub items: Vec<Gc<ForeignItem>>,
} }
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
@ -922,7 +923,7 @@ pub struct VariantArg {
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum VariantKind { pub enum VariantKind {
TupleVariantKind(Vec<VariantArg>), TupleVariantKind(Vec<VariantArg>),
StructVariantKind(@StructDef), StructVariantKind(Gc<StructDef>),
} }
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
@ -936,7 +937,7 @@ pub struct Variant_ {
pub attrs: Vec<Attribute>, pub attrs: Vec<Attribute>,
pub kind: VariantKind, pub kind: VariantKind,
pub id: NodeId, pub id: NodeId,
pub disr_expr: Option<@Expr>, pub disr_expr: Option<Gc<Expr>>,
pub vis: Visibility, pub vis: Visibility,
} }
@ -984,7 +985,7 @@ pub enum ViewItem_ {
// (containing arbitrary characters) from which to fetch the crate sources // (containing arbitrary characters) from which to fetch the crate sources
// For example, extern crate whatever = "github.com/mozilla/rust" // For example, extern crate whatever = "github.com/mozilla/rust"
ViewItemExternCrate(Ident, Option<(InternedString,StrStyle)>, NodeId), ViewItemExternCrate(Ident, Option<(InternedString,StrStyle)>, NodeId),
ViewItemUse(@ViewPath), ViewItemUse(Gc<ViewPath>),
} }
// Meta-data associated with an item // Meta-data associated with an item
@ -1007,7 +1008,7 @@ pub struct AttrId(pub uint);
pub struct Attribute_ { pub struct Attribute_ {
pub id: AttrId, pub id: AttrId,
pub style: AttrStyle, pub style: AttrStyle,
pub value: @MetaItem, pub value: Gc<MetaItem>,
pub is_sugared_doc: bool, pub is_sugared_doc: bool,
} }
@ -1105,18 +1106,18 @@ pub struct Item {
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum Item_ { pub enum Item_ {
ItemStatic(P<Ty>, Mutability, @Expr), ItemStatic(P<Ty>, Mutability, Gc<Expr>),
ItemFn(P<FnDecl>, FnStyle, Abi, Generics, P<Block>), ItemFn(P<FnDecl>, FnStyle, Abi, Generics, P<Block>),
ItemMod(Mod), ItemMod(Mod),
ItemForeignMod(ForeignMod), ItemForeignMod(ForeignMod),
ItemTy(P<Ty>, Generics), ItemTy(P<Ty>, Generics),
ItemEnum(EnumDef, Generics), ItemEnum(EnumDef, Generics),
ItemStruct(@StructDef, Generics), ItemStruct(Gc<StructDef>, Generics),
ItemTrait(Generics, Sized, Vec<TraitRef> , Vec<TraitMethod> ), ItemTrait(Generics, Sized, Vec<TraitRef> , Vec<TraitMethod> ),
ItemImpl(Generics, ItemImpl(Generics,
Option<TraitRef>, // (optional) trait this impl implements Option<TraitRef>, // (optional) trait this impl implements
P<Ty>, // self P<Ty>, // self
Vec<@Method> ), Vec<Gc<Method>>),
// a macro invocation (which includes macro definition) // a macro invocation (which includes macro definition)
ItemMac(Mac), ItemMac(Mac),
} }
@ -1142,9 +1143,9 @@ pub enum ForeignItem_ {
// that we trans. // that we trans.
#[deriving(PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum InlinedItem { pub enum InlinedItem {
IIItem(@Item), IIItem(Gc<Item>),
IIMethod(DefId /* impl id */, bool /* is provided */, @Method), IIMethod(DefId /* impl id */, bool /* is provided */, Gc<Method>),
IIForeign(@ForeignItem), IIForeign(Gc<ForeignItem>),
} }
#[cfg(test)] #[cfg(test)]

View file

@ -20,9 +20,9 @@ use util::small_vector::SmallVector;
use std::cell::RefCell; use std::cell::RefCell;
use std::fmt; use std::fmt;
use std::gc::Gc;
use std::iter; use std::iter;
use std::slice; use std::slice;
use std::string::String;
#[deriving(Clone, PartialEq)] #[deriving(Clone, PartialEq)]
pub enum PathElem { pub enum PathElem {
@ -94,22 +94,22 @@ pub fn path_to_str<PI: Iterator<PathElem>>(mut path: PI) -> String {
#[deriving(Clone)] #[deriving(Clone)]
pub enum Node { pub enum Node {
NodeItem(@Item), NodeItem(Gc<Item>),
NodeForeignItem(@ForeignItem), NodeForeignItem(Gc<ForeignItem>),
NodeTraitMethod(@TraitMethod), NodeTraitMethod(Gc<TraitMethod>),
NodeMethod(@Method), NodeMethod(Gc<Method>),
NodeVariant(P<Variant>), NodeVariant(P<Variant>),
NodeExpr(@Expr), NodeExpr(Gc<Expr>),
NodeStmt(@Stmt), NodeStmt(Gc<Stmt>),
NodeArg(@Pat), NodeArg(Gc<Pat>),
NodeLocal(@Pat), NodeLocal(Gc<Pat>),
NodePat(@Pat), NodePat(Gc<Pat>),
NodeBlock(P<Block>), NodeBlock(P<Block>),
/// NodeStructCtor represents a tuple struct. /// NodeStructCtor represents a tuple struct.
NodeStructCtor(@StructDef), NodeStructCtor(Gc<StructDef>),
NodeLifetime(@Lifetime), NodeLifetime(Gc<Lifetime>),
} }
// The odd layout is to bring down the total size. // The odd layout is to bring down the total size.
@ -119,19 +119,19 @@ enum MapEntry {
NotPresent, NotPresent,
// All the node types, with a parent ID. // All the node types, with a parent ID.
EntryItem(NodeId, @Item), EntryItem(NodeId, Gc<Item>),
EntryForeignItem(NodeId, @ForeignItem), EntryForeignItem(NodeId, Gc<ForeignItem>),
EntryTraitMethod(NodeId, @TraitMethod), EntryTraitMethod(NodeId, Gc<TraitMethod>),
EntryMethod(NodeId, @Method), EntryMethod(NodeId, Gc<Method>),
EntryVariant(NodeId, P<Variant>), EntryVariant(NodeId, P<Variant>),
EntryExpr(NodeId, @Expr), EntryExpr(NodeId, Gc<Expr>),
EntryStmt(NodeId, @Stmt), EntryStmt(NodeId, Gc<Stmt>),
EntryArg(NodeId, @Pat), EntryArg(NodeId, Gc<Pat>),
EntryLocal(NodeId, @Pat), EntryLocal(NodeId, Gc<Pat>),
EntryPat(NodeId, @Pat), EntryPat(NodeId, Gc<Pat>),
EntryBlock(NodeId, P<Block>), EntryBlock(NodeId, P<Block>),
EntryStructCtor(NodeId, @StructDef), EntryStructCtor(NodeId, Gc<StructDef>),
EntryLifetime(NodeId, @Lifetime), EntryLifetime(NodeId, Gc<Lifetime>),
// Roots for node trees. // Roots for node trees.
RootCrate, RootCrate,
@ -262,14 +262,14 @@ impl Map {
} }
} }
pub fn expect_item(&self, id: NodeId) -> @Item { pub fn expect_item(&self, id: NodeId) -> Gc<Item> {
match self.find(id) { match self.find(id) {
Some(NodeItem(item)) => item, Some(NodeItem(item)) => item,
_ => fail!("expected item, found {}", self.node_to_str(id)) _ => fail!("expected item, found {}", self.node_to_str(id))
} }
} }
pub fn expect_struct(&self, id: NodeId) -> @StructDef { pub fn expect_struct(&self, id: NodeId) -> Gc<StructDef> {
match self.find(id) { match self.find(id) {
Some(NodeItem(i)) => { Some(NodeItem(i)) => {
match i.node { match i.node {
@ -294,7 +294,7 @@ impl Map {
} }
} }
pub fn expect_foreign_item(&self, id: NodeId) -> @ForeignItem { pub fn expect_foreign_item(&self, id: NodeId) -> Gc<ForeignItem> {
match self.find(id) { match self.find(id) {
Some(NodeForeignItem(item)) => item, Some(NodeForeignItem(item)) => item,
_ => fail!("expected foreign item, found {}", self.node_to_str(id)) _ => fail!("expected foreign item, found {}", self.node_to_str(id))
@ -457,11 +457,11 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
self.fold_ops.new_span(span) self.fold_ops.new_span(span)
} }
fn fold_item(&mut self, i: @Item) -> SmallVector<@Item> { fn fold_item(&mut self, i: Gc<Item>) -> SmallVector<Gc<Item>> {
let parent = self.parent; let parent = self.parent;
self.parent = DUMMY_NODE_ID; self.parent = DUMMY_NODE_ID;
let i = fold::noop_fold_item(i, self).expect_one("expected one item"); let i = fold::noop_fold_item(&*i, self).expect_one("expected one item");
assert_eq!(self.parent, i.id); assert_eq!(self.parent, i.id);
match i.node { match i.node {
@ -476,16 +476,17 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
} }
} }
ItemForeignMod(ref nm) => { ItemForeignMod(ref nm) => {
for &nitem in nm.items.iter() { for nitem in nm.items.iter() {
self.insert(nitem.id, EntryForeignItem(self.parent, nitem)); self.insert(nitem.id, EntryForeignItem(self.parent,
nitem.clone()));
} }
} }
ItemStruct(struct_def, _) => { ItemStruct(ref struct_def, _) => {
// If this is a tuple-like struct, register the constructor. // If this is a tuple-like struct, register the constructor.
match struct_def.ctor_id { match struct_def.ctor_id {
Some(ctor_id) => { Some(ctor_id) => {
self.insert(ctor_id, EntryStructCtor(self.parent, self.insert(ctor_id, EntryStructCtor(self.parent,
struct_def)); struct_def.clone()));
} }
None => {} None => {}
} }
@ -499,11 +500,11 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
match *tm { match *tm {
Required(ref m) => { Required(ref m) => {
self.insert(m.id, EntryTraitMethod(self.parent, self.insert(m.id, EntryTraitMethod(self.parent,
@(*tm).clone())); box(GC) (*tm).clone()));
} }
Provided(m) => { Provided(m) => {
self.insert(m.id, EntryTraitMethod(self.parent, self.insert(m.id, EntryTraitMethod(self.parent,
@Provided(m))); box(GC) Provided(m)));
} }
} }
} }
@ -517,7 +518,7 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
SmallVector::one(i) SmallVector::one(i)
} }
fn fold_pat(&mut self, pat: @Pat) -> @Pat { fn fold_pat(&mut self, pat: Gc<Pat>) -> Gc<Pat> {
let pat = fold::noop_fold_pat(pat, self); let pat = fold::noop_fold_pat(pat, self);
match pat.node { match pat.node {
PatIdent(..) => { PatIdent(..) => {
@ -532,7 +533,7 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
pat pat
} }
fn fold_expr(&mut self, expr: @Expr) -> @Expr { fn fold_expr(&mut self, expr: Gc<Expr>) -> Gc<Expr> {
let expr = fold::noop_fold_expr(expr, self); let expr = fold::noop_fold_expr(expr, self);
self.insert(expr.id, EntryExpr(self.parent, expr)); self.insert(expr.id, EntryExpr(self.parent, expr));
@ -540,9 +541,9 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
expr expr
} }
fn fold_stmt(&mut self, stmt: &Stmt) -> SmallVector<@Stmt> { fn fold_stmt(&mut self, stmt: &Stmt) -> SmallVector<Gc<Stmt>> {
let stmt = fold::noop_fold_stmt(stmt, self).expect_one("expected one statement"); let stmt = fold::noop_fold_stmt(stmt, self).expect_one("expected one statement");
self.insert(ast_util::stmt_id(stmt), EntryStmt(self.parent, stmt)); self.insert(ast_util::stmt_id(&*stmt), EntryStmt(self.parent, stmt));
SmallVector::one(stmt) SmallVector::one(stmt)
} }
@ -555,10 +556,10 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
m m
} }
fn fold_method(&mut self, m: @Method) -> @Method { fn fold_method(&mut self, m: Gc<Method>) -> Gc<Method> {
let parent = self.parent; let parent = self.parent;
self.parent = DUMMY_NODE_ID; self.parent = DUMMY_NODE_ID;
let m = fold::noop_fold_method(m, self); let m = fold::noop_fold_method(&*m, self);
assert_eq!(self.parent, m.id); assert_eq!(self.parent, m.id);
self.parent = parent; self.parent = parent;
m m
@ -580,7 +581,7 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
fn fold_lifetime(&mut self, lifetime: &Lifetime) -> Lifetime { fn fold_lifetime(&mut self, lifetime: &Lifetime) -> Lifetime {
let lifetime = fold::noop_fold_lifetime(lifetime, self); let lifetime = fold::noop_fold_lifetime(lifetime, self);
self.insert(lifetime.id, EntryLifetime(self.parent, @lifetime)); self.insert(lifetime.id, EntryLifetime(self.parent, box(GC) lifetime));
lifetime lifetime
} }
} }
@ -643,7 +644,7 @@ pub fn map_decoded_item<F: FoldOps>(map: &Map,
IIItem(_) => {} IIItem(_) => {}
IIMethod(impl_did, is_provided, m) => { IIMethod(impl_did, is_provided, m) => {
let entry = if is_provided { let entry = if is_provided {
EntryTraitMethod(cx.parent, @Provided(m)) EntryTraitMethod(cx.parent, box(GC) Provided(m))
} else { } else {
EntryMethod(cx.parent, m) EntryMethod(cx.parent, m)
}; };
@ -701,28 +702,28 @@ fn node_id_to_str(map: &Map, id: NodeId) -> String {
token::get_ident(variant.node.name), token::get_ident(variant.node.name),
map.path_to_str(id), id)).to_string() map.path_to_str(id), id)).to_string()
} }
Some(NodeExpr(expr)) => { Some(NodeExpr(ref expr)) => {
(format!("expr {} (id={})", (format!("expr {} (id={})",
pprust::expr_to_str(expr), id)).to_string() pprust::expr_to_str(&**expr), id)).to_string()
} }
Some(NodeStmt(stmt)) => { Some(NodeStmt(ref stmt)) => {
(format!("stmt {} (id={})", (format!("stmt {} (id={})",
pprust::stmt_to_str(stmt), id)).to_string() pprust::stmt_to_str(&**stmt), id)).to_string()
} }
Some(NodeArg(pat)) => { Some(NodeArg(ref pat)) => {
(format!("arg {} (id={})", (format!("arg {} (id={})",
pprust::pat_to_str(pat), id)).to_string() pprust::pat_to_str(&**pat), id)).to_string()
} }
Some(NodeLocal(pat)) => { Some(NodeLocal(ref pat)) => {
(format!("local {} (id={})", (format!("local {} (id={})",
pprust::pat_to_str(pat), id)).to_string() pprust::pat_to_str(&**pat), id)).to_string()
} }
Some(NodePat(pat)) => { Some(NodePat(ref pat)) => {
(format!("pat {} (id={})", pprust::pat_to_str(pat), id)).to_string() (format!("pat {} (id={})", pprust::pat_to_str(&**pat), id)).to_string()
} }
Some(NodeBlock(block)) => { Some(NodeBlock(ref block)) => {
(format!("block {} (id={})", (format!("block {} (id={})",
pprust::block_to_str(block), id)).to_string() pprust::block_to_str(&**block), id)).to_string()
} }
Some(NodeStructCtor(_)) => { Some(NodeStructCtor(_)) => {
(format!("struct_ctor {} (id={})", (format!("struct_ctor {} (id={})",
@ -730,7 +731,7 @@ fn node_id_to_str(map: &Map, id: NodeId) -> String {
} }
Some(NodeLifetime(ref l)) => { Some(NodeLifetime(ref l)) => {
(format!("lifetime {} (id={})", (format!("lifetime {} (id={})",
pprust::lifetime_to_str(*l), id)).to_string() pprust::lifetime_to_str(&**l), id)).to_string()
} }
None => { None => {
(format!("unknown node (id={})", id)).to_string() (format!("unknown node (id={})", id)).to_string()

View file

@ -21,7 +21,7 @@ use visit;
use std::cell::Cell; use std::cell::Cell;
use std::cmp; use std::cmp;
use std::string::String; use std::gc::Gc;
use std::u32; use std::u32;
pub fn path_name_i(idents: &[Ident]) -> String { pub fn path_name_i(idents: &[Ident]) -> String {
@ -93,7 +93,7 @@ pub fn is_shift_binop(b: BinOp) -> bool {
pub fn unop_to_str(op: UnOp) -> &'static str { pub fn unop_to_str(op: UnOp) -> &'static str {
match op { match op {
UnBox => "@", UnBox => "box(GC) ",
UnUniq => "box() ", UnUniq => "box() ",
UnDeref => "*", UnDeref => "*",
UnNot => "!", UnNot => "!",
@ -101,7 +101,7 @@ pub fn unop_to_str(op: UnOp) -> &'static str {
} }
} }
pub fn is_path(e: @Expr) -> bool { pub fn is_path(e: Gc<Expr>) -> bool {
return match e.node { ExprPath(_) => true, _ => false }; return match e.node { ExprPath(_) => true, _ => false };
} }
@ -181,11 +181,11 @@ pub fn float_ty_to_str(t: FloatTy) -> String {
} }
} }
pub fn is_call_expr(e: @Expr) -> bool { pub fn is_call_expr(e: Gc<Expr>) -> bool {
match e.node { ExprCall(..) => true, _ => false } match e.node { ExprCall(..) => true, _ => false }
} }
pub fn block_from_expr(e: @Expr) -> P<Block> { pub fn block_from_expr(e: Gc<Expr>) -> P<Block> {
P(Block { P(Block {
view_items: Vec::new(), view_items: Vec::new(),
stmts: Vec::new(), stmts: Vec::new(),
@ -210,8 +210,8 @@ pub fn ident_to_path(s: Span, identifier: Ident) -> Path {
} }
} }
pub fn ident_to_pat(id: NodeId, s: Span, i: Ident) -> @Pat { pub fn ident_to_pat(id: NodeId, s: Span, i: Ident) -> Gc<Pat> {
@ast::Pat { id: id, box(GC) ast::Pat { id: id,
node: PatIdent(BindByValue(MutImmutable), ident_to_path(s, i), None), node: PatIdent(BindByValue(MutImmutable), ident_to_path(s, i), None),
span: s } span: s }
} }
@ -229,7 +229,7 @@ pub fn is_unguarded(a: &Arm) -> bool {
} }
} }
pub fn unguarded_pat(a: &Arm) -> Option<Vec<@Pat> > { pub fn unguarded_pat(a: &Arm) -> Option<Vec<Gc<Pat>>> {
if is_unguarded(a) { if is_unguarded(a) {
Some(/* FIXME (#2543) */ a.pats.clone()) Some(/* FIXME (#2543) */ a.pats.clone())
} else { } else {
@ -254,7 +254,7 @@ pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: &Ty) -> Ident {
token::gensym_ident(pretty.as_slice()) token::gensym_ident(pretty.as_slice())
} }
pub fn public_methods(ms: Vec<@Method> ) -> Vec<@Method> { pub fn public_methods(ms: Vec<Gc<Method>> ) -> Vec<Gc<Method>> {
ms.move_iter().filter(|m| { ms.move_iter().filter(|m| {
match m.vis { match m.vis {
Public => true, Public => true,
@ -285,7 +285,7 @@ pub fn trait_method_to_ty_method(method: &TraitMethod) -> TypeMethod {
} }
pub fn split_trait_methods(trait_methods: &[TraitMethod]) pub fn split_trait_methods(trait_methods: &[TraitMethod])
-> (Vec<TypeMethod> , Vec<@Method> ) { -> (Vec<TypeMethod> , Vec<Gc<Method>> ) {
let mut reqd = Vec::new(); let mut reqd = Vec::new();
let mut provd = Vec::new(); let mut provd = Vec::new();
for trt_method in trait_methods.iter() { for trt_method in trait_methods.iter() {
@ -610,7 +610,7 @@ pub fn compute_id_range_for_fn_body(fk: &visit::FnKind,
visitor.result.get() visitor.result.get()
} }
pub fn is_item_impl(item: @ast::Item) -> bool { pub fn is_item_impl(item: Gc<ast::Item>) -> bool {
match item.node { match item.node {
ItemImpl(..) => true, ItemImpl(..) => true,
_ => false _ => false
@ -623,20 +623,20 @@ pub fn walk_pat(pat: &Pat, it: |&Pat| -> bool) -> bool {
} }
match pat.node { match pat.node {
PatIdent(_, _, Some(p)) => walk_pat(p, it), PatIdent(_, _, Some(ref p)) => walk_pat(&**p, it),
PatStruct(_, ref fields, _) => { PatStruct(_, ref fields, _) => {
fields.iter().advance(|f| walk_pat(f.pat, |p| it(p))) fields.iter().advance(|f| walk_pat(&*f.pat, |p| it(p)))
} }
PatEnum(_, Some(ref s)) | PatTup(ref s) => { PatEnum(_, Some(ref s)) | PatTup(ref s) => {
s.iter().advance(|&p| walk_pat(p, |p| it(p))) s.iter().advance(|p| walk_pat(&**p, |p| it(p)))
} }
PatBox(s) | PatRegion(s) => { PatBox(ref s) | PatRegion(ref s) => {
walk_pat(s, it) walk_pat(&**s, it)
} }
PatVec(ref before, ref slice, ref after) => { PatVec(ref before, ref slice, ref after) => {
before.iter().advance(|&p| walk_pat(p, |p| it(p))) && before.iter().advance(|p| walk_pat(&**p, |p| it(p))) &&
slice.iter().advance(|&p| walk_pat(p, |p| it(p))) && slice.iter().advance(|p| walk_pat(&**p, |p| it(p))) &&
after.iter().advance(|&p| walk_pat(p, |p| it(p))) after.iter().advance(|p| walk_pat(&**p, |p| it(p)))
} }
PatMac(_) => fail!("attempted to analyze unexpanded pattern"), PatMac(_) => fail!("attempted to analyze unexpanded pattern"),
PatWild | PatWildMulti | PatLit(_) | PatRange(_, _) | PatIdent(_, _, _) | PatWild | PatWildMulti | PatLit(_) | PatRange(_, _) | PatIdent(_, _, _) |
@ -685,7 +685,7 @@ pub fn struct_def_is_tuple_like(struct_def: &ast::StructDef) -> bool {
/// Returns true if the given pattern consists solely of an identifier /// Returns true if the given pattern consists solely of an identifier
/// and false otherwise. /// and false otherwise.
pub fn pat_is_ident(pat: @ast::Pat) -> bool { pub fn pat_is_ident(pat: Gc<ast::Pat>) -> bool {
match pat.node { match pat.node {
ast::PatIdent(..) => true, ast::PatIdent(..) => true,
_ => false, _ => false,
@ -720,7 +720,7 @@ pub fn segments_name_eq(a : &[ast::PathSegment], b : &[ast::PathSegment]) -> boo
} }
// Returns true if this literal is a string and false otherwise. // Returns true if this literal is a string and false otherwise.
pub fn lit_is_str(lit: @Lit) -> bool { pub fn lit_is_str(lit: Gc<Lit>) -> bool {
match lit.node { match lit.node {
LitStr(..) => true, LitStr(..) => true,
_ => false, _ => false,

View file

@ -22,6 +22,7 @@ use crateid::CrateId;
use std::collections::HashSet; use std::collections::HashSet;
use std::collections::BitvSet; use std::collections::BitvSet;
use std::gc::Gc;
local_data_key!(used_attrs: BitvSet) local_data_key!(used_attrs: BitvSet)
@ -52,7 +53,7 @@ pub trait AttrMetaMethods {
*/ */
fn value_str(&self) -> Option<InternedString>; fn value_str(&self) -> Option<InternedString>;
/// Gets a list of inner meta items from a list MetaItem type. /// Gets a list of inner meta items from a list MetaItem type.
fn meta_item_list<'a>(&'a self) -> Option<&'a [@MetaItem]>; fn meta_item_list<'a>(&'a self) -> Option<&'a [Gc<MetaItem>]>;
} }
impl AttrMetaMethods for Attribute { impl AttrMetaMethods for Attribute {
@ -67,7 +68,7 @@ impl AttrMetaMethods for Attribute {
fn value_str(&self) -> Option<InternedString> { fn value_str(&self) -> Option<InternedString> {
self.meta().value_str() self.meta().value_str()
} }
fn meta_item_list<'a>(&'a self) -> Option<&'a [@MetaItem]> { fn meta_item_list<'a>(&'a self) -> Option<&'a [Gc<MetaItem>]> {
self.node.value.meta_item_list() self.node.value.meta_item_list()
} }
} }
@ -93,7 +94,7 @@ impl AttrMetaMethods for MetaItem {
} }
} }
fn meta_item_list<'a>(&'a self) -> Option<&'a [@MetaItem]> { fn meta_item_list<'a>(&'a self) -> Option<&'a [Gc<MetaItem>]> {
match self.node { match self.node {
MetaList(_, ref l) => Some(l.as_slice()), MetaList(_, ref l) => Some(l.as_slice()),
_ => None _ => None
@ -102,23 +103,23 @@ impl AttrMetaMethods for MetaItem {
} }
// Annoying, but required to get test_cfg to work // Annoying, but required to get test_cfg to work
impl AttrMetaMethods for @MetaItem { impl AttrMetaMethods for Gc<MetaItem> {
fn name(&self) -> InternedString { (**self).name() } fn name(&self) -> InternedString { (**self).name() }
fn value_str(&self) -> Option<InternedString> { (**self).value_str() } fn value_str(&self) -> Option<InternedString> { (**self).value_str() }
fn meta_item_list<'a>(&'a self) -> Option<&'a [@MetaItem]> { fn meta_item_list<'a>(&'a self) -> Option<&'a [Gc<MetaItem>]> {
(**self).meta_item_list() (**self).meta_item_list()
} }
} }
pub trait AttributeMethods { pub trait AttributeMethods {
fn meta(&self) -> @MetaItem; fn meta(&self) -> Gc<MetaItem>;
fn desugar_doc(&self) -> Attribute; fn desugar_doc(&self) -> Attribute;
} }
impl AttributeMethods for Attribute { impl AttributeMethods for Attribute {
/// Extract the MetaItem from inside this Attribute. /// Extract the MetaItem from inside this Attribute.
fn meta(&self) -> @MetaItem { fn meta(&self) -> Gc<MetaItem> {
self.node.value self.node.value
} }
@ -146,22 +147,23 @@ impl AttributeMethods for Attribute {
/* Constructors */ /* Constructors */
pub fn mk_name_value_item_str(name: InternedString, value: InternedString) pub fn mk_name_value_item_str(name: InternedString, value: InternedString)
-> @MetaItem { -> Gc<MetaItem> {
let value_lit = dummy_spanned(ast::LitStr(value, ast::CookedStr)); let value_lit = dummy_spanned(ast::LitStr(value, ast::CookedStr));
mk_name_value_item(name, value_lit) mk_name_value_item(name, value_lit)
} }
pub fn mk_name_value_item(name: InternedString, value: ast::Lit) pub fn mk_name_value_item(name: InternedString, value: ast::Lit)
-> @MetaItem { -> Gc<MetaItem> {
@dummy_spanned(MetaNameValue(name, value)) box(GC) dummy_spanned(MetaNameValue(name, value))
} }
pub fn mk_list_item(name: InternedString, items: Vec<@MetaItem> ) -> @MetaItem { pub fn mk_list_item(name: InternedString,
@dummy_spanned(MetaList(name, items)) items: Vec<Gc<MetaItem>>) -> Gc<MetaItem> {
box(GC) dummy_spanned(MetaList(name, items))
} }
pub fn mk_word_item(name: InternedString) -> @MetaItem { pub fn mk_word_item(name: InternedString) -> Gc<MetaItem> {
@dummy_spanned(MetaWord(name)) box(GC) dummy_spanned(MetaWord(name))
} }
local_data_key!(next_attr_id: uint) local_data_key!(next_attr_id: uint)
@ -173,7 +175,7 @@ pub fn mk_attr_id() -> AttrId {
} }
/// Returns an inner attribute with the given value. /// Returns an inner attribute with the given value.
pub fn mk_attr_inner(id: AttrId, item: @MetaItem) -> Attribute { pub fn mk_attr_inner(id: AttrId, item: Gc<MetaItem>) -> Attribute {
dummy_spanned(Attribute_ { dummy_spanned(Attribute_ {
id: id, id: id,
style: ast::AttrInner, style: ast::AttrInner,
@ -183,7 +185,7 @@ pub fn mk_attr_inner(id: AttrId, item: @MetaItem) -> Attribute {
} }
/// Returns an outer attribute with the given value. /// Returns an outer attribute with the given value.
pub fn mk_attr_outer(id: AttrId, item: @MetaItem) -> Attribute { pub fn mk_attr_outer(id: AttrId, item: Gc<MetaItem>) -> Attribute {
dummy_spanned(Attribute_ { dummy_spanned(Attribute_ {
id: id, id: id,
style: ast::AttrOuter, style: ast::AttrOuter,
@ -200,7 +202,7 @@ pub fn mk_sugared_doc_attr(id: AttrId, text: InternedString, lo: BytePos,
let attr = Attribute_ { let attr = Attribute_ {
id: id, id: id,
style: style, style: style,
value: @spanned(lo, hi, MetaNameValue(InternedString::new("doc"), value: box(GC) spanned(lo, hi, MetaNameValue(InternedString::new("doc"),
lit)), lit)),
is_sugared_doc: true is_sugared_doc: true
}; };
@ -211,8 +213,8 @@ pub fn mk_sugared_doc_attr(id: AttrId, text: InternedString, lo: BytePos,
/// Check if `needle` occurs in `haystack` by a structural /// Check if `needle` occurs in `haystack` by a structural
/// comparison. This is slightly subtle, and relies on ignoring the /// comparison. This is slightly subtle, and relies on ignoring the
/// span included in the `==` comparison a plain MetaItem. /// span included in the `==` comparison a plain MetaItem.
pub fn contains(haystack: &[@ast::MetaItem], pub fn contains(haystack: &[Gc<ast::MetaItem>],
needle: @ast::MetaItem) -> bool { needle: Gc<ast::MetaItem>) -> bool {
debug!("attr::contains (name={})", needle.name()); debug!("attr::contains (name={})", needle.name());
haystack.iter().any(|item| { haystack.iter().any(|item| {
debug!(" testing: {}", item.name()); debug!(" testing: {}", item.name());
@ -235,7 +237,7 @@ pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: &str)
.and_then(|at| at.value_str()) .and_then(|at| at.value_str())
} }
pub fn last_meta_item_value_str_by_name(items: &[@MetaItem], name: &str) pub fn last_meta_item_value_str_by_name(items: &[Gc<MetaItem>], name: &str)
-> Option<InternedString> { -> Option<InternedString> {
items.iter() items.iter()
.rev() .rev()
@ -245,12 +247,12 @@ pub fn last_meta_item_value_str_by_name(items: &[@MetaItem], name: &str)
/* Higher-level applications */ /* Higher-level applications */
pub fn sort_meta_items(items: &[@MetaItem]) -> Vec<@MetaItem> { pub fn sort_meta_items(items: &[Gc<MetaItem>]) -> Vec<Gc<MetaItem>> {
// This is sort of stupid here, but we need to sort by // This is sort of stupid here, but we need to sort by
// human-readable strings. // human-readable strings.
let mut v = items.iter() let mut v = items.iter()
.map(|&mi| (mi.name(), mi)) .map(|&mi| (mi.name(), mi))
.collect::<Vec<(InternedString, @MetaItem)> >(); .collect::<Vec<(InternedString, Gc<MetaItem>)> >();
v.sort_by(|&(ref a, _), &(ref b, _)| a.cmp(b)); v.sort_by(|&(ref a, _), &(ref b, _)| a.cmp(b));
@ -258,7 +260,7 @@ pub fn sort_meta_items(items: &[@MetaItem]) -> Vec<@MetaItem> {
v.move_iter().map(|(_, m)| { v.move_iter().map(|(_, m)| {
match m.node { match m.node {
MetaList(ref n, ref mis) => { MetaList(ref n, ref mis) => {
@Spanned { box(GC) Spanned {
node: MetaList((*n).clone(), node: MetaList((*n).clone(),
sort_meta_items(mis.as_slice())), sort_meta_items(mis.as_slice())),
.. /*bad*/ (*m).clone() .. /*bad*/ (*m).clone()
@ -273,7 +275,7 @@ pub fn sort_meta_items(items: &[@MetaItem]) -> Vec<@MetaItem> {
* From a list of crate attributes get only the meta_items that affect crate * From a list of crate attributes get only the meta_items that affect crate
* linkage * linkage
*/ */
pub fn find_linkage_metas(attrs: &[Attribute]) -> Vec<@MetaItem> { pub fn find_linkage_metas(attrs: &[Attribute]) -> Vec<Gc<MetaItem>> {
let mut result = Vec::new(); let mut result = Vec::new();
for attr in attrs.iter().filter(|at| at.check_name("link")) { for attr in attrs.iter().filter(|at| at.check_name("link")) {
match attr.meta().node { match attr.meta().node {
@ -330,7 +332,7 @@ pub fn find_inline_attr(attrs: &[Attribute]) -> InlineAttr {
/// test_cfg(`[foo="a", bar]`, `[cfg(bar, foo="a")]`) == true /// test_cfg(`[foo="a", bar]`, `[cfg(bar, foo="a")]`) == true
/// test_cfg(`[foo="a", bar]`, `[cfg(bar, foo="b")]`) == false /// test_cfg(`[foo="a", bar]`, `[cfg(bar, foo="b")]`) == false
pub fn test_cfg<AM: AttrMetaMethods, It: Iterator<AM>> pub fn test_cfg<AM: AttrMetaMethods, It: Iterator<AM>>
(cfg: &[@MetaItem], mut metas: It) -> bool { (cfg: &[Gc<MetaItem>], mut metas: It) -> bool {
// having no #[cfg(...)] attributes counts as matching. // having no #[cfg(...)] attributes counts as matching.
let mut no_cfgs = true; let mut no_cfgs = true;
@ -422,7 +424,7 @@ pub fn find_stability(attrs: &[Attribute]) -> Option<Stability> {
}) })
} }
pub fn require_unique_names(diagnostic: &SpanHandler, metas: &[@MetaItem]) { pub fn require_unique_names(diagnostic: &SpanHandler, metas: &[Gc<MetaItem>]) {
let mut set = HashSet::new(); let mut set = HashSet::new();
for meta in metas.iter() { for meta in metas.iter() {
let name = meta.name(); let name = meta.name();

View file

@ -23,8 +23,8 @@ source code snippets, etc.
use serialize::{Encodable, Decodable, Encoder, Decoder}; use serialize::{Encodable, Decodable, Encoder, Decoder};
use std::cell::RefCell; use std::cell::RefCell;
use std::gc::Gc;
use std::rc::Rc; use std::rc::Rc;
use std::string::String;
pub trait Pos { pub trait Pos {
fn from_uint(n: uint) -> Self; fn from_uint(n: uint) -> Self;
@ -91,7 +91,7 @@ pub struct Span {
pub hi: BytePos, pub hi: BytePos,
/// Information about where the macro came from, if this piece of /// Information about where the macro came from, if this piece of
/// code was created by a macro expansion. /// code was created by a macro expansion.
pub expn_info: Option<@ExpnInfo> pub expn_info: Option<Gc<ExpnInfo>>
} }
pub static DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0), expn_info: None }; pub static DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0), expn_info: None };

View file

@ -20,7 +20,6 @@ use parse;
use parse::token::InternedString; use parse::token::InternedString;
use parse::token; use parse::token;
enum State { enum State {
Asm, Asm,
Outputs, Outputs,
@ -214,7 +213,7 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
out)); out));
} }
MacExpr::new(@ast::Expr { MacExpr::new(box(GC) ast::Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::ExprInlineAsm(ast::InlineAsm { node: ast::ExprInlineAsm(ast::InlineAsm {
asm: token::intern_and_get_ident(asm.get()), asm: token::intern_and_get_ident(asm.get()),

View file

@ -20,6 +20,7 @@ use parse::token::{InternedString, intern, str_to_ident};
use util::small_vector::SmallVector; use util::small_vector::SmallVector;
use std::collections::HashMap; use std::collections::HashMap;
use std::gc::Gc;
// new-style macro! tt code: // new-style macro! tt code:
// //
@ -35,10 +36,10 @@ pub struct MacroDef {
} }
pub type ItemDecorator = pub type ItemDecorator =
fn(&mut ExtCtxt, Span, @ast::MetaItem, @ast::Item, |@ast::Item|); fn(&mut ExtCtxt, Span, Gc<ast::MetaItem>, Gc<ast::Item>, |Gc<ast::Item>|);
pub type ItemModifier = pub type ItemModifier =
fn(&mut ExtCtxt, Span, @ast::MetaItem, @ast::Item) -> @ast::Item; fn(&mut ExtCtxt, Span, Gc<ast::MetaItem>, Gc<ast::Item>) -> Gc<ast::Item>;
pub struct BasicMacroExpander { pub struct BasicMacroExpander {
pub expander: MacroExpanderFn, pub expander: MacroExpanderFn,
@ -104,11 +105,11 @@ pub trait MacResult {
None None
} }
/// Create an expression. /// Create an expression.
fn make_expr(&self) -> Option<@ast::Expr> { fn make_expr(&self) -> Option<Gc<ast::Expr>> {
None None
} }
/// Create zero or more items. /// Create zero or more items.
fn make_items(&self) -> Option<SmallVector<@ast::Item>> { fn make_items(&self) -> Option<SmallVector<Gc<ast::Item>>> {
None None
} }
/// Create a pattern. /// Create a pattern.
@ -120,23 +121,23 @@ pub trait MacResult {
/// ///
/// By default this attempts to create an expression statement, /// By default this attempts to create an expression statement,
/// returning None if that fails. /// returning None if that fails.
fn make_stmt(&self) -> Option<@ast::Stmt> { fn make_stmt(&self) -> Option<Gc<ast::Stmt>> {
self.make_expr() self.make_expr()
.map(|e| @codemap::respan(e.span, ast::StmtExpr(e, ast::DUMMY_NODE_ID))) .map(|e| box(GC) codemap::respan(e.span, ast::StmtExpr(e, ast::DUMMY_NODE_ID)))
} }
} }
/// A convenience type for macros that return a single expression. /// A convenience type for macros that return a single expression.
pub struct MacExpr { pub struct MacExpr {
e: @ast::Expr e: Gc<ast::Expr>,
} }
impl MacExpr { impl MacExpr {
pub fn new(e: @ast::Expr) -> Box<MacResult> { pub fn new(e: Gc<ast::Expr>) -> Box<MacResult> {
box MacExpr { e: e } as Box<MacResult> box MacExpr { e: e } as Box<MacResult>
} }
} }
impl MacResult for MacExpr { impl MacResult for MacExpr {
fn make_expr(&self) -> Option<@ast::Expr> { fn make_expr(&self) -> Option<Gc<ast::Expr>> {
Some(self.e) Some(self.e)
} }
} }
@ -156,22 +157,22 @@ impl MacResult for MacPat {
} }
/// A convenience type for macros that return a single item. /// A convenience type for macros that return a single item.
pub struct MacItem { pub struct MacItem {
i: @ast::Item i: Gc<ast::Item>
} }
impl MacItem { impl MacItem {
pub fn new(i: @ast::Item) -> Box<MacResult> { pub fn new(i: Gc<ast::Item>) -> Box<MacResult> {
box MacItem { i: i } as Box<MacResult> box MacItem { i: i } as Box<MacResult>
} }
} }
impl MacResult for MacItem { impl MacResult for MacItem {
fn make_items(&self) -> Option<SmallVector<@ast::Item>> { fn make_items(&self) -> Option<SmallVector<Gc<ast::Item>>> {
Some(SmallVector::one(self.i)) Some(SmallVector::one(self.i))
} }
fn make_stmt(&self) -> Option<@ast::Stmt> { fn make_stmt(&self) -> Option<Gc<ast::Stmt>> {
Some(@codemap::respan( Some(box(GC) codemap::respan(
self.i.span, self.i.span,
ast::StmtDecl( ast::StmtDecl(
@codemap::respan(self.i.span, ast::DeclItem(self.i)), box(GC) codemap::respan(self.i.span, ast::DeclItem(self.i)),
ast::DUMMY_NODE_ID))) ast::DUMMY_NODE_ID)))
} }
} }
@ -202,10 +203,10 @@ impl DummyResult {
} }
/// A plain dummy expression. /// A plain dummy expression.
pub fn raw_expr(sp: Span) -> @ast::Expr { pub fn raw_expr(sp: Span) -> Gc<ast::Expr> {
@ast::Expr { box(GC) ast::Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::ExprLit(@codemap::respan(sp, ast::LitNil)), node: ast::ExprLit(box(GC) codemap::respan(sp, ast::LitNil)),
span: sp, span: sp,
} }
} }
@ -221,21 +222,21 @@ impl DummyResult {
} }
impl MacResult for DummyResult { impl MacResult for DummyResult {
fn make_expr(&self) -> Option<@ast::Expr> { fn make_expr(&self) -> Option<Gc<ast::Expr>> {
Some(DummyResult::raw_expr(self.span)) Some(DummyResult::raw_expr(self.span))
} }
fn make_pat(&self) -> Option<@ast::Pat> { fn make_pat(&self) -> Option<Gc<ast::Pat>> {
Some(DummyResult::raw_pat(self.span)) Some(DummyResult::raw_pat(self.span))
} }
fn make_items(&self) -> Option<SmallVector<@ast::Item>> { fn make_items(&self) -> Option<SmallVector<Gc<ast::Item>>> {
if self.expr_only { if self.expr_only {
None None
} else { } else {
Some(SmallVector::zero()) Some(SmallVector::zero())
} }
} }
fn make_stmt(&self) -> Option<@ast::Stmt> { fn make_stmt(&self) -> Option<Gc<ast::Stmt>> {
Some(@codemap::respan(self.span, Some(box(GC) codemap::respan(self.span,
ast::StmtExpr(DummyResult::raw_expr(self.span), ast::StmtExpr(DummyResult::raw_expr(self.span),
ast::DUMMY_NODE_ID))) ast::DUMMY_NODE_ID)))
} }
@ -397,7 +398,7 @@ pub fn syntax_expander_table() -> SyntaxEnv {
pub struct ExtCtxt<'a> { pub struct ExtCtxt<'a> {
pub parse_sess: &'a parse::ParseSess, pub parse_sess: &'a parse::ParseSess,
pub cfg: ast::CrateConfig, pub cfg: ast::CrateConfig,
pub backtrace: Option<@ExpnInfo>, pub backtrace: Option<Gc<ExpnInfo>>,
pub ecfg: expand::ExpansionConfig, pub ecfg: expand::ExpansionConfig,
pub mod_path: Vec<ast::Ident> , pub mod_path: Vec<ast::Ident> ,
@ -417,7 +418,7 @@ impl<'a> ExtCtxt<'a> {
} }
} }
pub fn expand_expr(&mut self, mut e: @ast::Expr) -> @ast::Expr { pub fn expand_expr(&mut self, mut e: Gc<ast::Expr>) -> Gc<ast::Expr> {
loop { loop {
match e.node { match e.node {
ast::ExprMac(..) => { ast::ExprMac(..) => {
@ -442,7 +443,7 @@ impl<'a> ExtCtxt<'a> {
} }
} }
pub fn print_backtrace(&self) { } pub fn print_backtrace(&self) { }
pub fn backtrace(&self) -> Option<@ExpnInfo> { self.backtrace } pub fn backtrace(&self) -> Option<Gc<ExpnInfo>> { self.backtrace }
pub fn mod_push(&mut self, i: ast::Ident) { self.mod_path.push(i); } pub fn mod_push(&mut self, i: ast::Ident) { self.mod_path.push(i); }
pub fn mod_pop(&mut self) { self.mod_path.pop().unwrap(); } pub fn mod_pop(&mut self) { self.mod_path.pop().unwrap(); }
pub fn mod_path(&self) -> Vec<ast::Ident> { pub fn mod_path(&self) -> Vec<ast::Ident> {
@ -455,9 +456,9 @@ impl<'a> ExtCtxt<'a> {
match ei { match ei {
ExpnInfo {call_site: cs, callee: ref callee} => { ExpnInfo {call_site: cs, callee: ref callee} => {
self.backtrace = self.backtrace =
Some(@ExpnInfo { Some(box(GC) ExpnInfo {
call_site: Span {lo: cs.lo, hi: cs.hi, call_site: Span {lo: cs.lo, hi: cs.hi,
expn_info: self.backtrace}, expn_info: self.backtrace.clone()},
callee: (*callee).clone() callee: (*callee).clone()
}); });
} }
@ -528,7 +529,7 @@ impl<'a> ExtCtxt<'a> {
/// Extract a string literal from the macro expanded version of `expr`, /// Extract a string literal from the macro expanded version of `expr`,
/// emitting `err_msg` if `expr` is not a string literal. This does not stop /// emitting `err_msg` if `expr` is not a string literal. This does not stop
/// compilation on error, merely emits a non-fatal error and returns None. /// compilation on error, merely emits a non-fatal error and returns None.
pub fn expr_to_str(cx: &mut ExtCtxt, expr: @ast::Expr, err_msg: &str) pub fn expr_to_str(cx: &mut ExtCtxt, expr: Gc<ast::Expr>, err_msg: &str)
-> Option<(InternedString, ast::StrStyle)> { -> Option<(InternedString, ast::StrStyle)> {
// we want to be able to handle e.g. concat("foo", "bar") // we want to be able to handle e.g. concat("foo", "bar")
let expr = cx.expand_expr(expr); let expr = cx.expand_expr(expr);
@ -584,7 +585,7 @@ pub fn get_single_str_from_tts(cx: &ExtCtxt,
/// parsing error, emit a non-fatal error and return None. /// parsing error, emit a non-fatal error and return None.
pub fn get_exprs_from_tts(cx: &mut ExtCtxt, pub fn get_exprs_from_tts(cx: &mut ExtCtxt,
sp: Span, sp: Span,
tts: &[ast::TokenTree]) -> Option<Vec<@ast::Expr> > { tts: &[ast::TokenTree]) -> Option<Vec<Gc<ast::Expr>>> {
let mut p = parse::new_parser_from_tts(cx.parse_sess(), let mut p = parse::new_parser_from_tts(cx.parse_sess(),
cx.cfg(), cx.cfg(),
tts.iter() tts.iter()

View file

@ -21,6 +21,8 @@ use parse::token::special_idents;
use parse::token::InternedString; use parse::token::InternedString;
use parse::token; use parse::token;
use std::gc::Gc;
// Transitional reexports so qquote can find the paths it is looking for // Transitional reexports so qquote can find the paths it is looking for
mod syntax { mod syntax {
pub use ext; pub use ext;
@ -73,115 +75,129 @@ pub trait AstBuilder {
fn lifetime(&self, span: Span, ident: ast::Name) -> ast::Lifetime; fn lifetime(&self, span: Span, ident: ast::Name) -> ast::Lifetime;
// statements // statements
fn stmt_expr(&self, expr: @ast::Expr) -> @ast::Stmt; fn stmt_expr(&self, expr: Gc<ast::Expr>) -> Gc<ast::Stmt>;
fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, ex: @ast::Expr) -> @ast::Stmt; fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident,
ex: Gc<ast::Expr>) -> Gc<ast::Stmt>;
fn stmt_let_typed(&self, fn stmt_let_typed(&self,
sp: Span, sp: Span,
mutbl: bool, mutbl: bool,
ident: ast::Ident, ident: ast::Ident,
typ: P<ast::Ty>, typ: P<ast::Ty>,
ex: @ast::Expr) ex: Gc<ast::Expr>)
-> @ast::Stmt; -> Gc<ast::Stmt>;
// blocks // blocks
fn block(&self, span: Span, stmts: Vec<@ast::Stmt> , expr: Option<@ast::Expr>) -> P<ast::Block>; fn block(&self, span: Span, stmts: Vec<Gc<ast::Stmt>>,
fn block_expr(&self, expr: @ast::Expr) -> P<ast::Block>; expr: Option<Gc<ast::Expr>>) -> P<ast::Block>;
fn block_expr(&self, expr: Gc<ast::Expr>) -> P<ast::Block>;
fn block_all(&self, span: Span, fn block_all(&self, span: Span,
view_items: Vec<ast::ViewItem> , view_items: Vec<ast::ViewItem> ,
stmts: Vec<@ast::Stmt> , stmts: Vec<Gc<ast::Stmt>> ,
expr: Option<@ast::Expr>) -> P<ast::Block>; expr: Option<Gc<ast::Expr>>) -> P<ast::Block>;
// expressions // expressions
fn expr(&self, span: Span, node: ast::Expr_) -> @ast::Expr; fn expr(&self, span: Span, node: ast::Expr_) -> Gc<ast::Expr>;
fn expr_path(&self, path: ast::Path) -> @ast::Expr; fn expr_path(&self, path: ast::Path) -> Gc<ast::Expr>;
fn expr_ident(&self, span: Span, id: ast::Ident) -> @ast::Expr; fn expr_ident(&self, span: Span, id: ast::Ident) -> Gc<ast::Expr>;
fn expr_self(&self, span: Span) -> @ast::Expr; fn expr_self(&self, span: Span) -> Gc<ast::Expr>;
fn expr_binary(&self, sp: Span, op: ast::BinOp, fn expr_binary(&self, sp: Span, op: ast::BinOp,
lhs: @ast::Expr, rhs: @ast::Expr) -> @ast::Expr; lhs: Gc<ast::Expr>, rhs: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn expr_deref(&self, sp: Span, e: @ast::Expr) -> @ast::Expr; fn expr_deref(&self, sp: Span, e: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn expr_unary(&self, sp: Span, op: ast::UnOp, e: @ast::Expr) -> @ast::Expr; fn expr_unary(&self, sp: Span, op: ast::UnOp, e: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn expr_managed(&self, sp: Span, e: @ast::Expr) -> @ast::Expr; fn expr_managed(&self, sp: Span, e: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn expr_addr_of(&self, sp: Span, e: @ast::Expr) -> @ast::Expr; fn expr_addr_of(&self, sp: Span, e: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn expr_mut_addr_of(&self, sp: Span, e: @ast::Expr) -> @ast::Expr; fn expr_mut_addr_of(&self, sp: Span, e: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn expr_field_access(&self, span: Span, expr: @ast::Expr, ident: ast::Ident) -> @ast::Expr; fn expr_field_access(&self, span: Span, expr: Gc<ast::Expr>,
fn expr_call(&self, span: Span, expr: @ast::Expr, args: Vec<@ast::Expr> ) -> @ast::Expr; ident: ast::Ident) -> Gc<ast::Expr>;
fn expr_call_ident(&self, span: Span, id: ast::Ident, args: Vec<@ast::Expr> ) -> @ast::Expr; fn expr_call(&self, span: Span, expr: Gc<ast::Expr>,
args: Vec<Gc<ast::Expr>>) -> Gc<ast::Expr>;
fn expr_call_ident(&self, span: Span, id: ast::Ident,
args: Vec<Gc<ast::Expr>>) -> Gc<ast::Expr>;
fn expr_call_global(&self, sp: Span, fn_path: Vec<ast::Ident> , fn expr_call_global(&self, sp: Span, fn_path: Vec<ast::Ident> ,
args: Vec<@ast::Expr> ) -> @ast::Expr; args: Vec<Gc<ast::Expr>>) -> Gc<ast::Expr>;
fn expr_method_call(&self, span: Span, fn expr_method_call(&self, span: Span,
expr: @ast::Expr, ident: ast::Ident, expr: Gc<ast::Expr>, ident: ast::Ident,
args: Vec<@ast::Expr> ) -> @ast::Expr; args: Vec<Gc<ast::Expr>> ) -> Gc<ast::Expr>;
fn expr_block(&self, b: P<ast::Block>) -> @ast::Expr; fn expr_block(&self, b: P<ast::Block>) -> Gc<ast::Expr>;
fn expr_cast(&self, sp: Span, expr: @ast::Expr, ty: P<ast::Ty>) -> @ast::Expr; fn expr_cast(&self, sp: Span, expr: Gc<ast::Expr>,
ty: P<ast::Ty>) -> Gc<ast::Expr>;
fn field_imm(&self, span: Span, name: Ident, e: @ast::Expr) -> ast::Field; fn field_imm(&self, span: Span, name: Ident, e: Gc<ast::Expr>) -> ast::Field;
fn expr_struct(&self, span: Span, path: ast::Path, fields: Vec<ast::Field> ) -> @ast::Expr; fn expr_struct(&self, span: Span, path: ast::Path,
fn expr_struct_ident(&self, span: Span, id: ast::Ident, fields: Vec<ast::Field> ) -> @ast::Expr; fields: Vec<ast::Field> ) -> Gc<ast::Expr>;
fn expr_struct_ident(&self, span: Span, id: ast::Ident,
fields: Vec<ast::Field> ) -> Gc<ast::Expr>;
fn expr_lit(&self, sp: Span, lit: ast::Lit_) -> @ast::Expr; fn expr_lit(&self, sp: Span, lit: ast::Lit_) -> Gc<ast::Expr>;
fn expr_uint(&self, span: Span, i: uint) -> @ast::Expr; fn expr_uint(&self, span: Span, i: uint) -> Gc<ast::Expr>;
fn expr_int(&self, sp: Span, i: int) -> @ast::Expr; fn expr_int(&self, sp: Span, i: int) -> Gc<ast::Expr>;
fn expr_u8(&self, sp: Span, u: u8) -> @ast::Expr; fn expr_u8(&self, sp: Span, u: u8) -> Gc<ast::Expr>;
fn expr_bool(&self, sp: Span, value: bool) -> @ast::Expr; fn expr_bool(&self, sp: Span, value: bool) -> Gc<ast::Expr>;
fn expr_vstore(&self, sp: Span, expr: @ast::Expr, vst: ast::ExprVstore) -> @ast::Expr; fn expr_vstore(&self, sp: Span, expr: Gc<ast::Expr>, vst: ast::ExprVstore) -> Gc<ast::Expr>;
fn expr_vec(&self, sp: Span, exprs: Vec<@ast::Expr> ) -> @ast::Expr; fn expr_vec(&self, sp: Span, exprs: Vec<Gc<ast::Expr>> ) -> Gc<ast::Expr>;
fn expr_vec_ng(&self, sp: Span) -> @ast::Expr; fn expr_vec_ng(&self, sp: Span) -> Gc<ast::Expr>;
fn expr_vec_slice(&self, sp: Span, exprs: Vec<@ast::Expr> ) -> @ast::Expr; fn expr_vec_slice(&self, sp: Span, exprs: Vec<Gc<ast::Expr>> ) -> Gc<ast::Expr>;
fn expr_str(&self, sp: Span, s: InternedString) -> @ast::Expr; fn expr_str(&self, sp: Span, s: InternedString) -> Gc<ast::Expr>;
fn expr_str_uniq(&self, sp: Span, s: InternedString) -> @ast::Expr; fn expr_str_uniq(&self, sp: Span, s: InternedString) -> Gc<ast::Expr>;
fn expr_some(&self, sp: Span, expr: @ast::Expr) -> @ast::Expr; fn expr_some(&self, sp: Span, expr: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn expr_none(&self, sp: Span) -> @ast::Expr; fn expr_none(&self, sp: Span) -> Gc<ast::Expr>;
fn expr_fail(&self, span: Span, msg: InternedString) -> @ast::Expr; fn expr_fail(&self, span: Span, msg: InternedString) -> Gc<ast::Expr>;
fn expr_unreachable(&self, span: Span) -> @ast::Expr; fn expr_unreachable(&self, span: Span) -> Gc<ast::Expr>;
fn expr_ok(&self, span: Span, expr: @ast::Expr) -> @ast::Expr; fn expr_ok(&self, span: Span, expr: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn expr_err(&self, span: Span, expr: @ast::Expr) -> @ast::Expr; fn expr_err(&self, span: Span, expr: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn expr_try(&self, span: Span, head: @ast::Expr) -> @ast::Expr; fn expr_try(&self, span: Span, head: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn pat(&self, span: Span, pat: ast::Pat_) -> @ast::Pat; fn pat(&self, span: Span, pat: ast::Pat_) -> Gc<ast::Pat>;
fn pat_wild(&self, span: Span) -> @ast::Pat; fn pat_wild(&self, span: Span) -> Gc<ast::Pat>;
fn pat_lit(&self, span: Span, expr: @ast::Expr) -> @ast::Pat; fn pat_lit(&self, span: Span, expr: Gc<ast::Expr>) -> Gc<ast::Pat>;
fn pat_ident(&self, span: Span, ident: ast::Ident) -> @ast::Pat; fn pat_ident(&self, span: Span, ident: ast::Ident) -> Gc<ast::Pat>;
fn pat_ident_binding_mode(&self, fn pat_ident_binding_mode(&self,
span: Span, span: Span,
ident: ast::Ident, ident: ast::Ident,
bm: ast::BindingMode) -> @ast::Pat; bm: ast::BindingMode) -> Gc<ast::Pat>;
fn pat_enum(&self, span: Span, path: ast::Path, subpats: Vec<@ast::Pat> ) -> @ast::Pat; fn pat_enum(&self, span: Span, path: ast::Path,
subpats: Vec<Gc<ast::Pat>>) -> Gc<ast::Pat>;
fn pat_struct(&self, span: Span, fn pat_struct(&self, span: Span,
path: ast::Path, field_pats: Vec<ast::FieldPat> ) -> @ast::Pat; path: ast::Path, field_pats: Vec<ast::FieldPat> ) -> Gc<ast::Pat>;
fn arm(&self, span: Span, pats: Vec<@ast::Pat> , expr: @ast::Expr) -> ast::Arm; fn arm(&self, span: Span, pats: Vec<Gc<ast::Pat>> , expr: Gc<ast::Expr>) -> ast::Arm;
fn arm_unreachable(&self, span: Span) -> ast::Arm; fn arm_unreachable(&self, span: Span) -> ast::Arm;
fn expr_match(&self, span: Span, arg: @ast::Expr, arms: Vec<ast::Arm> ) -> @ast::Expr; fn expr_match(&self, span: Span, arg: Gc<ast::Expr>, arms: Vec<ast::Arm> ) -> Gc<ast::Expr>;
fn expr_if(&self, span: Span, fn expr_if(&self, span: Span,
cond: @ast::Expr, then: @ast::Expr, els: Option<@ast::Expr>) -> @ast::Expr; cond: Gc<ast::Expr>, then: Gc<ast::Expr>,
els: Option<Gc<ast::Expr>>) -> Gc<ast::Expr>;
fn lambda_fn_decl(&self, span: Span, fn lambda_fn_decl(&self, span: Span,
fn_decl: P<ast::FnDecl>, blk: P<ast::Block>) -> @ast::Expr; fn_decl: P<ast::FnDecl>, blk: P<ast::Block>) -> Gc<ast::Expr>;
fn lambda(&self, span: Span, ids: Vec<ast::Ident> , blk: P<ast::Block>) -> @ast::Expr; fn lambda(&self, span: Span, ids: Vec<ast::Ident> , blk: P<ast::Block>) -> Gc<ast::Expr>;
fn lambda0(&self, span: Span, blk: P<ast::Block>) -> @ast::Expr; fn lambda0(&self, span: Span, blk: P<ast::Block>) -> Gc<ast::Expr>;
fn lambda1(&self, span: Span, blk: P<ast::Block>, ident: ast::Ident) -> @ast::Expr; fn lambda1(&self, span: Span, blk: P<ast::Block>, ident: ast::Ident) -> Gc<ast::Expr>;
fn lambda_expr(&self, span: Span, ids: Vec<ast::Ident> , blk: @ast::Expr) -> @ast::Expr; fn lambda_expr(&self, span: Span, ids: Vec<ast::Ident> , blk: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn lambda_expr_0(&self, span: Span, expr: @ast::Expr) -> @ast::Expr; fn lambda_expr_0(&self, span: Span, expr: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn lambda_expr_1(&self, span: Span, expr: @ast::Expr, ident: ast::Ident) -> @ast::Expr; fn lambda_expr_1(&self, span: Span, expr: Gc<ast::Expr>, ident: ast::Ident) -> Gc<ast::Expr>;
fn lambda_stmts(&self, span: Span, ids: Vec<ast::Ident> , blk: Vec<@ast::Stmt> ) -> @ast::Expr; fn lambda_stmts(&self, span: Span, ids: Vec<ast::Ident>,
fn lambda_stmts_0(&self, span: Span, stmts: Vec<@ast::Stmt> ) -> @ast::Expr; blk: Vec<Gc<ast::Stmt>>) -> Gc<ast::Expr>;
fn lambda_stmts_1(&self, span: Span, stmts: Vec<@ast::Stmt> , ident: ast::Ident) -> @ast::Expr; fn lambda_stmts_0(&self, span: Span,
stmts: Vec<Gc<ast::Stmt>>) -> Gc<ast::Expr>;
fn lambda_stmts_1(&self, span: Span,
stmts: Vec<Gc<ast::Stmt>>, ident: ast::Ident) -> Gc<ast::Expr>;
// items // items
fn item(&self, span: Span, fn item(&self, span: Span,
name: Ident, attrs: Vec<ast::Attribute> , node: ast::Item_) -> @ast::Item; name: Ident, attrs: Vec<ast::Attribute>,
node: ast::Item_) -> Gc<ast::Item>;
fn arg(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> ast::Arg; fn arg(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> ast::Arg;
// FIXME unused self // FIXME unused self
@ -193,56 +209,59 @@ pub trait AstBuilder {
inputs: Vec<ast::Arg> , inputs: Vec<ast::Arg> ,
output: P<ast::Ty>, output: P<ast::Ty>,
generics: Generics, generics: Generics,
body: P<ast::Block>) -> @ast::Item; body: P<ast::Block>) -> Gc<ast::Item>;
fn item_fn(&self, fn item_fn(&self,
span: Span, span: Span,
name: Ident, name: Ident,
inputs: Vec<ast::Arg> , inputs: Vec<ast::Arg> ,
output: P<ast::Ty>, output: P<ast::Ty>,
body: P<ast::Block>) -> @ast::Item; body: P<ast::Block>) -> Gc<ast::Item>;
fn variant(&self, span: Span, name: Ident, tys: Vec<P<ast::Ty>> ) -> ast::Variant; fn variant(&self, span: Span, name: Ident, tys: Vec<P<ast::Ty>> ) -> ast::Variant;
fn item_enum_poly(&self, fn item_enum_poly(&self,
span: Span, span: Span,
name: Ident, name: Ident,
enum_definition: ast::EnumDef, enum_definition: ast::EnumDef,
generics: Generics) -> @ast::Item; generics: Generics) -> Gc<ast::Item>;
fn item_enum(&self, span: Span, name: Ident, enum_def: ast::EnumDef) -> @ast::Item; fn item_enum(&self, span: Span, name: Ident,
enum_def: ast::EnumDef) -> Gc<ast::Item>;
fn item_struct_poly(&self, fn item_struct_poly(&self,
span: Span, span: Span,
name: Ident, name: Ident,
struct_def: ast::StructDef, struct_def: ast::StructDef,
generics: Generics) -> @ast::Item; generics: Generics) -> Gc<ast::Item>;
fn item_struct(&self, span: Span, name: Ident, struct_def: ast::StructDef) -> @ast::Item; fn item_struct(&self, span: Span, name: Ident,
struct_def: ast::StructDef) -> Gc<ast::Item>;
fn item_mod(&self, span: Span, inner_span: Span, fn item_mod(&self, span: Span, inner_span: Span,
name: Ident, attrs: Vec<ast::Attribute> , name: Ident, attrs: Vec<ast::Attribute>,
vi: Vec<ast::ViewItem> , items: Vec<@ast::Item> ) -> @ast::Item; vi: Vec<ast::ViewItem>,
items: Vec<Gc<ast::Item>>) -> Gc<ast::Item>;
fn item_ty_poly(&self, fn item_ty_poly(&self,
span: Span, span: Span,
name: Ident, name: Ident,
ty: P<ast::Ty>, ty: P<ast::Ty>,
generics: Generics) -> @ast::Item; generics: Generics) -> Gc<ast::Item>;
fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> @ast::Item; fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> Gc<ast::Item>;
fn attribute(&self, sp: Span, mi: @ast::MetaItem) -> ast::Attribute; fn attribute(&self, sp: Span, mi: Gc<ast::MetaItem>) -> ast::Attribute;
fn meta_word(&self, sp: Span, w: InternedString) -> @ast::MetaItem; fn meta_word(&self, sp: Span, w: InternedString) -> Gc<ast::MetaItem>;
fn meta_list(&self, fn meta_list(&self,
sp: Span, sp: Span,
name: InternedString, name: InternedString,
mis: Vec<@ast::MetaItem> ) mis: Vec<Gc<ast::MetaItem>>)
-> @ast::MetaItem; -> Gc<ast::MetaItem>;
fn meta_name_value(&self, fn meta_name_value(&self,
sp: Span, sp: Span,
name: InternedString, name: InternedString,
value: ast::Lit_) value: ast::Lit_)
-> @ast::MetaItem; -> Gc<ast::MetaItem>;
fn view_use(&self, sp: Span, fn view_use(&self, sp: Span,
vis: ast::Visibility, vp: @ast::ViewPath) -> ast::ViewItem; vis: ast::Visibility, vp: Gc<ast::ViewPath>) -> ast::ViewItem;
fn view_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> ast::ViewItem; fn view_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> ast::ViewItem;
fn view_use_simple_(&self, sp: Span, vis: ast::Visibility, fn view_use_simple_(&self, sp: Span, vis: ast::Visibility,
ident: ast::Ident, path: ast::Path) -> ast::ViewItem; ident: ast::Ident, path: ast::Path) -> ast::ViewItem;
@ -418,17 +437,18 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
ast::Lifetime { id: ast::DUMMY_NODE_ID, span: span, name: name } ast::Lifetime { id: ast::DUMMY_NODE_ID, span: span, name: name }
} }
fn stmt_expr(&self, expr: @ast::Expr) -> @ast::Stmt { fn stmt_expr(&self, expr: Gc<ast::Expr>) -> Gc<ast::Stmt> {
@respan(expr.span, ast::StmtSemi(expr, ast::DUMMY_NODE_ID)) box(GC) respan(expr.span, ast::StmtSemi(expr, ast::DUMMY_NODE_ID))
} }
fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, ex: @ast::Expr) -> @ast::Stmt { fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident,
ex: Gc<ast::Expr>) -> Gc<ast::Stmt> {
let pat = if mutbl { let pat = if mutbl {
self.pat_ident_binding_mode(sp, ident, ast::BindByValue(ast::MutMutable)) self.pat_ident_binding_mode(sp, ident, ast::BindByValue(ast::MutMutable))
} else { } else {
self.pat_ident(sp, ident) self.pat_ident(sp, ident)
}; };
let local = @ast::Local { let local = box(GC) ast::Local {
ty: self.ty_infer(sp), ty: self.ty_infer(sp),
pat: pat, pat: pat,
init: Some(ex), init: Some(ex),
@ -437,7 +457,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
source: ast::LocalLet, source: ast::LocalLet,
}; };
let decl = respan(sp, ast::DeclLocal(local)); let decl = respan(sp, ast::DeclLocal(local));
@respan(sp, ast::StmtDecl(@decl, ast::DUMMY_NODE_ID)) box(GC) respan(sp, ast::StmtDecl(box(GC) decl, ast::DUMMY_NODE_ID))
} }
fn stmt_let_typed(&self, fn stmt_let_typed(&self,
@ -445,14 +465,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
mutbl: bool, mutbl: bool,
ident: ast::Ident, ident: ast::Ident,
typ: P<ast::Ty>, typ: P<ast::Ty>,
ex: @ast::Expr) ex: Gc<ast::Expr>)
-> @ast::Stmt { -> Gc<ast::Stmt> {
let pat = if mutbl { let pat = if mutbl {
self.pat_ident_binding_mode(sp, ident, ast::BindByValue(ast::MutMutable)) self.pat_ident_binding_mode(sp, ident, ast::BindByValue(ast::MutMutable))
} else { } else {
self.pat_ident(sp, ident) self.pat_ident(sp, ident)
}; };
let local = @ast::Local { let local = box(GC) ast::Local {
ty: typ, ty: typ,
pat: pat, pat: pat,
init: Some(ex), init: Some(ex),
@ -461,21 +481,22 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
source: ast::LocalLet, source: ast::LocalLet,
}; };
let decl = respan(sp, ast::DeclLocal(local)); let decl = respan(sp, ast::DeclLocal(local));
@respan(sp, ast::StmtDecl(@decl, ast::DUMMY_NODE_ID)) box(GC) respan(sp, ast::StmtDecl(box(GC) decl, ast::DUMMY_NODE_ID))
} }
fn block(&self, span: Span, stmts: Vec<@ast::Stmt> , expr: Option<@Expr>) -> P<ast::Block> { fn block(&self, span: Span, stmts: Vec<Gc<ast::Stmt>>,
expr: Option<Gc<Expr>>) -> P<ast::Block> {
self.block_all(span, Vec::new(), stmts, expr) self.block_all(span, Vec::new(), stmts, expr)
} }
fn block_expr(&self, expr: @ast::Expr) -> P<ast::Block> { fn block_expr(&self, expr: Gc<ast::Expr>) -> P<ast::Block> {
self.block_all(expr.span, Vec::new(), Vec::new(), Some(expr)) self.block_all(expr.span, Vec::new(), Vec::new(), Some(expr))
} }
fn block_all(&self, fn block_all(&self,
span: Span, span: Span,
view_items: Vec<ast::ViewItem> , view_items: Vec<ast::ViewItem> ,
stmts: Vec<@ast::Stmt> , stmts: Vec<Gc<ast::Stmt>>,
expr: Option<@ast::Expr>) -> P<ast::Block> { expr: Option<Gc<ast::Expr>>) -> P<ast::Block> {
P(ast::Block { P(ast::Block {
view_items: view_items, view_items: view_items,
stmts: stmts, stmts: stmts,
@ -486,107 +507,109 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
}) })
} }
fn expr(&self, span: Span, node: ast::Expr_) -> @ast::Expr { fn expr(&self, span: Span, node: ast::Expr_) -> Gc<ast::Expr> {
@ast::Expr { box(GC) ast::Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: node, node: node,
span: span, span: span,
} }
} }
fn expr_path(&self, path: ast::Path) -> @ast::Expr { fn expr_path(&self, path: ast::Path) -> Gc<ast::Expr> {
self.expr(path.span, ast::ExprPath(path)) self.expr(path.span, ast::ExprPath(path))
} }
fn expr_ident(&self, span: Span, id: ast::Ident) -> @ast::Expr { fn expr_ident(&self, span: Span, id: ast::Ident) -> Gc<ast::Expr> {
self.expr_path(self.path_ident(span, id)) self.expr_path(self.path_ident(span, id))
} }
fn expr_self(&self, span: Span) -> @ast::Expr { fn expr_self(&self, span: Span) -> Gc<ast::Expr> {
self.expr_ident(span, special_idents::self_) self.expr_ident(span, special_idents::self_)
} }
fn expr_binary(&self, sp: Span, op: ast::BinOp, fn expr_binary(&self, sp: Span, op: ast::BinOp,
lhs: @ast::Expr, rhs: @ast::Expr) -> @ast::Expr { lhs: Gc<ast::Expr>, rhs: Gc<ast::Expr>) -> Gc<ast::Expr> {
self.expr(sp, ast::ExprBinary(op, lhs, rhs)) self.expr(sp, ast::ExprBinary(op, lhs, rhs))
} }
fn expr_deref(&self, sp: Span, e: @ast::Expr) -> @ast::Expr { fn expr_deref(&self, sp: Span, e: Gc<ast::Expr>) -> Gc<ast::Expr> {
self.expr_unary(sp, ast::UnDeref, e) self.expr_unary(sp, ast::UnDeref, e)
} }
fn expr_unary(&self, sp: Span, op: ast::UnOp, e: @ast::Expr) -> @ast::Expr { fn expr_unary(&self, sp: Span, op: ast::UnOp, e: Gc<ast::Expr>) -> Gc<ast::Expr> {
self.expr(sp, ast::ExprUnary(op, e)) self.expr(sp, ast::ExprUnary(op, e))
} }
fn expr_managed(&self, sp: Span, e: @ast::Expr) -> @ast::Expr { fn expr_managed(&self, sp: Span, e: Gc<ast::Expr>) -> Gc<ast::Expr> {
self.expr_unary(sp, ast::UnBox, e) self.expr_unary(sp, ast::UnBox, e)
} }
fn expr_field_access(&self, sp: Span, expr: @ast::Expr, ident: ast::Ident) -> @ast::Expr { fn expr_field_access(&self, sp: Span, expr: Gc<ast::Expr>, ident: ast::Ident) -> Gc<ast::Expr> {
self.expr(sp, ast::ExprField(expr, ident, Vec::new())) self.expr(sp, ast::ExprField(expr, ident, Vec::new()))
} }
fn expr_addr_of(&self, sp: Span, e: @ast::Expr) -> @ast::Expr { fn expr_addr_of(&self, sp: Span, e: Gc<ast::Expr>) -> Gc<ast::Expr> {
self.expr(sp, ast::ExprAddrOf(ast::MutImmutable, e)) self.expr(sp, ast::ExprAddrOf(ast::MutImmutable, e))
} }
fn expr_mut_addr_of(&self, sp: Span, e: @ast::Expr) -> @ast::Expr { fn expr_mut_addr_of(&self, sp: Span, e: Gc<ast::Expr>) -> Gc<ast::Expr> {
self.expr(sp, ast::ExprAddrOf(ast::MutMutable, e)) self.expr(sp, ast::ExprAddrOf(ast::MutMutable, e))
} }
fn expr_call(&self, span: Span, expr: @ast::Expr, args: Vec<@ast::Expr> ) -> @ast::Expr { fn expr_call(&self, span: Span, expr: Gc<ast::Expr>,
args: Vec<Gc<ast::Expr>>) -> Gc<ast::Expr> {
self.expr(span, ast::ExprCall(expr, args)) self.expr(span, ast::ExprCall(expr, args))
} }
fn expr_call_ident(&self, span: Span, id: ast::Ident, args: Vec<@ast::Expr> ) -> @ast::Expr { fn expr_call_ident(&self, span: Span, id: ast::Ident,
args: Vec<Gc<ast::Expr>>) -> Gc<ast::Expr> {
self.expr(span, ast::ExprCall(self.expr_ident(span, id), args)) self.expr(span, ast::ExprCall(self.expr_ident(span, id), args))
} }
fn expr_call_global(&self, sp: Span, fn_path: Vec<ast::Ident> , fn expr_call_global(&self, sp: Span, fn_path: Vec<ast::Ident> ,
args: Vec<@ast::Expr> ) -> @ast::Expr { args: Vec<Gc<ast::Expr>> ) -> Gc<ast::Expr> {
let pathexpr = self.expr_path(self.path_global(sp, fn_path)); let pathexpr = self.expr_path(self.path_global(sp, fn_path));
self.expr_call(sp, pathexpr, args) self.expr_call(sp, pathexpr, args)
} }
fn expr_method_call(&self, span: Span, fn expr_method_call(&self, span: Span,
expr: @ast::Expr, expr: Gc<ast::Expr>,
ident: ast::Ident, ident: ast::Ident,
mut args: Vec<@ast::Expr> ) -> @ast::Expr { mut args: Vec<Gc<ast::Expr>> ) -> Gc<ast::Expr> {
let id = Spanned { node: ident, span: span }; let id = Spanned { node: ident, span: span };
args.unshift(expr); args.unshift(expr);
self.expr(span, ast::ExprMethodCall(id, Vec::new(), args)) self.expr(span, ast::ExprMethodCall(id, Vec::new(), args))
} }
fn expr_block(&self, b: P<ast::Block>) -> @ast::Expr { fn expr_block(&self, b: P<ast::Block>) -> Gc<ast::Expr> {
self.expr(b.span, ast::ExprBlock(b)) self.expr(b.span, ast::ExprBlock(b))
} }
fn field_imm(&self, span: Span, name: Ident, e: @ast::Expr) -> ast::Field { fn field_imm(&self, span: Span, name: Ident, e: Gc<ast::Expr>) -> ast::Field {
ast::Field { ident: respan(span, name), expr: e, span: span } ast::Field { ident: respan(span, name), expr: e, span: span }
} }
fn expr_struct(&self, span: Span, path: ast::Path, fields: Vec<ast::Field> ) -> @ast::Expr { fn expr_struct(&self, span: Span, path: ast::Path, fields: Vec<ast::Field> ) -> Gc<ast::Expr> {
self.expr(span, ast::ExprStruct(path, fields, None)) self.expr(span, ast::ExprStruct(path, fields, None))
} }
fn expr_struct_ident(&self, span: Span, fn expr_struct_ident(&self, span: Span,
id: ast::Ident, fields: Vec<ast::Field> ) -> @ast::Expr { id: ast::Ident, fields: Vec<ast::Field> ) -> Gc<ast::Expr> {
self.expr_struct(span, self.path_ident(span, id), fields) self.expr_struct(span, self.path_ident(span, id), fields)
} }
fn expr_lit(&self, sp: Span, lit: ast::Lit_) -> @ast::Expr { fn expr_lit(&self, sp: Span, lit: ast::Lit_) -> Gc<ast::Expr> {
self.expr(sp, ast::ExprLit(@respan(sp, lit))) self.expr(sp, ast::ExprLit(box(GC) respan(sp, lit)))
} }
fn expr_uint(&self, span: Span, i: uint) -> @ast::Expr { fn expr_uint(&self, span: Span, i: uint) -> Gc<ast::Expr> {
self.expr_lit(span, ast::LitUint(i as u64, ast::TyU)) self.expr_lit(span, ast::LitUint(i as u64, ast::TyU))
} }
fn expr_int(&self, sp: Span, i: int) -> @ast::Expr { fn expr_int(&self, sp: Span, i: int) -> Gc<ast::Expr> {
self.expr_lit(sp, ast::LitInt(i as i64, ast::TyI)) self.expr_lit(sp, ast::LitInt(i as i64, ast::TyI))
} }
fn expr_u8(&self, sp: Span, u: u8) -> @ast::Expr { fn expr_u8(&self, sp: Span, u: u8) -> Gc<ast::Expr> {
self.expr_lit(sp, ast::LitUint(u as u64, ast::TyU8)) self.expr_lit(sp, ast::LitUint(u as u64, ast::TyU8))
} }
fn expr_bool(&self, sp: Span, value: bool) -> @ast::Expr { fn expr_bool(&self, sp: Span, value: bool) -> Gc<ast::Expr> {
self.expr_lit(sp, ast::LitBool(value)) self.expr_lit(sp, ast::LitBool(value))
} }
fn expr_vstore(&self, sp: Span, expr: @ast::Expr, vst: ast::ExprVstore) -> @ast::Expr { fn expr_vstore(&self, sp: Span, expr: Gc<ast::Expr>, vst: ast::ExprVstore) -> Gc<ast::Expr> {
self.expr(sp, ast::ExprVstore(expr, vst)) self.expr(sp, ast::ExprVstore(expr, vst))
} }
fn expr_vec(&self, sp: Span, exprs: Vec<@ast::Expr> ) -> @ast::Expr { fn expr_vec(&self, sp: Span, exprs: Vec<Gc<ast::Expr>> ) -> Gc<ast::Expr> {
self.expr(sp, ast::ExprVec(exprs)) self.expr(sp, ast::ExprVec(exprs))
} }
fn expr_vec_ng(&self, sp: Span) -> @ast::Expr { fn expr_vec_ng(&self, sp: Span) -> Gc<ast::Expr> {
self.expr_call_global(sp, self.expr_call_global(sp,
vec!(self.ident_of("std"), vec!(self.ident_of("std"),
self.ident_of("vec"), self.ident_of("vec"),
@ -594,23 +617,23 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
self.ident_of("new")), self.ident_of("new")),
Vec::new()) Vec::new())
} }
fn expr_vec_slice(&self, sp: Span, exprs: Vec<@ast::Expr> ) -> @ast::Expr { fn expr_vec_slice(&self, sp: Span, exprs: Vec<Gc<ast::Expr>> ) -> Gc<ast::Expr> {
self.expr_vstore(sp, self.expr_vec(sp, exprs), ast::ExprVstoreSlice) self.expr_vstore(sp, self.expr_vec(sp, exprs), ast::ExprVstoreSlice)
} }
fn expr_str(&self, sp: Span, s: InternedString) -> @ast::Expr { fn expr_str(&self, sp: Span, s: InternedString) -> Gc<ast::Expr> {
self.expr_lit(sp, ast::LitStr(s, ast::CookedStr)) self.expr_lit(sp, ast::LitStr(s, ast::CookedStr))
} }
fn expr_str_uniq(&self, sp: Span, s: InternedString) -> @ast::Expr { fn expr_str_uniq(&self, sp: Span, s: InternedString) -> Gc<ast::Expr> {
self.expr_vstore(sp, self.expr_str(sp, s), ast::ExprVstoreUniq) self.expr_vstore(sp, self.expr_str(sp, s), ast::ExprVstoreUniq)
} }
fn expr_cast(&self, sp: Span, expr: @ast::Expr, ty: P<ast::Ty>) -> @ast::Expr { fn expr_cast(&self, sp: Span, expr: Gc<ast::Expr>, ty: P<ast::Ty>) -> Gc<ast::Expr> {
self.expr(sp, ast::ExprCast(expr, ty)) self.expr(sp, ast::ExprCast(expr, ty))
} }
fn expr_some(&self, sp: Span, expr: @ast::Expr) -> @ast::Expr { fn expr_some(&self, sp: Span, expr: Gc<ast::Expr>) -> Gc<ast::Expr> {
let some = vec!( let some = vec!(
self.ident_of("std"), self.ident_of("std"),
self.ident_of("option"), self.ident_of("option"),
@ -618,7 +641,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
self.expr_call_global(sp, some, vec!(expr)) self.expr_call_global(sp, some, vec!(expr))
} }
fn expr_none(&self, sp: Span) -> @ast::Expr { fn expr_none(&self, sp: Span) -> Gc<ast::Expr> {
let none = self.path_global(sp, vec!( let none = self.path_global(sp, vec!(
self.ident_of("std"), self.ident_of("std"),
self.ident_of("option"), self.ident_of("option"),
@ -626,7 +649,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
self.expr_path(none) self.expr_path(none)
} }
fn expr_fail(&self, span: Span, msg: InternedString) -> @ast::Expr { fn expr_fail(&self, span: Span, msg: InternedString) -> Gc<ast::Expr> {
let loc = self.codemap().lookup_char_pos(span.lo); let loc = self.codemap().lookup_char_pos(span.lo);
self.expr_call_global( self.expr_call_global(
span, span,
@ -643,13 +666,13 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
self.expr_uint(span, loc.line))) self.expr_uint(span, loc.line)))
} }
fn expr_unreachable(&self, span: Span) -> @ast::Expr { fn expr_unreachable(&self, span: Span) -> Gc<ast::Expr> {
self.expr_fail(span, self.expr_fail(span,
InternedString::new( InternedString::new(
"internal error: entered unreachable code")) "internal error: entered unreachable code"))
} }
fn expr_ok(&self, sp: Span, expr: @ast::Expr) -> @ast::Expr { fn expr_ok(&self, sp: Span, expr: Gc<ast::Expr>) -> Gc<ast::Expr> {
let ok = vec!( let ok = vec!(
self.ident_of("std"), self.ident_of("std"),
self.ident_of("result"), self.ident_of("result"),
@ -657,7 +680,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
self.expr_call_global(sp, ok, vec!(expr)) self.expr_call_global(sp, ok, vec!(expr))
} }
fn expr_err(&self, sp: Span, expr: @ast::Expr) -> @ast::Expr { fn expr_err(&self, sp: Span, expr: Gc<ast::Expr>) -> Gc<ast::Expr> {
let err = vec!( let err = vec!(
self.ident_of("std"), self.ident_of("std"),
self.ident_of("result"), self.ident_of("result"),
@ -665,7 +688,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
self.expr_call_global(sp, err, vec!(expr)) self.expr_call_global(sp, err, vec!(expr))
} }
fn expr_try(&self, sp: Span, head: @ast::Expr) -> @ast::Expr { fn expr_try(&self, sp: Span, head: Gc<ast::Expr>) -> Gc<ast::Expr> {
let ok = self.ident_of("Ok"); let ok = self.ident_of("Ok");
let ok_path = self.path_ident(sp, ok); let ok_path = self.path_ident(sp, ok);
let err = self.ident_of("Err"); let err = self.ident_of("Err");
@ -694,38 +717,38 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
} }
fn pat(&self, span: Span, pat: ast::Pat_) -> @ast::Pat { fn pat(&self, span: Span, pat: ast::Pat_) -> Gc<ast::Pat> {
@ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span: span } box(GC) ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span: span }
} }
fn pat_wild(&self, span: Span) -> @ast::Pat { fn pat_wild(&self, span: Span) -> Gc<ast::Pat> {
self.pat(span, ast::PatWild) self.pat(span, ast::PatWild)
} }
fn pat_lit(&self, span: Span, expr: @ast::Expr) -> @ast::Pat { fn pat_lit(&self, span: Span, expr: Gc<ast::Expr>) -> Gc<ast::Pat> {
self.pat(span, ast::PatLit(expr)) self.pat(span, ast::PatLit(expr))
} }
fn pat_ident(&self, span: Span, ident: ast::Ident) -> @ast::Pat { fn pat_ident(&self, span: Span, ident: ast::Ident) -> Gc<ast::Pat> {
self.pat_ident_binding_mode(span, ident, ast::BindByValue(ast::MutImmutable)) self.pat_ident_binding_mode(span, ident, ast::BindByValue(ast::MutImmutable))
} }
fn pat_ident_binding_mode(&self, fn pat_ident_binding_mode(&self,
span: Span, span: Span,
ident: ast::Ident, ident: ast::Ident,
bm: ast::BindingMode) -> @ast::Pat { bm: ast::BindingMode) -> Gc<ast::Pat> {
let path = self.path_ident(span, ident); let path = self.path_ident(span, ident);
let pat = ast::PatIdent(bm, path, None); let pat = ast::PatIdent(bm, path, None);
self.pat(span, pat) self.pat(span, pat)
} }
fn pat_enum(&self, span: Span, path: ast::Path, subpats: Vec<@ast::Pat> ) -> @ast::Pat { fn pat_enum(&self, span: Span, path: ast::Path, subpats: Vec<Gc<ast::Pat>> ) -> Gc<ast::Pat> {
let pat = ast::PatEnum(path, Some(subpats)); let pat = ast::PatEnum(path, Some(subpats));
self.pat(span, pat) self.pat(span, pat)
} }
fn pat_struct(&self, span: Span, fn pat_struct(&self, span: Span,
path: ast::Path, field_pats: Vec<ast::FieldPat> ) -> @ast::Pat { path: ast::Path, field_pats: Vec<ast::FieldPat> ) -> Gc<ast::Pat> {
let pat = ast::PatStruct(path, field_pats, false); let pat = ast::PatStruct(path, field_pats, false);
self.pat(span, pat) self.pat(span, pat)
} }
fn arm(&self, _span: Span, pats: Vec<@ast::Pat> , expr: @ast::Expr) -> ast::Arm { fn arm(&self, _span: Span, pats: Vec<Gc<ast::Pat>> , expr: Gc<ast::Expr>) -> ast::Arm {
ast::Arm { ast::Arm {
attrs: vec!(), attrs: vec!(),
pats: pats, pats: pats,
@ -738,56 +761,60 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
self.arm(span, vec!(self.pat_wild(span)), self.expr_unreachable(span)) self.arm(span, vec!(self.pat_wild(span)), self.expr_unreachable(span))
} }
fn expr_match(&self, span: Span, arg: @ast::Expr, arms: Vec<ast::Arm> ) -> @Expr { fn expr_match(&self, span: Span, arg: Gc<ast::Expr>,
arms: Vec<ast::Arm>) -> Gc<Expr> {
self.expr(span, ast::ExprMatch(arg, arms)) self.expr(span, ast::ExprMatch(arg, arms))
} }
fn expr_if(&self, span: Span, fn expr_if(&self, span: Span,
cond: @ast::Expr, then: @ast::Expr, els: Option<@ast::Expr>) -> @ast::Expr { cond: Gc<ast::Expr>, then: Gc<ast::Expr>,
els: Option<Gc<ast::Expr>>) -> Gc<ast::Expr> {
let els = els.map(|x| self.expr_block(self.block_expr(x))); let els = els.map(|x| self.expr_block(self.block_expr(x)));
self.expr(span, ast::ExprIf(cond, self.block_expr(then), els)) self.expr(span, ast::ExprIf(cond, self.block_expr(then), els))
} }
fn lambda_fn_decl(&self, span: Span, fn lambda_fn_decl(&self, span: Span,
fn_decl: P<ast::FnDecl>, blk: P<ast::Block>) -> @ast::Expr { fn_decl: P<ast::FnDecl>, blk: P<ast::Block>) -> Gc<ast::Expr> {
self.expr(span, ast::ExprFnBlock(fn_decl, blk)) self.expr(span, ast::ExprFnBlock(fn_decl, blk))
} }
fn lambda(&self, span: Span, ids: Vec<ast::Ident> , blk: P<ast::Block>) -> @ast::Expr { fn lambda(&self, span: Span, ids: Vec<ast::Ident> , blk: P<ast::Block>) -> Gc<ast::Expr> {
let fn_decl = self.fn_decl( let fn_decl = self.fn_decl(
ids.iter().map(|id| self.arg(span, *id, self.ty_infer(span))).collect(), ids.iter().map(|id| self.arg(span, *id, self.ty_infer(span))).collect(),
self.ty_infer(span)); self.ty_infer(span));
self.expr(span, ast::ExprFnBlock(fn_decl, blk)) self.expr(span, ast::ExprFnBlock(fn_decl, blk))
} }
fn lambda0(&self, span: Span, blk: P<ast::Block>) -> @ast::Expr { fn lambda0(&self, span: Span, blk: P<ast::Block>) -> Gc<ast::Expr> {
self.lambda(span, Vec::new(), blk) self.lambda(span, Vec::new(), blk)
} }
fn lambda1(&self, span: Span, blk: P<ast::Block>, ident: ast::Ident) -> @ast::Expr { fn lambda1(&self, span: Span, blk: P<ast::Block>, ident: ast::Ident) -> Gc<ast::Expr> {
self.lambda(span, vec!(ident), blk) self.lambda(span, vec!(ident), blk)
} }
fn lambda_expr(&self, span: Span, ids: Vec<ast::Ident> , expr: @ast::Expr) -> @ast::Expr { fn lambda_expr(&self, span: Span, ids: Vec<ast::Ident> , expr: Gc<ast::Expr>) -> Gc<ast::Expr> {
self.lambda(span, ids, self.block_expr(expr)) self.lambda(span, ids, self.block_expr(expr))
} }
fn lambda_expr_0(&self, span: Span, expr: @ast::Expr) -> @ast::Expr { fn lambda_expr_0(&self, span: Span, expr: Gc<ast::Expr>) -> Gc<ast::Expr> {
self.lambda0(span, self.block_expr(expr)) self.lambda0(span, self.block_expr(expr))
} }
fn lambda_expr_1(&self, span: Span, expr: @ast::Expr, ident: ast::Ident) -> @ast::Expr { fn lambda_expr_1(&self, span: Span, expr: Gc<ast::Expr>, ident: ast::Ident) -> Gc<ast::Expr> {
self.lambda1(span, self.block_expr(expr), ident) self.lambda1(span, self.block_expr(expr), ident)
} }
fn lambda_stmts(&self, fn lambda_stmts(&self,
span: Span, span: Span,
ids: Vec<ast::Ident>, ids: Vec<ast::Ident>,
stmts: Vec<@ast::Stmt>) stmts: Vec<Gc<ast::Stmt>>)
-> @ast::Expr { -> Gc<ast::Expr> {
self.lambda(span, ids, self.block(span, stmts, None)) self.lambda(span, ids, self.block(span, stmts, None))
} }
fn lambda_stmts_0(&self, span: Span, stmts: Vec<@ast::Stmt> ) -> @ast::Expr { fn lambda_stmts_0(&self, span: Span,
stmts: Vec<Gc<ast::Stmt>>) -> Gc<ast::Expr> {
self.lambda0(span, self.block(span, stmts, None)) self.lambda0(span, self.block(span, stmts, None))
} }
fn lambda_stmts_1(&self, span: Span, stmts: Vec<@ast::Stmt> , ident: ast::Ident) -> @ast::Expr { fn lambda_stmts_1(&self, span: Span, stmts: Vec<Gc<ast::Stmt>>,
ident: ast::Ident) -> Gc<ast::Expr> {
self.lambda1(span, self.block(span, stmts, None), ident) self.lambda1(span, self.block(span, stmts, None), ident)
} }
@ -811,10 +838,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
} }
fn item(&self, span: Span, fn item(&self, span: Span,
name: Ident, attrs: Vec<ast::Attribute> , node: ast::Item_) -> @ast::Item { name: Ident, attrs: Vec<ast::Attribute>,
node: ast::Item_) -> Gc<ast::Item> {
// FIXME: Would be nice if our generated code didn't violate // FIXME: Would be nice if our generated code didn't violate
// Rust coding conventions // Rust coding conventions
@ast::Item { ident: name, box(GC) ast::Item { ident: name,
attrs: attrs, attrs: attrs,
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: node, node: node,
@ -828,7 +856,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
inputs: Vec<ast::Arg> , inputs: Vec<ast::Arg> ,
output: P<ast::Ty>, output: P<ast::Ty>,
generics: Generics, generics: Generics,
body: P<ast::Block>) -> @ast::Item { body: P<ast::Block>) -> Gc<ast::Item> {
self.item(span, self.item(span,
name, name,
Vec::new(), Vec::new(),
@ -845,7 +873,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
inputs: Vec<ast::Arg> , inputs: Vec<ast::Arg> ,
output: P<ast::Ty>, output: P<ast::Ty>,
body: P<ast::Block> body: P<ast::Block>
) -> @ast::Item { ) -> Gc<ast::Item> {
self.item_fn_poly( self.item_fn_poly(
span, span,
name, name,
@ -873,18 +901,18 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
fn item_enum_poly(&self, span: Span, name: Ident, fn item_enum_poly(&self, span: Span, name: Ident,
enum_definition: ast::EnumDef, enum_definition: ast::EnumDef,
generics: Generics) -> @ast::Item { generics: Generics) -> Gc<ast::Item> {
self.item(span, name, Vec::new(), ast::ItemEnum(enum_definition, generics)) self.item(span, name, Vec::new(), ast::ItemEnum(enum_definition, generics))
} }
fn item_enum(&self, span: Span, name: Ident, fn item_enum(&self, span: Span, name: Ident,
enum_definition: ast::EnumDef) -> @ast::Item { enum_definition: ast::EnumDef) -> Gc<ast::Item> {
self.item_enum_poly(span, name, enum_definition, self.item_enum_poly(span, name, enum_definition,
ast_util::empty_generics()) ast_util::empty_generics())
} }
fn item_struct(&self, span: Span, name: Ident, fn item_struct(&self, span: Span, name: Ident,
struct_def: ast::StructDef) -> @ast::Item { struct_def: ast::StructDef) -> Gc<ast::Item> {
self.item_struct_poly( self.item_struct_poly(
span, span,
name, name,
@ -894,14 +922,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
} }
fn item_struct_poly(&self, span: Span, name: Ident, fn item_struct_poly(&self, span: Span, name: Ident,
struct_def: ast::StructDef, generics: Generics) -> @ast::Item { struct_def: ast::StructDef, generics: Generics) -> Gc<ast::Item> {
self.item(span, name, Vec::new(), ast::ItemStruct(@struct_def, generics)) self.item(span, name, Vec::new(), ast::ItemStruct(box(GC) struct_def, generics))
} }
fn item_mod(&self, span: Span, inner_span: Span, name: Ident, fn item_mod(&self, span: Span, inner_span: Span, name: Ident,
attrs: Vec<ast::Attribute> , attrs: Vec<ast::Attribute> ,
vi: Vec<ast::ViewItem> , vi: Vec<ast::ViewItem> ,
items: Vec<@ast::Item> ) -> @ast::Item { items: Vec<Gc<ast::Item>>) -> Gc<ast::Item> {
self.item( self.item(
span, span,
name, name,
@ -915,15 +943,15 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
} }
fn item_ty_poly(&self, span: Span, name: Ident, ty: P<ast::Ty>, fn item_ty_poly(&self, span: Span, name: Ident, ty: P<ast::Ty>,
generics: Generics) -> @ast::Item { generics: Generics) -> Gc<ast::Item> {
self.item(span, name, Vec::new(), ast::ItemTy(ty, generics)) self.item(span, name, Vec::new(), ast::ItemTy(ty, generics))
} }
fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> @ast::Item { fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> Gc<ast::Item> {
self.item_ty_poly(span, name, ty, ast_util::empty_generics()) self.item_ty_poly(span, name, ty, ast_util::empty_generics())
} }
fn attribute(&self, sp: Span, mi: @ast::MetaItem) -> ast::Attribute { fn attribute(&self, sp: Span, mi: Gc<ast::MetaItem>) -> ast::Attribute {
respan(sp, ast::Attribute_ { respan(sp, ast::Attribute_ {
id: attr::mk_attr_id(), id: attr::mk_attr_id(),
style: ast::AttrOuter, style: ast::AttrOuter,
@ -932,26 +960,26 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
}) })
} }
fn meta_word(&self, sp: Span, w: InternedString) -> @ast::MetaItem { fn meta_word(&self, sp: Span, w: InternedString) -> Gc<ast::MetaItem> {
@respan(sp, ast::MetaWord(w)) box(GC) respan(sp, ast::MetaWord(w))
} }
fn meta_list(&self, fn meta_list(&self,
sp: Span, sp: Span,
name: InternedString, name: InternedString,
mis: Vec<@ast::MetaItem> ) mis: Vec<Gc<ast::MetaItem>> )
-> @ast::MetaItem { -> Gc<ast::MetaItem> {
@respan(sp, ast::MetaList(name, mis)) box(GC) respan(sp, ast::MetaList(name, mis))
} }
fn meta_name_value(&self, fn meta_name_value(&self,
sp: Span, sp: Span,
name: InternedString, name: InternedString,
value: ast::Lit_) value: ast::Lit_)
-> @ast::MetaItem { -> Gc<ast::MetaItem> {
@respan(sp, ast::MetaNameValue(name, respan(sp, value))) box(GC) respan(sp, ast::MetaNameValue(name, respan(sp, value)))
} }
fn view_use(&self, sp: Span, fn view_use(&self, sp: Span,
vis: ast::Visibility, vp: @ast::ViewPath) -> ast::ViewItem { vis: ast::Visibility, vp: Gc<ast::ViewPath>) -> ast::ViewItem {
ast::ViewItem { ast::ViewItem {
node: ast::ViewItemUse(vp), node: ast::ViewItemUse(vp),
attrs: Vec::new(), attrs: Vec::new(),
@ -968,7 +996,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
fn view_use_simple_(&self, sp: Span, vis: ast::Visibility, fn view_use_simple_(&self, sp: Span, vis: ast::Visibility,
ident: ast::Ident, path: ast::Path) -> ast::ViewItem { ident: ast::Ident, path: ast::Path) -> ast::ViewItem {
self.view_use(sp, vis, self.view_use(sp, vis,
@respan(sp, box(GC) respan(sp,
ast::ViewPathSimple(ident, ast::ViewPathSimple(ident,
path, path,
ast::DUMMY_NODE_ID))) ast::DUMMY_NODE_ID)))
@ -981,7 +1009,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
}).collect(); }).collect();
self.view_use(sp, vis, self.view_use(sp, vis,
@respan(sp, box(GC) respan(sp,
ast::ViewPathList(self.path(sp, path), ast::ViewPathList(self.path(sp, path),
imports, imports,
ast::DUMMY_NODE_ID))) ast::DUMMY_NODE_ID)))
@ -990,7 +1018,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
fn view_use_glob(&self, sp: Span, fn view_use_glob(&self, sp: Span,
vis: ast::Visibility, path: Vec<ast::Ident> ) -> ast::ViewItem { vis: ast::Visibility, path: Vec<ast::Ident> ) -> ast::ViewItem {
self.view_use(sp, vis, self.view_use(sp, vis,
@respan(sp, box(GC) respan(sp,
ast::ViewPathGlob(self.path(sp, path), ast::DUMMY_NODE_ID))) ast::ViewPathGlob(self.path(sp, path), ast::DUMMY_NODE_ID)))
} }
} }
@ -1013,8 +1041,8 @@ pub trait Duplicate {
fn duplicate(&self, cx: &ExtCtxt) -> Self; fn duplicate(&self, cx: &ExtCtxt) -> Self;
} }
impl Duplicate for @ast::Expr { impl Duplicate for Gc<ast::Expr> {
fn duplicate(&self, _: &ExtCtxt) -> @ast::Expr { fn duplicate(&self, _: &ExtCtxt) -> Gc<ast::Expr> {
let mut folder = Duplicator; let mut folder = Duplicator;
folder.fold_expr(*self) folder.fold_expr(*self)
} }

View file

@ -44,7 +44,7 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
} }
let res = str_to_ident(res_str.as_slice()); let res = str_to_ident(res_str.as_slice());
let e = @ast::Expr { let e = box(GC) ast::Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::ExprPath( node: ast::ExprPath(
ast::Path { ast::Path {

View file

@ -14,11 +14,13 @@ use ext::base::ExtCtxt;
use ext::deriving::generic::*; use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use std::gc::Gc;
pub fn expand_deriving_bound(cx: &mut ExtCtxt, pub fn expand_deriving_bound(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
let name = match mitem.node { let name = match mitem.node {
MetaWord(ref tname) => { MetaWord(ref tname) => {

View file

@ -16,11 +16,13 @@ use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use std::gc::Gc;
pub fn expand_deriving_clone(cx: &mut ExtCtxt, pub fn expand_deriving_clone(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
let inline = cx.meta_word(span, InternedString::new("inline")); let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline)); let attrs = vec!(cx.attribute(span, inline));
let trait_def = TraitDef { let trait_def = TraitDef {
@ -51,7 +53,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt,
fn cs_clone( fn cs_clone(
name: &str, name: &str,
cx: &mut ExtCtxt, trait_span: Span, cx: &mut ExtCtxt, trait_span: Span,
substr: &Substructure) -> @Expr { substr: &Substructure) -> Gc<Expr> {
let clone_ident = substr.method_ident; let clone_ident = substr.method_ident;
let ctor_ident; let ctor_ident;
let all_fields; let all_fields;

View file

@ -16,18 +16,20 @@ use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use std::gc::Gc;
pub fn expand_deriving_eq(cx: &mut ExtCtxt, pub fn expand_deriving_eq(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
// structures are equal if all fields are equal, and non equal, if // structures are equal if all fields are equal, and non equal, if
// any fields are not equal or if the enum variants are different // any fields are not equal or if the enum variants are different
fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr { fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> Gc<Expr> {
cs_and(|cx, span, _, _| cx.expr_bool(span, false), cs_and(|cx, span, _, _| cx.expr_bool(span, false),
cx, span, substr) cx, span, substr)
} }
fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr { fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> Gc<Expr> {
cs_or(|cx, span, _, _| cx.expr_bool(span, true), cs_or(|cx, span, _, _| cx.expr_bool(span, true),
cx, span, substr) cx, span, substr)
} }

View file

@ -17,11 +17,13 @@ use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use std::gc::Gc;
pub fn expand_deriving_ord(cx: &mut ExtCtxt, pub fn expand_deriving_ord(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
macro_rules! md ( macro_rules! md (
($name:expr, $op:expr, $equal:expr) => { { ($name:expr, $op:expr, $equal:expr) => { {
let inline = cx.meta_word(span, InternedString::new("inline")); let inline = cx.meta_word(span, InternedString::new("inline"));
@ -58,7 +60,8 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt,
} }
/// Strict inequality. /// Strict inequality.
fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr { fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt, span: Span,
substr: &Substructure) -> Gc<Expr> {
let op = if less {ast::BiLt} else {ast::BiGt}; let op = if less {ast::BiLt} else {ast::BiGt};
cs_fold( cs_fold(
false, // need foldr, false, // need foldr,

View file

@ -16,12 +16,15 @@ use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use std::gc::Gc;
pub fn expand_deriving_totaleq(cx: &mut ExtCtxt, pub fn expand_deriving_totaleq(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr { fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span,
substr: &Substructure) -> Gc<Expr> {
cs_same_method(|cx, span, exprs| { cs_same_method(|cx, span, exprs| {
// create `a.<method>(); b.<method>(); c.<method>(); ...` // create `a.<method>(); b.<method>(); c.<method>(); ...`
// (where method is `assert_receiver_is_total_eq`) // (where method is `assert_receiver_is_total_eq`)

View file

@ -18,12 +18,13 @@ use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use std::cmp::{Ordering, Equal, Less, Greater}; use std::cmp::{Ordering, Equal, Less, Greater};
use std::gc::Gc;
pub fn expand_deriving_totalord(cx: &mut ExtCtxt, pub fn expand_deriving_totalord(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
let inline = cx.meta_word(span, InternedString::new("inline")); let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline)); let attrs = vec!(cx.attribute(span, inline));
let trait_def = TraitDef { let trait_def = TraitDef {
@ -65,7 +66,7 @@ pub fn ordering_const(cx: &mut ExtCtxt, span: Span, cnst: Ordering) -> ast::Path
} }
pub fn cs_cmp(cx: &mut ExtCtxt, span: Span, pub fn cs_cmp(cx: &mut ExtCtxt, span: Span,
substr: &Substructure) -> @Expr { substr: &Substructure) -> Gc<Expr> {
let test_id = cx.ident_of("__test"); let test_id = cx.ident_of("__test");
let equals_path = ordering_const(cx, span, Equal); let equals_path = ordering_const(cx, span, Equal);

View file

@ -23,11 +23,13 @@ use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use parse::token; use parse::token;
use std::gc::Gc;
pub fn expand_deriving_decodable(cx: &mut ExtCtxt, pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
let trait_def = TraitDef { let trait_def = TraitDef {
span: span, span: span,
attributes: Vec::new(), attributes: Vec::new(),
@ -64,7 +66,7 @@ pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
} }
fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span, fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
substr: &Substructure) -> @Expr { substr: &Substructure) -> Gc<Expr> {
let decoder = substr.nonself_args[0]; let decoder = substr.nonself_args[0];
let recurse = vec!(cx.ident_of("serialize"), let recurse = vec!(cx.ident_of("serialize"),
cx.ident_of("Decodable"), cx.ident_of("Decodable"),
@ -159,8 +161,8 @@ fn decode_static_fields(cx: &mut ExtCtxt,
trait_span: Span, trait_span: Span,
outer_pat_ident: Ident, outer_pat_ident: Ident,
fields: &StaticFields, fields: &StaticFields,
getarg: |&mut ExtCtxt, Span, InternedString, uint| -> @Expr) getarg: |&mut ExtCtxt, Span, InternedString, uint| -> Gc<Expr>)
-> @Expr { -> Gc<Expr> {
match *fields { match *fields {
Unnamed(ref fields) => { Unnamed(ref fields) => {
if fields.is_empty() { if fields.is_empty() {

View file

@ -16,11 +16,13 @@ use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use std::gc::Gc;
pub fn expand_deriving_default(cx: &mut ExtCtxt, pub fn expand_deriving_default(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
let inline = cx.meta_word(span, InternedString::new("inline")); let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline)); let attrs = vec!(cx.attribute(span, inline));
let trait_def = TraitDef { let trait_def = TraitDef {
@ -46,7 +48,8 @@ pub fn expand_deriving_default(cx: &mut ExtCtxt,
trait_def.expand(cx, mitem, item, push) trait_def.expand(cx, mitem, item, push)
} }
fn default_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { fn default_substructure(cx: &mut ExtCtxt, trait_span: Span,
substr: &Substructure) -> Gc<Expr> {
let default_ident = vec!( let default_ident = vec!(
cx.ident_of("std"), cx.ident_of("std"),
cx.ident_of("default"), cx.ident_of("default"),

View file

@ -91,11 +91,13 @@ use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token; use parse::token;
use std::gc::Gc;
pub fn expand_deriving_encodable(cx: &mut ExtCtxt, pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
let trait_def = TraitDef { let trait_def = TraitDef {
span: span, span: span,
attributes: Vec::new(), attributes: Vec::new(),
@ -134,7 +136,7 @@ pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
} }
fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span, fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
substr: &Substructure) -> @Expr { substr: &Substructure) -> Gc<Expr> {
let encoder = substr.nonself_args[0]; let encoder = substr.nonself_args[0];
// throw an underscore in front to suppress unused variable warnings // throw an underscore in front to suppress unused variable warnings
let blkarg = cx.ident_of("_e"); let blkarg = cx.ident_of("_e");

View file

@ -178,6 +178,7 @@ StaticEnum(<ast::EnumDef of C>, ~[(<ident of C0>, <span of C0>, Unnamed(~[<span
*/ */
use std::cell::RefCell; use std::cell::RefCell;
use std::gc::Gc;
use ast; use ast;
use ast::{P, EnumDef, Expr, Ident, Generics, StructDef}; use ast::{P, EnumDef, Expr, Ident, Generics, StructDef};
@ -248,9 +249,9 @@ pub struct Substructure<'a> {
/// ident of the method /// ident of the method
pub method_ident: Ident, pub method_ident: Ident,
/// dereferenced access to any Self or Ptr(Self, _) arguments /// dereferenced access to any Self or Ptr(Self, _) arguments
pub self_args: &'a [@Expr], pub self_args: &'a [Gc<Expr>],
/// verbatim access to any other arguments /// verbatim access to any other arguments
pub nonself_args: &'a [@Expr], pub nonself_args: &'a [Gc<Expr>],
pub fields: &'a SubstructureFields<'a> pub fields: &'a SubstructureFields<'a>
} }
@ -262,42 +263,43 @@ pub struct FieldInfo {
pub name: Option<Ident>, pub name: Option<Ident>,
/// The expression corresponding to this field of `self` /// The expression corresponding to this field of `self`
/// (specifically, a reference to it). /// (specifically, a reference to it).
pub self_: @Expr, pub self_: Gc<Expr>,
/// The expressions corresponding to references to this field in /// The expressions corresponding to references to this field in
/// the other Self arguments. /// the other Self arguments.
pub other: Vec<@Expr>, pub other: Vec<Gc<Expr>>,
} }
/// Fields for a static method /// Fields for a static method
pub enum StaticFields { pub enum StaticFields {
/// Tuple structs/enum variants like this /// Tuple structs/enum variants like this
Unnamed(Vec<Span> ), Unnamed(Vec<Span>),
/// Normal structs/struct variants. /// Normal structs/struct variants.
Named(Vec<(Ident, Span)> ) Named(Vec<(Ident, Span)>),
} }
/// A summary of the possible sets of fields. See above for details /// A summary of the possible sets of fields. See above for details
/// and examples /// and examples
pub enum SubstructureFields<'a> { pub enum SubstructureFields<'a> {
Struct(Vec<FieldInfo> ), Struct(Vec<FieldInfo>),
/** /**
Matching variants of the enum: variant index, ast::Variant, Matching variants of the enum: variant index, ast::Variant,
fields: the field name is only non-`None` in the case of a struct fields: the field name is only non-`None` in the case of a struct
variant. variant.
*/ */
EnumMatching(uint, &'a ast::Variant, Vec<FieldInfo> ), EnumMatching(uint, &'a ast::Variant, Vec<FieldInfo>),
/** /**
non-matching variants of the enum, [(variant index, ast::Variant, non-matching variants of the enum, [(variant index, ast::Variant,
[field span, field ident, fields])] \(i.e. all fields for self are in the [field span, field ident, fields])] \(i.e. all fields for self are in the
first tuple, for other1 are in the second tuple, etc.) first tuple, for other1 are in the second tuple, etc.)
*/ */
EnumNonMatching(&'a [(uint, P<ast::Variant>, Vec<(Span, Option<Ident>, @Expr)> )]), EnumNonMatching(&'a [(uint, P<ast::Variant>,
Vec<(Span, Option<Ident>, Gc<Expr>)>)]),
/// A static method where Self is a struct. /// A static method where Self is a struct.
StaticStruct(&'a ast::StructDef, StaticFields), StaticStruct(&'a ast::StructDef, StaticFields),
/// A static method where Self is an enum. /// A static method where Self is an enum.
StaticEnum(&'a ast::EnumDef, Vec<(Ident, Span, StaticFields)> ) StaticEnum(&'a ast::EnumDef, Vec<(Ident, Span, StaticFields)>),
} }
@ -307,7 +309,7 @@ Combine the values of all the fields together. The last argument is
all the fields of all the structures, see above for details. all the fields of all the structures, see above for details.
*/ */
pub type CombineSubstructureFunc<'a> = pub type CombineSubstructureFunc<'a> =
|&mut ExtCtxt, Span, &Substructure|: 'a -> @Expr; |&mut ExtCtxt, Span, &Substructure|: 'a -> Gc<Expr>;
/** /**
Deal with non-matching enum variants, the arguments are a list Deal with non-matching enum variants, the arguments are a list
@ -317,9 +319,9 @@ representing each variant: (variant index, ast::Variant instance,
pub type EnumNonMatchFunc<'a> = pub type EnumNonMatchFunc<'a> =
|&mut ExtCtxt, |&mut ExtCtxt,
Span, Span,
&[(uint, P<ast::Variant>, Vec<(Span, Option<Ident>, @Expr)> )], &[(uint, P<ast::Variant>, Vec<(Span, Option<Ident>, Gc<Expr>)>)],
&[@Expr]|: 'a &[Gc<Expr>]|: 'a
-> @Expr; -> Gc<Expr>;
pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>) pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
-> RefCell<CombineSubstructureFunc<'a>> { -> RefCell<CombineSubstructureFunc<'a>> {
@ -330,13 +332,13 @@ pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
impl<'a> TraitDef<'a> { impl<'a> TraitDef<'a> {
pub fn expand(&self, pub fn expand(&self,
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
_mitem: @ast::MetaItem, _mitem: Gc<ast::MetaItem>,
item: @ast::Item, item: Gc<ast::Item>,
push: |@ast::Item|) { push: |Gc<ast::Item>|) {
let newitem = match item.node { let newitem = match item.node {
ast::ItemStruct(struct_def, ref generics) => { ast::ItemStruct(ref struct_def, ref generics) => {
self.expand_struct_def(cx, self.expand_struct_def(cx,
struct_def, &**struct_def,
item.ident, item.ident,
generics) generics)
} }
@ -357,7 +359,7 @@ impl<'a> TraitDef<'a> {
_ => false, _ => false,
} }
}).map(|a| a.clone())); }).map(|a| a.clone()));
push(@ast::Item { push(box(GC) ast::Item {
attrs: attrs, attrs: attrs,
..(*newitem).clone() ..(*newitem).clone()
}) })
@ -379,7 +381,7 @@ impl<'a> TraitDef<'a> {
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
type_ident: Ident, type_ident: Ident,
generics: &Generics, generics: &Generics,
methods: Vec<@ast::Method> ) -> @ast::Item { methods: Vec<Gc<ast::Method>> ) -> Gc<ast::Item> {
let trait_path = self.path.to_path(cx, self.span, type_ident, generics); let trait_path = self.path.to_path(cx, self.span, type_ident, generics);
let Generics { mut lifetimes, ty_params } = let Generics { mut lifetimes, ty_params } =
@ -435,7 +437,7 @@ impl<'a> TraitDef<'a> {
// Just mark it now since we know that it'll end up used downstream // Just mark it now since we know that it'll end up used downstream
attr::mark_used(&attr); attr::mark_used(&attr);
let opt_trait_ref = Some(trait_ref); let opt_trait_ref = Some(trait_ref);
let ident = ast_util::impl_pretty_name(&opt_trait_ref, self_type); let ident = ast_util::impl_pretty_name(&opt_trait_ref, &*self_type);
cx.item( cx.item(
self.span, self.span,
ident, ident,
@ -448,7 +450,7 @@ impl<'a> TraitDef<'a> {
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
struct_def: &StructDef, struct_def: &StructDef,
type_ident: Ident, type_ident: Ident,
generics: &Generics) -> @ast::Item { generics: &Generics) -> Gc<ast::Item> {
let methods = self.methods.iter().map(|method_def| { let methods = self.methods.iter().map(|method_def| {
let (explicit_self, self_args, nonself_args, tys) = let (explicit_self, self_args, nonself_args, tys) =
method_def.split_self_nonself_args( method_def.split_self_nonself_args(
@ -484,7 +486,7 @@ impl<'a> TraitDef<'a> {
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
enum_def: &EnumDef, enum_def: &EnumDef,
type_ident: Ident, type_ident: Ident,
generics: &Generics) -> @ast::Item { generics: &Generics) -> Gc<ast::Item> {
let methods = self.methods.iter().map(|method_def| { let methods = self.methods.iter().map(|method_def| {
let (explicit_self, self_args, nonself_args, tys) = let (explicit_self, self_args, nonself_args, tys) =
method_def.split_self_nonself_args(cx, self, method_def.split_self_nonself_args(cx, self,
@ -522,10 +524,10 @@ impl<'a> MethodDef<'a> {
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
trait_: &TraitDef, trait_: &TraitDef,
type_ident: Ident, type_ident: Ident,
self_args: &[@Expr], self_args: &[Gc<Expr>],
nonself_args: &[@Expr], nonself_args: &[Gc<Expr>],
fields: &SubstructureFields) fields: &SubstructureFields)
-> @Expr { -> Gc<Expr> {
let substructure = Substructure { let substructure = Substructure {
type_ident: type_ident, type_ident: type_ident,
method_ident: cx.ident_of(self.name), method_ident: cx.ident_of(self.name),
@ -556,7 +558,8 @@ impl<'a> MethodDef<'a> {
trait_: &TraitDef, trait_: &TraitDef,
type_ident: Ident, type_ident: Ident,
generics: &Generics) generics: &Generics)
-> (ast::ExplicitSelf, Vec<@Expr> , Vec<@Expr> , Vec<(Ident, P<ast::Ty>)> ) { -> (ast::ExplicitSelf, Vec<Gc<Expr>>, Vec<Gc<Expr>>,
Vec<(Ident, P<ast::Ty>)>) {
let mut self_args = Vec::new(); let mut self_args = Vec::new();
let mut nonself_args = Vec::new(); let mut nonself_args = Vec::new();
@ -608,7 +611,7 @@ impl<'a> MethodDef<'a> {
generics: &Generics, generics: &Generics,
explicit_self: ast::ExplicitSelf, explicit_self: ast::ExplicitSelf,
arg_types: Vec<(Ident, P<ast::Ty>)> , arg_types: Vec<(Ident, P<ast::Ty>)> ,
body: @Expr) -> @ast::Method { body: Gc<Expr>) -> Gc<ast::Method> {
// create the generics that aren't for Self // create the generics that aren't for Self
let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics); let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics);
@ -630,7 +633,7 @@ impl<'a> MethodDef<'a> {
let body_block = cx.block_expr(body); let body_block = cx.block_expr(body);
// Create the method. // Create the method.
@ast::Method { box(GC) ast::Method {
ident: method_ident, ident: method_ident,
attrs: self.attributes.clone(), attrs: self.attributes.clone(),
generics: fn_generics, generics: fn_generics,
@ -670,9 +673,9 @@ impl<'a> MethodDef<'a> {
trait_: &TraitDef, trait_: &TraitDef,
struct_def: &StructDef, struct_def: &StructDef,
type_ident: Ident, type_ident: Ident,
self_args: &[@Expr], self_args: &[Gc<Expr>],
nonself_args: &[@Expr]) nonself_args: &[Gc<Expr>])
-> @Expr { -> Gc<Expr> {
let mut raw_fields = Vec::new(); // ~[[fields of self], let mut raw_fields = Vec::new(); // ~[[fields of self],
// [fields of next Self arg], [etc]] // [fields of next Self arg], [etc]]
@ -737,9 +740,9 @@ impl<'a> MethodDef<'a> {
trait_: &TraitDef, trait_: &TraitDef,
struct_def: &StructDef, struct_def: &StructDef,
type_ident: Ident, type_ident: Ident,
self_args: &[@Expr], self_args: &[Gc<Expr>],
nonself_args: &[@Expr]) nonself_args: &[Gc<Expr>])
-> @Expr { -> Gc<Expr> {
let summary = trait_.summarise_struct(cx, struct_def); let summary = trait_.summarise_struct(cx, struct_def);
self.call_substructure_method(cx, self.call_substructure_method(cx,
@ -780,9 +783,9 @@ impl<'a> MethodDef<'a> {
trait_: &TraitDef, trait_: &TraitDef,
enum_def: &EnumDef, enum_def: &EnumDef,
type_ident: Ident, type_ident: Ident,
self_args: &[@Expr], self_args: &[Gc<Expr>],
nonself_args: &[@Expr]) nonself_args: &[Gc<Expr>])
-> @Expr { -> Gc<Expr> {
let mut matches = Vec::new(); let mut matches = Vec::new();
self.build_enum_match(cx, trait_, enum_def, type_ident, self.build_enum_match(cx, trait_, enum_def, type_ident,
self_args, nonself_args, self_args, nonself_args,
@ -816,12 +819,12 @@ impl<'a> MethodDef<'a> {
trait_: &TraitDef, trait_: &TraitDef,
enum_def: &EnumDef, enum_def: &EnumDef,
type_ident: Ident, type_ident: Ident,
self_args: &[@Expr], self_args: &[Gc<Expr>],
nonself_args: &[@Expr], nonself_args: &[Gc<Expr>],
matching: Option<uint>, matching: Option<uint>,
matches_so_far: &mut Vec<(uint, P<ast::Variant>, matches_so_far: &mut Vec<(uint, P<ast::Variant>,
Vec<(Span, Option<Ident>, @Expr)> )> , Vec<(Span, Option<Ident>, Gc<Expr>)>)> ,
match_count: uint) -> @Expr { match_count: uint) -> Gc<Expr> {
if match_count == self_args.len() { if match_count == self_args.len() {
// we've matched against all arguments, so make the final // we've matched against all arguments, so make the final
// expression at the bottom of the match tree // expression at the bottom of the match tree
@ -871,7 +874,7 @@ impl<'a> MethodDef<'a> {
other: (*other).clone() other: (*other).clone()
} }
}).collect(); }).collect();
EnumMatching(variant_index, variant, field_tuples) EnumMatching(variant_index, &*variant, field_tuples)
} }
None => { None => {
EnumNonMatching(matches_so_far.as_slice()) EnumNonMatching(matches_so_far.as_slice())
@ -905,7 +908,7 @@ impl<'a> MethodDef<'a> {
let variant = *enum_def.variants.get(index); let variant = *enum_def.variants.get(index);
let (pattern, idents) = trait_.create_enum_variant_pattern( let (pattern, idents) = trait_.create_enum_variant_pattern(
cx, cx,
variant, &*variant,
current_match_str.as_slice(), current_match_str.as_slice(),
ast::MutImmutable); ast::MutImmutable);
@ -938,7 +941,7 @@ impl<'a> MethodDef<'a> {
let (pattern, idents) = let (pattern, idents) =
trait_.create_enum_variant_pattern( trait_.create_enum_variant_pattern(
cx, cx,
variant, &*variant,
current_match_str.as_slice(), current_match_str.as_slice(),
ast::MutImmutable); ast::MutImmutable);
@ -974,17 +977,17 @@ impl<'a> MethodDef<'a> {
trait_: &TraitDef, trait_: &TraitDef,
enum_def: &EnumDef, enum_def: &EnumDef,
type_ident: Ident, type_ident: Ident,
self_args: &[@Expr], self_args: &[Gc<Expr>],
nonself_args: &[@Expr]) nonself_args: &[Gc<Expr>])
-> @Expr { -> Gc<Expr> {
let summary = enum_def.variants.iter().map(|v| { let summary = enum_def.variants.iter().map(|v| {
let ident = v.node.name; let ident = v.node.name;
let summary = match v.node.kind { let summary = match v.node.kind {
ast::TupleVariantKind(ref args) => { ast::TupleVariantKind(ref args) => {
Unnamed(args.iter().map(|va| trait_.set_expn_info(cx, va.ty.span)).collect()) Unnamed(args.iter().map(|va| trait_.set_expn_info(cx, va.ty.span)).collect())
} }
ast::StructVariantKind(struct_def) => { ast::StructVariantKind(ref struct_def) => {
trait_.summarise_struct(cx, struct_def) trait_.summarise_struct(cx, &**struct_def)
} }
}; };
(ident, v.span, summary) (ident, v.span, summary)
@ -1009,7 +1012,7 @@ impl<'a> TraitDef<'a> {
None => cx.span_bug(self.span, "trait with empty path in generic `deriving`"), None => cx.span_bug(self.span, "trait with empty path in generic `deriving`"),
Some(name) => *name Some(name) => *name
}; };
to_set.expn_info = Some(@codemap::ExpnInfo { to_set.expn_info = Some(box(GC) codemap::ExpnInfo {
call_site: to_set, call_site: to_set,
callee: codemap::NameAndSpan { callee: codemap::NameAndSpan {
name: format!("deriving({})", trait_name).to_string(), name: format!("deriving({})", trait_name).to_string(),
@ -1048,7 +1051,7 @@ impl<'a> TraitDef<'a> {
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
field_paths: Vec<ast::Path> , field_paths: Vec<ast::Path> ,
mutbl: ast::Mutability) mutbl: ast::Mutability)
-> Vec<@ast::Pat> { -> Vec<Gc<ast::Pat>> {
field_paths.iter().map(|path| { field_paths.iter().map(|path| {
cx.pat(path.span, cx.pat(path.span,
ast::PatIdent(ast::BindByRef(mutbl), (*path).clone(), None)) ast::PatIdent(ast::BindByRef(mutbl), (*path).clone(), None))
@ -1061,7 +1064,7 @@ impl<'a> TraitDef<'a> {
struct_def: &StructDef, struct_def: &StructDef,
prefix: &str, prefix: &str,
mutbl: ast::Mutability) mutbl: ast::Mutability)
-> (@ast::Pat, Vec<(Span, Option<Ident>, @Expr)> ) { -> (Gc<ast::Pat>, Vec<(Span, Option<Ident>, Gc<Expr>)>) {
if struct_def.fields.is_empty() { if struct_def.fields.is_empty() {
return ( return (
cx.pat_ident_binding_mode( cx.pat_ident_binding_mode(
@ -1126,7 +1129,7 @@ impl<'a> TraitDef<'a> {
variant: &ast::Variant, variant: &ast::Variant,
prefix: &str, prefix: &str,
mutbl: ast::Mutability) mutbl: ast::Mutability)
-> (@ast::Pat, Vec<(Span, Option<Ident>, @Expr)> ) { -> (Gc<ast::Pat>, Vec<(Span, Option<Ident>, Gc<Expr>)> ) {
let variant_ident = variant.node.name; let variant_ident = variant.node.name;
match variant.node.kind { match variant.node.kind {
ast::TupleVariantKind(ref variant_args) => { ast::TupleVariantKind(ref variant_args) => {
@ -1159,8 +1162,8 @@ impl<'a> TraitDef<'a> {
(cx.pat_enum(variant.span, matching_path, subpats), (cx.pat_enum(variant.span, matching_path, subpats),
ident_expr) ident_expr)
} }
ast::StructVariantKind(struct_def) => { ast::StructVariantKind(ref struct_def) => {
self.create_struct_pattern(cx, variant_ident, struct_def, self.create_struct_pattern(cx, variant_ident, &**struct_def,
prefix, mutbl) prefix, mutbl)
} }
} }
@ -1174,13 +1177,13 @@ Fold the fields. `use_foldl` controls whether this is done
left-to-right (`true`) or right-to-left (`false`). left-to-right (`true`) or right-to-left (`false`).
*/ */
pub fn cs_fold(use_foldl: bool, pub fn cs_fold(use_foldl: bool,
f: |&mut ExtCtxt, Span, @Expr, @Expr, &[@Expr]| -> @Expr, f: |&mut ExtCtxt, Span, Gc<Expr>, Gc<Expr>, &[Gc<Expr>]| -> Gc<Expr>,
base: @Expr, base: Gc<Expr>,
enum_nonmatch_f: EnumNonMatchFunc, enum_nonmatch_f: EnumNonMatchFunc,
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
trait_span: Span, trait_span: Span,
substructure: &Substructure) substructure: &Substructure)
-> @Expr { -> Gc<Expr> {
match *substructure.fields { match *substructure.fields {
EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => { EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
if use_foldl { if use_foldl {
@ -1221,12 +1224,12 @@ f(cx, span, ~[self_1.method(__arg_1_1, __arg_2_1),
~~~ ~~~
*/ */
#[inline] #[inline]
pub fn cs_same_method(f: |&mut ExtCtxt, Span, Vec<@Expr> | -> @Expr, pub fn cs_same_method(f: |&mut ExtCtxt, Span, Vec<Gc<Expr>>| -> Gc<Expr>,
enum_nonmatch_f: EnumNonMatchFunc, enum_nonmatch_f: EnumNonMatchFunc,
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
trait_span: Span, trait_span: Span,
substructure: &Substructure) substructure: &Substructure)
-> @Expr { -> Gc<Expr> {
match *substructure.fields { match *substructure.fields {
EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => { EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
// call self_n.method(other_1_n, other_2_n, ...) // call self_n.method(other_1_n, other_2_n, ...)
@ -1257,13 +1260,13 @@ fields. `use_foldl` controls whether this is done left-to-right
*/ */
#[inline] #[inline]
pub fn cs_same_method_fold(use_foldl: bool, pub fn cs_same_method_fold(use_foldl: bool,
f: |&mut ExtCtxt, Span, @Expr, @Expr| -> @Expr, f: |&mut ExtCtxt, Span, Gc<Expr>, Gc<Expr>| -> Gc<Expr>,
base: @Expr, base: Gc<Expr>,
enum_nonmatch_f: EnumNonMatchFunc, enum_nonmatch_f: EnumNonMatchFunc,
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
trait_span: Span, trait_span: Span,
substructure: &Substructure) substructure: &Substructure)
-> @Expr { -> Gc<Expr> {
cs_same_method( cs_same_method(
|cx, span, vals| { |cx, span, vals| {
if use_foldl { if use_foldl {
@ -1285,10 +1288,10 @@ Use a given binop to combine the result of calling the derived method
on all the fields. on all the fields.
*/ */
#[inline] #[inline]
pub fn cs_binop(binop: ast::BinOp, base: @Expr, pub fn cs_binop(binop: ast::BinOp, base: Gc<Expr>,
enum_nonmatch_f: EnumNonMatchFunc, enum_nonmatch_f: EnumNonMatchFunc,
cx: &mut ExtCtxt, trait_span: Span, cx: &mut ExtCtxt, trait_span: Span,
substructure: &Substructure) -> @Expr { substructure: &Substructure) -> Gc<Expr> {
cs_same_method_fold( cs_same_method_fold(
true, // foldl is good enough true, // foldl is good enough
|cx, span, old, new| { |cx, span, old, new| {
@ -1306,7 +1309,7 @@ pub fn cs_binop(binop: ast::BinOp, base: @Expr,
#[inline] #[inline]
pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc, pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc,
cx: &mut ExtCtxt, span: Span, cx: &mut ExtCtxt, span: Span,
substructure: &Substructure) -> @Expr { substructure: &Substructure) -> Gc<Expr> {
cs_binop(ast::BiOr, cx.expr_bool(span, false), cs_binop(ast::BiOr, cx.expr_bool(span, false),
enum_nonmatch_f, enum_nonmatch_f,
cx, span, substructure) cx, span, substructure)
@ -1316,7 +1319,7 @@ pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc,
#[inline] #[inline]
pub fn cs_and(enum_nonmatch_f: EnumNonMatchFunc, pub fn cs_and(enum_nonmatch_f: EnumNonMatchFunc,
cx: &mut ExtCtxt, span: Span, cx: &mut ExtCtxt, span: Span,
substructure: &Substructure) -> @Expr { substructure: &Substructure) -> Gc<Expr> {
cs_binop(ast::BiAnd, cx.expr_bool(span, true), cs_binop(ast::BiAnd, cx.expr_bool(span, true),
enum_nonmatch_f, enum_nonmatch_f,
cx, span, substructure) cx, span, substructure)

View file

@ -20,6 +20,7 @@ use ext::build::AstBuilder;
use codemap::{Span,respan}; use codemap::{Span,respan};
use owned_slice::OwnedSlice; use owned_slice::OwnedSlice;
use std::gc::Gc;
/// The types of pointers /// The types of pointers
pub enum PtrTy<'a> { pub enum PtrTy<'a> {
@ -81,7 +82,7 @@ impl<'a> Path<'a> {
/// A type. Supports pointers (except for *), Self, and literals /// A type. Supports pointers (except for *), Self, and literals
pub enum Ty<'a> { pub enum Ty<'a> {
Self, Self,
// &/Box/@ Ty // &/Box/ Ty
Ptr(Box<Ty<'a>>, PtrTy<'a>), Ptr(Box<Ty<'a>>, PtrTy<'a>),
// mod::mod::Type<[lifetime], [Params...]>, including a plain type // mod::mod::Type<[lifetime], [Params...]>, including a plain type
// parameter, and things like `int` // parameter, and things like `int`
@ -244,7 +245,7 @@ impl<'a> LifetimeBounds<'a> {
pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>) pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>)
-> (@Expr, ast::ExplicitSelf) { -> (Gc<Expr>, ast::ExplicitSelf) {
let self_path = cx.expr_self(span); let self_path = cx.expr_self(span);
match *self_ptr { match *self_ptr {
None => { None => {

View file

@ -17,11 +17,13 @@ use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use std::gc::Gc;
pub fn expand_deriving_hash(cx: &mut ExtCtxt, pub fn expand_deriving_hash(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
let (path, generics, args) = if cx.ecfg.deriving_hash_type_parameter { let (path, generics, args) = if cx.ecfg.deriving_hash_type_parameter {
(Path::new_(vec!("std", "hash", "Hash"), None, (Path::new_(vec!("std", "hash", "Hash"), None,
@ -64,7 +66,8 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt,
hash_trait_def.expand(cx, mitem, item, push); hash_trait_def.expand(cx, mitem, item, push);
} }
fn hash_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { fn hash_substructure(cx: &mut ExtCtxt, trait_span: Span,
substr: &Substructure) -> Gc<Expr> {
let state_expr = match substr.nonself_args { let state_expr = match substr.nonself_args {
[state_expr] => state_expr, [state_expr] => state_expr,
_ => cx.span_bug(trait_span, "incorrect number of arguments in `deriving(Hash)`") _ => cx.span_bug(trait_span, "incorrect number of arguments in `deriving(Hash)`")

View file

@ -22,6 +22,8 @@ use ast::{Item, MetaItem, MetaList, MetaNameValue, MetaWord};
use ext::base::ExtCtxt; use ext::base::ExtCtxt;
use codemap::Span; use codemap::Span;
use std::gc::Gc;
pub mod bounds; pub mod bounds;
pub mod clone; pub mod clone;
pub mod encodable; pub mod encodable;
@ -47,9 +49,9 @@ pub mod generic;
pub fn expand_meta_deriving(cx: &mut ExtCtxt, pub fn expand_meta_deriving(cx: &mut ExtCtxt,
_span: Span, _span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
match mitem.node { match mitem.node {
MetaNameValue(_, ref l) => { MetaNameValue(_, ref l) => {
cx.span_err(l.span, "unexpected value in `deriving`"); cx.span_err(l.span, "unexpected value in `deriving`");

View file

@ -17,11 +17,13 @@ use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use std::gc::Gc;
pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt, pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
let inline = cx.meta_word(span, InternedString::new("inline")); let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline)); let attrs = vec!(cx.attribute(span, inline));
let trait_def = TraitDef { let trait_def = TraitDef {
@ -70,7 +72,8 @@ pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
trait_def.expand(cx, mitem, item, push) trait_def.expand(cx, mitem, item, push)
} }
fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span,
substr: &Substructure) -> Gc<Expr> {
let n = match substr.nonself_args { let n = match substr.nonself_args {
[n] => n, [n] => n,
_ => cx.span_bug(trait_span, "incorrect number of arguments in `deriving(FromPrimitive)`") _ => cx.span_bug(trait_span, "incorrect number of arguments in `deriving(FromPrimitive)`")

View file

@ -16,11 +16,13 @@ use ext::build::{AstBuilder};
use ext::deriving::generic::*; use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use std::gc::Gc;
pub fn expand_deriving_rand(cx: &mut ExtCtxt, pub fn expand_deriving_rand(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
let trait_def = TraitDef { let trait_def = TraitDef {
span: span, span: span,
attributes: Vec::new(), attributes: Vec::new(),
@ -53,7 +55,8 @@ pub fn expand_deriving_rand(cx: &mut ExtCtxt,
trait_def.expand(cx, mitem, item, push) trait_def.expand(cx, mitem, item, push)
} }
fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span,
substr: &Substructure) -> Gc<Expr> {
let rng = match substr.nonself_args { let rng = match substr.nonself_args {
[rng] => vec!( rng ), [rng] => vec!( rng ),
_ => cx.bug("Incorrect number of arguments to `rand` in `deriving(Rand)`") _ => cx.bug("Incorrect number of arguments to `rand` in `deriving(Rand)`")
@ -134,8 +137,8 @@ fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure)
trait_span: Span, trait_span: Span,
ctor_ident: Ident, ctor_ident: Ident,
summary: &StaticFields, summary: &StaticFields,
rand_call: |&mut ExtCtxt, Span| -> @Expr) rand_call: |&mut ExtCtxt, Span| -> Gc<Expr>)
-> @Expr { -> Gc<Expr> {
match *summary { match *summary {
Unnamed(ref fields) => { Unnamed(ref fields) => {
if fields.is_empty() { if fields.is_empty() {

View file

@ -20,12 +20,13 @@ use parse::token;
use std::collections::HashMap; use std::collections::HashMap;
use std::string::String; use std::string::String;
use std::gc::Gc;
pub fn expand_deriving_show(cx: &mut ExtCtxt, pub fn expand_deriving_show(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
// &mut ::std::fmt::Formatter // &mut ::std::fmt::Formatter
let fmtr = Ptr(box Literal(Path::new(vec!("std", "fmt", "Formatter"))), let fmtr = Ptr(box Literal(Path::new(vec!("std", "fmt", "Formatter"))),
Borrowed(None, ast::MutMutable)); Borrowed(None, ast::MutMutable));
@ -57,7 +58,7 @@ pub fn expand_deriving_show(cx: &mut ExtCtxt,
// we construct a format string and then defer to std::fmt, since that // we construct a format string and then defer to std::fmt, since that
// knows what's up with formatting at so on. // knows what's up with formatting at so on.
fn show_substructure(cx: &mut ExtCtxt, span: Span, fn show_substructure(cx: &mut ExtCtxt, span: Span,
substr: &Substructure) -> @Expr { substr: &Substructure) -> Gc<Expr> {
// build `<name>`, `<name>({}, {}, ...)` or `<name> { <field>: {}, // build `<name>`, `<name>({}, {}, ...)` or `<name> { <field>: {},
// <field>: {}, ... }` based on the "shape". // <field>: {}, ... }` based on the "shape".
// //

View file

@ -16,11 +16,13 @@ use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use std::gc::Gc;
pub fn expand_deriving_zero(cx: &mut ExtCtxt, pub fn expand_deriving_zero(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
let inline = cx.meta_word(span, InternedString::new("inline")); let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline)); let attrs = vec!(cx.attribute(span, inline));
let trait_def = TraitDef { let trait_def = TraitDef {
@ -63,7 +65,8 @@ pub fn expand_deriving_zero(cx: &mut ExtCtxt,
trait_def.expand(cx, mitem, item, push) trait_def.expand(cx, mitem, item, push)
} }
fn zero_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { fn zero_substructure(cx: &mut ExtCtxt, trait_span: Span,
substr: &Substructure) -> Gc<Expr> {
let zero_ident = vec!( let zero_ident = vec!(
cx.ident_of("std"), cx.ident_of("std"),
cx.ident_of("num"), cx.ident_of("num"),

View file

@ -29,7 +29,9 @@ use visit;
use visit::Visitor; use visit::Visitor;
use util::small_vector::SmallVector; use util::small_vector::SmallVector;
pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr { use std::gc::Gc;
pub fn expand_expr(e: Gc<ast::Expr>, fld: &mut MacroExpander) -> Gc<ast::Expr> {
match e.node { match e.node {
// expr_mac should really be expr_ext or something; it's the // expr_mac should really be expr_ext or something; it's the
// entry-point for all syntax extensions. // entry-point for all syntax extensions.
@ -115,7 +117,7 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr {
fld.fold_expr(marked_after).node.clone(); fld.fold_expr(marked_after).node.clone();
fld.cx.bt_pop(); fld.cx.bt_pop();
@ast::Expr { box(GC) ast::Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: fully_expanded, node: fully_expanded,
span: e.span, span: e.span,
@ -256,7 +258,7 @@ fn expand_loop_block(loop_block: P<Block>,
// in a block enclosed by loop head. // in a block enclosed by loop head.
fld.extsbox.push_frame(); fld.extsbox.push_frame();
fld.extsbox.info().pending_renames.push(rename); fld.extsbox.info().pending_renames.push(rename);
let expanded_block = expand_block_elts(loop_block, fld); let expanded_block = expand_block_elts(&*loop_block, fld);
fld.extsbox.pop_frame(); fld.extsbox.pop_frame();
(expanded_block, Some(renamed_ident)) (expanded_block, Some(renamed_ident))
@ -277,8 +279,8 @@ macro_rules! with_exts_frame (
) )
// When we enter a module, record it, for the sake of `module!` // When we enter a module, record it, for the sake of `module!`
pub fn expand_item(it: @ast::Item, fld: &mut MacroExpander) pub fn expand_item(it: Gc<ast::Item>, fld: &mut MacroExpander)
-> SmallVector<@ast::Item> { -> SmallVector<Gc<ast::Item>> {
let it = expand_item_modifiers(it, fld); let it = expand_item_modifiers(it, fld);
let mut decorator_items = SmallVector::zero(); let mut decorator_items = SmallVector::zero();
@ -301,7 +303,7 @@ pub fn expand_item(it: @ast::Item, fld: &mut MacroExpander)
// we'd ideally decorator_items.push_all(expand_item(item, fld)), // we'd ideally decorator_items.push_all(expand_item(item, fld)),
// but that double-mut-borrows fld // but that double-mut-borrows fld
let mut items: SmallVector<@ast::Item> = SmallVector::zero(); let mut items: SmallVector<Gc<ast::Item>> = SmallVector::zero();
dec_fn(fld.cx, attr.span, attr.node.value, it, dec_fn(fld.cx, attr.span, attr.node.value, it,
|item| items.push(item)); |item| items.push(item));
decorator_items.extend(items.move_iter() decorator_items.extend(items.move_iter()
@ -320,17 +322,17 @@ pub fn expand_item(it: @ast::Item, fld: &mut MacroExpander)
let macro_escape = contains_macro_escape(new_attrs.as_slice()); let macro_escape = contains_macro_escape(new_attrs.as_slice());
let result = with_exts_frame!(fld.extsbox, let result = with_exts_frame!(fld.extsbox,
macro_escape, macro_escape,
noop_fold_item(it, fld)); noop_fold_item(&*it, fld));
fld.cx.mod_pop(); fld.cx.mod_pop();
result result
}, },
_ => { _ => {
let it = @ast::Item { let it = box(GC) ast::Item {
attrs: new_attrs, attrs: new_attrs,
..(*it).clone() ..(*it).clone()
}; };
noop_fold_item(it, fld) noop_fold_item(&*it, fld)
} }
}; };
@ -338,8 +340,8 @@ pub fn expand_item(it: @ast::Item, fld: &mut MacroExpander)
new_items new_items
} }
fn expand_item_modifiers(mut it: @ast::Item, fld: &mut MacroExpander) fn expand_item_modifiers(mut it: Gc<ast::Item>, fld: &mut MacroExpander)
-> @ast::Item { -> Gc<ast::Item> {
let (modifiers, attrs) = it.attrs.partitioned(|attr| { let (modifiers, attrs) = it.attrs.partitioned(|attr| {
match fld.extsbox.find(&intern(attr.name().get())) { match fld.extsbox.find(&intern(attr.name().get())) {
Some(&ItemModifier(_)) => true, Some(&ItemModifier(_)) => true,
@ -347,7 +349,7 @@ fn expand_item_modifiers(mut it: @ast::Item, fld: &mut MacroExpander)
} }
}); });
it = @ast::Item { it = box(GC) ast::Item {
attrs: attrs, attrs: attrs,
..(*it).clone() ..(*it).clone()
}; };
@ -388,8 +390,8 @@ pub fn contains_macro_escape(attrs: &[ast::Attribute]) -> bool {
// Support for item-position macro invocations, exactly the same // Support for item-position macro invocations, exactly the same
// logic as for expression-position macro invocations. // logic as for expression-position macro invocations.
pub fn expand_item_mac(it: @ast::Item, fld: &mut MacroExpander) pub fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander)
-> SmallVector<@ast::Item> { -> SmallVector<Gc<ast::Item>> {
let (pth, tts) = match it.node { let (pth, tts) = match it.node {
ItemMac(codemap::Spanned { ItemMac(codemap::Spanned {
node: MacInvocTT(ref pth, ref tts, _), node: MacInvocTT(ref pth, ref tts, _),
@ -494,7 +496,7 @@ pub fn expand_item_mac(it: @ast::Item, fld: &mut MacroExpander)
} }
// expand a stmt // expand a stmt
pub fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<@Stmt> { pub fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<Gc<Stmt>> {
// why the copying here and not in expand_expr? // why the copying here and not in expand_expr?
// looks like classic changed-in-only-one-place // looks like classic changed-in-only-one-place
let (pth, tts, semi) = match s.node { let (pth, tts, semi) = match s.node {
@ -550,7 +552,7 @@ pub fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<@Stmt> {
} }
}; };
mark_stmt(expanded,fm) mark_stmt(&*expanded,fm)
} }
_ => { _ => {
@ -561,20 +563,20 @@ pub fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<@Stmt> {
}; };
// Keep going, outside-in. // Keep going, outside-in.
let fully_expanded = fld.fold_stmt(marked_after); let fully_expanded = fld.fold_stmt(&*marked_after);
if fully_expanded.is_empty() { if fully_expanded.is_empty() {
fld.cx.span_err(pth.span, "macro didn't expand to a statement"); fld.cx.span_err(pth.span, "macro didn't expand to a statement");
return SmallVector::zero(); return SmallVector::zero();
} }
fld.cx.bt_pop(); fld.cx.bt_pop();
let fully_expanded: SmallVector<@Stmt> = fully_expanded.move_iter() let fully_expanded: SmallVector<Gc<Stmt>> = fully_expanded.move_iter()
.map(|s| @Spanned { span: s.span, node: s.node.clone() }) .map(|s| box(GC) Spanned { span: s.span, node: s.node.clone() })
.collect(); .collect();
fully_expanded.move_iter().map(|s| { fully_expanded.move_iter().map(|s| {
match s.node { match s.node {
StmtExpr(e, stmt_id) if semi => { StmtExpr(e, stmt_id) if semi => {
@Spanned { box(GC) Spanned {
span: s.span, span: s.span,
node: StmtSemi(e, stmt_id) node: StmtSemi(e, stmt_id)
} }
@ -587,7 +589,7 @@ pub fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<@Stmt> {
// expand a non-macro stmt. this is essentially the fallthrough for // expand a non-macro stmt. this is essentially the fallthrough for
// expand_stmt, above. // expand_stmt, above.
fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander) fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
-> SmallVector<@Stmt> { -> SmallVector<Gc<Stmt>> {
// is it a let? // is it a let?
match s.node { match s.node {
StmtDecl(decl, node_id) => { StmtDecl(decl, node_id) => {
@ -612,7 +614,7 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
// names, as well... but that should be okay, as long as // names, as well... but that should be okay, as long as
// the new names are gensyms for the old ones. // the new names are gensyms for the old ones.
let mut name_finder = new_name_finder(Vec::new()); let mut name_finder = new_name_finder(Vec::new());
name_finder.visit_pat(expanded_pat,()); name_finder.visit_pat(&*expanded_pat,());
// generate fresh names, push them to a new pending list // generate fresh names, push them to a new pending list
let mut new_pending_renames = Vec::new(); let mut new_pending_renames = Vec::new();
for ident in name_finder.ident_accumulator.iter() { for ident in name_finder.ident_accumulator.iter() {
@ -631,7 +633,7 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
// also, don't forget to expand the init: // also, don't forget to expand the init:
let new_init_opt = init.map(|e| fld.fold_expr(e)); let new_init_opt = init.map(|e| fld.fold_expr(e));
let rewritten_local = let rewritten_local =
@Local { box(GC) Local {
ty: local.ty, ty: local.ty,
pat: rewritten_pat, pat: rewritten_pat,
init: new_init_opt, init: new_init_opt,
@ -639,8 +641,8 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
span: span, span: span,
source: source source: source
}; };
SmallVector::one(@Spanned { SmallVector::one(box(GC) Spanned {
node: StmtDecl(@Spanned { node: StmtDecl(box(GC) Spanned {
node: DeclLocal(rewritten_local), node: DeclLocal(rewritten_local),
span: stmt_span span: stmt_span
}, },
@ -687,7 +689,7 @@ impl Visitor<()> for NewNameFinderContext {
} }
// visit optional subpattern of pat_ident: // visit optional subpattern of pat_ident:
for subpat in inner.iter() { for subpat in inner.iter() {
self.visit_pat(*subpat, ()) self.visit_pat(&**subpat, ())
} }
} }
// use the default traversal for non-pat_idents // use the default traversal for non-pat_idents
@ -725,9 +727,9 @@ pub fn expand_block_elts(b: &Block, fld: &mut MacroExpander) -> P<Block> {
let renamed_stmt = { let renamed_stmt = {
let pending_renames = &mut fld.extsbox.info().pending_renames; let pending_renames = &mut fld.extsbox.info().pending_renames;
let mut rename_fld = renames_to_fold(pending_renames); let mut rename_fld = renames_to_fold(pending_renames);
rename_fld.fold_stmt(*x).expect_one("rename_fold didn't return one value") rename_fld.fold_stmt(&**x).expect_one("rename_fold didn't return one value")
}; };
fld.fold_stmt(renamed_stmt).move_iter() fld.fold_stmt(&*renamed_stmt).move_iter()
}).collect(); }).collect();
let new_expr = b.expr.map(|x| { let new_expr = b.expr.map(|x| {
let expr = { let expr = {
@ -863,24 +865,24 @@ pub struct MacroExpander<'a, 'b> {
} }
impl<'a, 'b> Folder for MacroExpander<'a, 'b> { impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
fn fold_expr(&mut self, expr: @ast::Expr) -> @ast::Expr { fn fold_expr(&mut self, expr: Gc<ast::Expr>) -> Gc<ast::Expr> {
expand_expr(expr, self) expand_expr(expr, self)
} }
fn fold_pat(&mut self, pat: @ast::Pat) -> @ast::Pat { fn fold_pat(&mut self, pat: Gc<ast::Pat>) -> Gc<ast::Pat> {
expand_pat(pat, self) expand_pat(pat, self)
} }
fn fold_item(&mut self, item: @ast::Item) -> SmallVector<@ast::Item> { fn fold_item(&mut self, item: Gc<ast::Item>) -> SmallVector<Gc<ast::Item>> {
expand_item(item, self) expand_item(item, self)
} }
fn fold_stmt(&mut self, stmt: &ast::Stmt) -> SmallVector<@ast::Stmt> { fn fold_stmt(&mut self, stmt: &ast::Stmt) -> SmallVector<Gc<ast::Stmt>> {
expand_stmt(stmt, self) expand_stmt(stmt, self)
} }
fn fold_block(&mut self, block: P<Block>) -> P<Block> { fn fold_block(&mut self, block: P<Block>) -> P<Block> {
expand_block(block, self) expand_block(&*block, self)
} }
fn new_span(&mut self, span: Span) -> Span { fn new_span(&mut self, span: Span) -> Span {
@ -976,7 +978,7 @@ fn mark_tts(tts: &[TokenTree], m: Mrk) -> Vec<TokenTree> {
} }
// apply a given mark to the given expr. Used following the expansion of a macro. // apply a given mark to the given expr. Used following the expansion of a macro.
fn mark_expr(expr: @ast::Expr, m: Mrk) -> @ast::Expr { fn mark_expr(expr: Gc<ast::Expr>, m: Mrk) -> Gc<ast::Expr> {
new_mark_folder(m).fold_expr(expr) new_mark_folder(m).fold_expr(expr)
} }
@ -986,17 +988,17 @@ fn mark_pat(pat: @ast::Pat, m: Mrk) -> @ast::Pat {
} }
// apply a given mark to the given stmt. Used following the expansion of a macro. // apply a given mark to the given stmt. Used following the expansion of a macro.
fn mark_stmt(expr: &ast::Stmt, m: Mrk) -> @ast::Stmt { fn mark_stmt(expr: &ast::Stmt, m: Mrk) -> Gc<ast::Stmt> {
new_mark_folder(m).fold_stmt(expr) new_mark_folder(m).fold_stmt(expr)
.expect_one("marking a stmt didn't return a stmt") .expect_one("marking a stmt didn't return a stmt")
} }
// apply a given mark to the given item. Used following the expansion of a macro. // apply a given mark to the given item. Used following the expansion of a macro.
fn mark_item(expr: @ast::Item, m: Mrk) -> SmallVector<@ast::Item> { fn mark_item(expr: Gc<ast::Item>, m: Mrk) -> SmallVector<Gc<ast::Item>> {
new_mark_folder(m).fold_item(expr) new_mark_folder(m).fold_item(expr)
} }
fn original_span(cx: &ExtCtxt) -> @codemap::ExpnInfo { fn original_span(cx: &ExtCtxt) -> Gc<codemap::ExpnInfo> {
let mut relevant_info = cx.backtrace(); let mut relevant_info = cx.backtrace();
let mut einfo = relevant_info.unwrap(); let mut einfo = relevant_info.unwrap();
loop { loop {
@ -1134,7 +1136,7 @@ mod test {
node: Attribute_ { node: Attribute_ {
id: attr::mk_attr_id(), id: attr::mk_attr_id(),
style: AttrOuter, style: AttrOuter,
value: @Spanned { value: box(GC) Spanned {
node: MetaWord(token::intern_and_get_ident(s)), node: MetaWord(token::intern_and_get_ident(s)),
span: codemap::DUMMY_SP, span: codemap::DUMMY_SP,
}, },

View file

@ -20,6 +20,7 @@ use rsparse = parse;
use parse = fmt_macros; use parse = fmt_macros;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::gc::Gc;
#[deriving(PartialEq)] #[deriving(PartialEq)]
enum ArgumentType { enum ArgumentType {
@ -39,20 +40,20 @@ struct Context<'a, 'b> {
// Parsed argument expressions and the types that we've found so far for // Parsed argument expressions and the types that we've found so far for
// them. // them.
args: Vec<@ast::Expr>, args: Vec<Gc<ast::Expr>>,
arg_types: Vec<Option<ArgumentType>>, arg_types: Vec<Option<ArgumentType>>,
// Parsed named expressions and the types that we've found for them so far. // Parsed named expressions and the types that we've found for them so far.
// Note that we keep a side-array of the ordering of the named arguments // Note that we keep a side-array of the ordering of the named arguments
// found to be sure that we can translate them in the same order that they // found to be sure that we can translate them in the same order that they
// were declared in. // were declared in.
names: HashMap<String, @ast::Expr>, names: HashMap<String, Gc<ast::Expr>>,
name_types: HashMap<String, ArgumentType>, name_types: HashMap<String, ArgumentType>,
name_ordering: Vec<String>, name_ordering: Vec<String>,
// Collection of the compiled `rt::Piece` structures // Collection of the compiled `rt::Piece` structures
pieces: Vec<@ast::Expr> , pieces: Vec<Gc<ast::Expr>>,
name_positions: HashMap<String, uint>, name_positions: HashMap<String, uint>,
method_statics: Vec<@ast::Item> , method_statics: Vec<Gc<ast::Item>>,
// Updated as arguments are consumed or methods are entered // Updated as arguments are consumed or methods are entered
nest_level: uint, nest_level: uint,
@ -60,8 +61,8 @@ struct Context<'a, 'b> {
} }
pub enum Invocation { pub enum Invocation {
Call(@ast::Expr), Call(Gc<ast::Expr>),
MethodCall(@ast::Expr, ast::Ident), MethodCall(Gc<ast::Expr>, ast::Ident),
} }
/// Parses the arguments from the given list of tokens, returning None /// Parses the arguments from the given list of tokens, returning None
@ -74,10 +75,10 @@ pub enum Invocation {
/// named arguments)) /// named arguments))
fn parse_args(ecx: &mut ExtCtxt, sp: Span, allow_method: bool, fn parse_args(ecx: &mut ExtCtxt, sp: Span, allow_method: bool,
tts: &[ast::TokenTree]) tts: &[ast::TokenTree])
-> (Invocation, Option<(@ast::Expr, Vec<@ast::Expr>, Vec<String>, -> (Invocation, Option<(Gc<ast::Expr>, Vec<Gc<ast::Expr>>, Vec<String>,
HashMap<String, @ast::Expr>)>) { HashMap<String, Gc<ast::Expr>>)>) {
let mut args = Vec::new(); let mut args = Vec::new();
let mut names = HashMap::<String, @ast::Expr>::new(); let mut names = HashMap::<String, Gc<ast::Expr>>::new();
let mut order = Vec::new(); let mut order = Vec::new();
let mut p = rsparse::new_parser_from_tts(ecx.parse_sess(), let mut p = rsparse::new_parser_from_tts(ecx.parse_sess(),
@ -399,7 +400,7 @@ impl<'a, 'b> Context<'a, 'b> {
self.ecx.ident_of("rt"), self.ecx.ident_of(s)) self.ecx.ident_of("rt"), self.ecx.ident_of(s))
} }
fn none(&self) -> @ast::Expr { fn none(&self) -> Gc<ast::Expr> {
let none = self.ecx.path_global(self.fmtsp, vec!( let none = self.ecx.path_global(self.fmtsp, vec!(
self.ecx.ident_of("std"), self.ecx.ident_of("std"),
self.ecx.ident_of("option"), self.ecx.ident_of("option"),
@ -407,7 +408,7 @@ impl<'a, 'b> Context<'a, 'b> {
self.ecx.expr_path(none) self.ecx.expr_path(none)
} }
fn some(&self, e: @ast::Expr) -> @ast::Expr { fn some(&self, e: Gc<ast::Expr>) -> Gc<ast::Expr> {
let p = self.ecx.path_global(self.fmtsp, vec!( let p = self.ecx.path_global(self.fmtsp, vec!(
self.ecx.ident_of("std"), self.ecx.ident_of("std"),
self.ecx.ident_of("option"), self.ecx.ident_of("option"),
@ -416,7 +417,7 @@ impl<'a, 'b> Context<'a, 'b> {
self.ecx.expr_call(self.fmtsp, p, vec!(e)) self.ecx.expr_call(self.fmtsp, p, vec!(e))
} }
fn trans_count(&self, c: parse::Count) -> @ast::Expr { fn trans_count(&self, c: parse::Count) -> Gc<ast::Expr> {
let sp = self.fmtsp; let sp = self.fmtsp;
match c { match c {
parse::CountIs(i) => { parse::CountIs(i) => {
@ -447,7 +448,7 @@ impl<'a, 'b> Context<'a, 'b> {
} }
} }
fn trans_method(&mut self, method: &parse::Method) -> @ast::Expr { fn trans_method(&mut self, method: &parse::Method) -> Gc<ast::Expr> {
let sp = self.fmtsp; let sp = self.fmtsp;
let method = match *method { let method = match *method {
parse::Select(ref arms, ref default) => { parse::Select(ref arms, ref default) => {
@ -528,7 +529,7 @@ impl<'a, 'b> Context<'a, 'b> {
} }
/// Translate a `parse::Piece` to a static `rt::Piece` /// Translate a `parse::Piece` to a static `rt::Piece`
fn trans_piece(&mut self, piece: &parse::Piece) -> @ast::Expr { fn trans_piece(&mut self, piece: &parse::Piece) -> Gc<ast::Expr> {
let sp = self.fmtsp; let sp = self.fmtsp;
match *piece { match *piece {
parse::String(s) => { parse::String(s) => {
@ -615,7 +616,7 @@ impl<'a, 'b> Context<'a, 'b> {
/// Actually builds the expression which the iformat! block will be expanded /// Actually builds the expression which the iformat! block will be expanded
/// to /// to
fn to_expr(&self, invocation: Invocation) -> @ast::Expr { fn to_expr(&self, invocation: Invocation) -> Gc<ast::Expr> {
let mut lets = Vec::new(); let mut lets = Vec::new();
let mut locals = Vec::new(); let mut locals = Vec::new();
let mut names = Vec::from_fn(self.name_positions.len(), |_| None); let mut names = Vec::from_fn(self.name_positions.len(), |_| None);
@ -625,8 +626,8 @@ impl<'a, 'b> Context<'a, 'b> {
// First, declare all of our methods that are statics // First, declare all of our methods that are statics
for &method in self.method_statics.iter() { for &method in self.method_statics.iter() {
let decl = respan(self.fmtsp, ast::DeclItem(method)); let decl = respan(self.fmtsp, ast::DeclItem(method));
lets.push(@respan(self.fmtsp, lets.push(box(GC) respan(self.fmtsp,
ast::StmtDecl(@decl, ast::DUMMY_NODE_ID))); ast::StmtDecl(box(GC) decl, ast::DUMMY_NODE_ID)));
} }
// Next, build up the static array which will become our precompiled // Next, build up the static array which will become our precompiled
@ -653,7 +654,8 @@ impl<'a, 'b> Context<'a, 'b> {
let item = self.ecx.item(self.fmtsp, static_name, let item = self.ecx.item(self.fmtsp, static_name,
self.static_attrs(), st); self.static_attrs(), st);
let decl = respan(self.fmtsp, ast::DeclItem(item)); let decl = respan(self.fmtsp, ast::DeclItem(item));
lets.push(@respan(self.fmtsp, ast::StmtDecl(@decl, ast::DUMMY_NODE_ID))); lets.push(box(GC) respan(self.fmtsp,
ast::StmtDecl(box(GC) decl, ast::DUMMY_NODE_ID)));
// Right now there is a bug such that for the expression: // Right now there is a bug such that for the expression:
// foo(bar(&1)) // foo(bar(&1))
@ -766,8 +768,8 @@ impl<'a, 'b> Context<'a, 'b> {
self.ecx.expr_match(self.fmtsp, head, vec!(arm)) self.ecx.expr_match(self.fmtsp, head, vec!(arm))
} }
fn format_arg(&self, sp: Span, argno: Position, arg: @ast::Expr) fn format_arg(&self, sp: Span, argno: Position, arg: Gc<ast::Expr>)
-> @ast::Expr { -> Gc<ast::Expr> {
let ty = match argno { let ty = match argno {
Exact(ref i) => self.arg_types.get(*i).get_ref(), Exact(ref i) => self.arg_types.get(*i).get_ref(),
Named(ref s) => self.name_types.get(s) Named(ref s) => self.name_types.get(s)
@ -854,9 +856,12 @@ pub fn expand_format_args_method(ecx: &mut ExtCtxt, sp: Span,
/// expression. /// expression.
pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span, pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
invocation: Invocation, invocation: Invocation,
efmt: @ast::Expr, args: Vec<@ast::Expr>, efmt: Gc<ast::Expr>,
args: Vec<Gc<ast::Expr>>,
name_ordering: Vec<String>, name_ordering: Vec<String>,
names: HashMap<String, @ast::Expr>) -> @ast::Expr { names: HashMap<String, Gc<ast::Expr>>)
-> Gc<ast::Expr>
{
let arg_types = Vec::from_fn(args.len(), |_| None); let arg_types = Vec::from_fn(args.len(), |_| None);
let mut cx = Context { let mut cx = Context {
ecx: ecx, ecx: ecx,

View file

@ -17,6 +17,7 @@ use parse::token::*;
use parse::token; use parse::token;
use parse; use parse;
use std::gc::Gc;
/** /**
* *
@ -50,6 +51,8 @@ pub mod rt {
pub use parse::new_parser_from_tts; pub use parse::new_parser_from_tts;
pub use codemap::{BytePos, Span, dummy_spanned}; pub use codemap::{BytePos, Span, dummy_spanned};
use std::gc::Gc;
pub trait ToTokens { pub trait ToTokens {
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> ; fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> ;
} }
@ -85,13 +88,13 @@ pub mod rt {
} }
} }
impl ToSource for @ast::Item { impl ToSource for Gc<ast::Item> {
fn to_source(&self) -> String { fn to_source(&self) -> String {
pprust::item_to_str(*self) pprust::item_to_str(*self)
} }
} }
impl<'a> ToSource for &'a [@ast::Item] { impl<'a> ToSource for &'a [Gc<ast::Item>] {
fn to_source(&self) -> String { fn to_source(&self) -> String {
self.iter() self.iter()
.map(|i| i.to_source()) .map(|i| i.to_source())
@ -123,7 +126,7 @@ pub mod rt {
} }
} }
impl ToSource for @ast::Expr { impl ToSource for Gc<ast::Expr> {
fn to_source(&self) -> String { fn to_source(&self) -> String {
pprust::expr_to_str(*self) pprust::expr_to_str(*self)
} }
@ -263,12 +266,12 @@ pub mod rt {
) )
impl_to_tokens!(ast::Ident) impl_to_tokens!(ast::Ident)
impl_to_tokens!(@ast::Item) impl_to_tokens!(Gc<ast::Item>)
impl_to_tokens_self!(&'a [@ast::Item]) impl_to_tokens_self!(&'a [Gc<ast::Item>])
impl_to_tokens!(ast::Ty) impl_to_tokens!(ast::Ty)
impl_to_tokens_self!(&'a [ast::Ty]) impl_to_tokens_self!(&'a [ast::Ty])
impl_to_tokens!(Generics) impl_to_tokens!(Generics)
impl_to_tokens!(@ast::Expr) impl_to_tokens!(Gc<ast::Expr>)
impl_to_tokens!(ast::Block) impl_to_tokens!(ast::Block)
impl_to_tokens!(ast::Arg) impl_to_tokens!(ast::Arg)
impl_to_tokens_self!(&'a str) impl_to_tokens_self!(&'a str)
@ -287,15 +290,15 @@ pub mod rt {
impl_to_tokens!(u64) impl_to_tokens!(u64)
pub trait ExtParseUtils { pub trait ExtParseUtils {
fn parse_item(&self, s: String) -> @ast::Item; fn parse_item(&self, s: String) -> Gc<ast::Item>;
fn parse_expr(&self, s: String) -> @ast::Expr; fn parse_expr(&self, s: String) -> Gc<ast::Expr>;
fn parse_stmt(&self, s: String) -> @ast::Stmt; fn parse_stmt(&self, s: String) -> Gc<ast::Stmt>;
fn parse_tts(&self, s: String) -> Vec<ast::TokenTree> ; fn parse_tts(&self, s: String) -> Vec<ast::TokenTree> ;
} }
impl<'a> ExtParseUtils for ExtCtxt<'a> { impl<'a> ExtParseUtils for ExtCtxt<'a> {
fn parse_item(&self, s: String) -> @ast::Item { fn parse_item(&self, s: String) -> Gc<ast::Item> {
let res = parse::parse_item_from_source_str( let res = parse::parse_item_from_source_str(
"<quote expansion>".to_string(), "<quote expansion>".to_string(),
s, s,
@ -310,7 +313,7 @@ pub mod rt {
} }
} }
fn parse_stmt(&self, s: String) -> @ast::Stmt { fn parse_stmt(&self, s: String) -> Gc<ast::Stmt> {
parse::parse_stmt_from_source_str("<quote expansion>".to_string(), parse::parse_stmt_from_source_str("<quote expansion>".to_string(),
s, s,
self.cfg(), self.cfg(),
@ -318,7 +321,7 @@ pub mod rt {
self.parse_sess()) self.parse_sess())
} }
fn parse_expr(&self, s: String) -> @ast::Expr { fn parse_expr(&self, s: String) -> Gc<ast::Expr> {
parse::parse_expr_from_source_str("<quote expansion>".to_string(), parse::parse_expr_from_source_str("<quote expansion>".to_string(),
s, s,
self.cfg(), self.cfg(),
@ -400,7 +403,7 @@ fn id_ext(str: &str) -> ast::Ident {
} }
// Lift an ident to the expr that evaluates to that ident. // Lift an ident to the expr that evaluates to that ident.
fn mk_ident(cx: &ExtCtxt, sp: Span, ident: ast::Ident) -> @ast::Expr { fn mk_ident(cx: &ExtCtxt, sp: Span, ident: ast::Ident) -> Gc<ast::Expr> {
let e_str = cx.expr_str(sp, token::get_ident(ident)); let e_str = cx.expr_str(sp, token::get_ident(ident));
cx.expr_method_call(sp, cx.expr_method_call(sp,
cx.expr_ident(sp, id_ext("ext_cx")), cx.expr_ident(sp, id_ext("ext_cx")),
@ -408,17 +411,17 @@ fn mk_ident(cx: &ExtCtxt, sp: Span, ident: ast::Ident) -> @ast::Expr {
vec!(e_str)) vec!(e_str))
} }
fn mk_ast_path(cx: &ExtCtxt, sp: Span, name: &str) -> @ast::Expr { fn mk_ast_path(cx: &ExtCtxt, sp: Span, name: &str) -> Gc<ast::Expr> {
let idents = vec!(id_ext("syntax"), id_ext("ast"), id_ext(name)); let idents = vec!(id_ext("syntax"), id_ext("ast"), id_ext(name));
cx.expr_path(cx.path_global(sp, idents)) cx.expr_path(cx.path_global(sp, idents))
} }
fn mk_token_path(cx: &ExtCtxt, sp: Span, name: &str) -> @ast::Expr { fn mk_token_path(cx: &ExtCtxt, sp: Span, name: &str) -> Gc<ast::Expr> {
let idents = vec!(id_ext("syntax"), id_ext("parse"), id_ext("token"), id_ext(name)); let idents = vec!(id_ext("syntax"), id_ext("parse"), id_ext("token"), id_ext(name));
cx.expr_path(cx.path_global(sp, idents)) cx.expr_path(cx.path_global(sp, idents))
} }
fn mk_binop(cx: &ExtCtxt, sp: Span, bop: token::BinOp) -> @ast::Expr { fn mk_binop(cx: &ExtCtxt, sp: Span, bop: token::BinOp) -> Gc<ast::Expr> {
let name = match bop { let name = match bop {
PLUS => "PLUS", PLUS => "PLUS",
MINUS => "MINUS", MINUS => "MINUS",
@ -434,7 +437,7 @@ fn mk_binop(cx: &ExtCtxt, sp: Span, bop: token::BinOp) -> @ast::Expr {
mk_token_path(cx, sp, name) mk_token_path(cx, sp, name)
} }
fn mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> @ast::Expr { fn mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> Gc<ast::Expr> {
match *tok { match *tok {
BINOP(binop) => { BINOP(binop) => {
@ -565,7 +568,8 @@ fn mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> @ast::Expr {
mk_token_path(cx, sp, name) mk_token_path(cx, sp, name)
} }
fn mk_tt(cx: &ExtCtxt, sp: Span, tt: &ast::TokenTree) -> Vec<@ast::Stmt> {
fn mk_tt(cx: &ExtCtxt, sp: Span, tt: &ast::TokenTree) -> Vec<Gc<ast::Stmt>> {
match *tt { match *tt {
ast::TTTok(sp, ref tok) => { ast::TTTok(sp, ref tok) => {
let e_sp = cx.expr_ident(sp, id_ext("_sp")); let e_sp = cx.expr_ident(sp, id_ext("_sp"));
@ -605,7 +609,7 @@ fn mk_tt(cx: &ExtCtxt, sp: Span, tt: &ast::TokenTree) -> Vec<@ast::Stmt> {
} }
fn mk_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree]) fn mk_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-> Vec<@ast::Stmt> { -> Vec<Gc<ast::Stmt>> {
let mut ss = Vec::new(); let mut ss = Vec::new();
for tt in tts.iter() { for tt in tts.iter() {
ss.push_all_move(mk_tt(cx, sp, tt)); ss.push_all_move(mk_tt(cx, sp, tt));
@ -614,7 +618,7 @@ fn mk_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
} }
fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree]) fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-> (@ast::Expr, @ast::Expr) { -> (Gc<ast::Expr>, Gc<ast::Expr>) {
// NB: It appears that the main parser loses its mind if we consider // NB: It appears that the main parser loses its mind if we consider
// $foo as a TTNonterminal during the main parse, so we have to re-parse // $foo as a TTNonterminal during the main parse, so we have to re-parse
// under quote_depth > 0. This is silly and should go away; the _guess_ is // under quote_depth > 0. This is silly and should go away; the _guess_ is
@ -686,8 +690,8 @@ fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
fn expand_wrapper(cx: &ExtCtxt, fn expand_wrapper(cx: &ExtCtxt,
sp: Span, sp: Span,
cx_expr: @ast::Expr, cx_expr: Gc<ast::Expr>,
expr: @ast::Expr) -> @ast::Expr { expr: Gc<ast::Expr>) -> Gc<ast::Expr> {
let uses = [ let uses = [
&["syntax", "ext", "quote", "rt"], &["syntax", "ext", "quote", "rt"],
].iter().map(|path| { ].iter().map(|path| {
@ -703,8 +707,8 @@ fn expand_wrapper(cx: &ExtCtxt,
fn expand_parse_call(cx: &ExtCtxt, fn expand_parse_call(cx: &ExtCtxt,
sp: Span, sp: Span,
parse_method: &str, parse_method: &str,
arg_exprs: Vec<@ast::Expr> , arg_exprs: Vec<Gc<ast::Expr>>,
tts: &[ast::TokenTree]) -> @ast::Expr { tts: &[ast::TokenTree]) -> Gc<ast::Expr> {
let (cx_expr, tts_expr) = expand_tts(cx, sp, tts); let (cx_expr, tts_expr) = expand_tts(cx, sp, tts);
let cfg_call = || cx.expr_method_call( let cfg_call = || cx.expr_method_call(

View file

@ -19,6 +19,7 @@ use parse;
use parse::token; use parse::token;
use print::pprust; use print::pprust;
use std::gc::Gc;
use std::io::File; use std::io::File;
use std::rc::Rc; use std::rc::Rc;
use std::str; use std::str;
@ -163,7 +164,7 @@ pub fn expand_include_bin(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
} }
// recur along an ExpnInfo chain to find the original expression // recur along an ExpnInfo chain to find the original expression
fn topmost_expn_info(expn_info: @codemap::ExpnInfo) -> @codemap::ExpnInfo { fn topmost_expn_info(expn_info: Gc<codemap::ExpnInfo>) -> Gc<codemap::ExpnInfo> {
match *expn_info { match *expn_info {
ExpnInfo { call_site: ref call_site, .. } => { ExpnInfo { call_site: ref call_site, .. } => {
match call_site.expn_info { match call_site.expn_info {

View file

@ -452,7 +452,7 @@ pub fn parse_nt(p: &mut Parser, name: &str) -> Nonterminal {
"meta" => token::NtMeta(p.parse_meta_item()), "meta" => token::NtMeta(p.parse_meta_item()),
"tt" => { "tt" => {
p.quote_depth += 1u; //but in theory, non-quoted tts might be useful p.quote_depth += 1u; //but in theory, non-quoted tts might be useful
let res = token::NtTT(@p.parse_token_tree()); let res = token::NtTT(box(GC) p.parse_token_tree());
p.quote_depth -= 1u; p.quote_depth -= 1u;
res res
} }

View file

@ -29,6 +29,7 @@ use util::small_vector::SmallVector;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use std::gc::Gc;
struct ParserAnyMacro<'a> { struct ParserAnyMacro<'a> {
parser: RefCell<Parser<'a>>, parser: RefCell<Parser<'a>>,
@ -58,17 +59,17 @@ impl<'a> ParserAnyMacro<'a> {
} }
impl<'a> MacResult for ParserAnyMacro<'a> { impl<'a> MacResult for ParserAnyMacro<'a> {
fn make_expr(&self) -> Option<@ast::Expr> { fn make_expr(&self) -> Option<Gc<ast::Expr>> {
let ret = self.parser.borrow_mut().parse_expr(); let ret = self.parser.borrow_mut().parse_expr();
self.ensure_complete_parse(true); self.ensure_complete_parse(true);
Some(ret) Some(ret)
} }
fn make_pat(&self) -> Option<@ast::Pat> { fn make_pat(&self) -> Option<Gc<ast::Pat>> {
let ret = self.parser.borrow_mut().parse_pat(); let ret = self.parser.borrow_mut().parse_pat();
self.ensure_complete_parse(false); self.ensure_complete_parse(false);
Some(ret) Some(ret)
} }
fn make_items(&self) -> Option<SmallVector<@ast::Item>> { fn make_items(&self) -> Option<SmallVector<Gc<ast::Item>>> {
let mut ret = SmallVector::zero(); let mut ret = SmallVector::zero();
loop { loop {
let mut parser = self.parser.borrow_mut(); let mut parser = self.parser.borrow_mut();
@ -81,7 +82,7 @@ impl<'a> MacResult for ParserAnyMacro<'a> {
self.ensure_complete_parse(false); self.ensure_complete_parse(false);
Some(ret) Some(ret)
} }
fn make_stmt(&self) -> Option<@ast::Stmt> { fn make_stmt(&self) -> Option<Gc<ast::Stmt>> {
let attrs = self.parser.borrow_mut().parse_outer_attributes(); let attrs = self.parser.borrow_mut().parse_outer_attributes();
let ret = self.parser.borrow_mut().parse_stmt(attrs); let ret = self.parser.borrow_mut().parse_stmt(attrs);
self.ensure_complete_parse(true); self.ensure_complete_parse(true);

View file

@ -17,6 +17,7 @@ use owned_slice::OwnedSlice;
use util::small_vector::SmallVector; use util::small_vector::SmallVector;
use std::rc::Rc; use std::rc::Rc;
use std::gc::Gc;
// We may eventually want to be able to fold over type parameters, too. // We may eventually want to be able to fold over type parameters, too.
pub trait Folder { pub trait Folder {
@ -24,11 +25,11 @@ pub trait Folder {
noop_fold_crate(c, self) noop_fold_crate(c, self)
} }
fn fold_meta_items(&mut self, meta_items: &[@MetaItem]) -> Vec<@MetaItem> { fn fold_meta_items(&mut self, meta_items: &[Gc<MetaItem>]) -> Vec<Gc<MetaItem>> {
meta_items.iter().map(|x| fold_meta_item_(*x, self)).collect() meta_items.iter().map(|x| fold_meta_item_(*x, self)).collect()
} }
fn fold_view_path(&mut self, view_path: @ViewPath) -> @ViewPath { fn fold_view_path(&mut self, view_path: Gc<ViewPath>) -> Gc<ViewPath> {
let inner_view_path = match view_path.node { let inner_view_path = match view_path.node {
ViewPathSimple(ref ident, ref path, node_id) => { ViewPathSimple(ref ident, ref path, node_id) => {
let id = self.new_id(node_id); let id = self.new_id(node_id);
@ -60,7 +61,7 @@ pub trait Folder {
id) id)
} }
}; };
@Spanned { box(GC) Spanned {
node: inner_view_path, node: inner_view_path,
span: self.new_span(view_path.span), span: self.new_span(view_path.span),
} }
@ -70,12 +71,12 @@ pub trait Folder {
noop_fold_view_item(vi, self) noop_fold_view_item(vi, self)
} }
fn fold_foreign_item(&mut self, ni: @ForeignItem) -> @ForeignItem { fn fold_foreign_item(&mut self, ni: Gc<ForeignItem>) -> Gc<ForeignItem> {
noop_fold_foreign_item(ni, self) noop_fold_foreign_item(&*ni, self)
} }
fn fold_item(&mut self, i: @Item) -> SmallVector<@Item> { fn fold_item(&mut self, i: Gc<Item>) -> SmallVector<Gc<Item>> {
noop_fold_item(i, self) noop_fold_item(&*i, self)
} }
fn fold_struct_field(&mut self, sf: &StructField) -> StructField { fn fold_struct_field(&mut self, sf: &StructField) -> StructField {
@ -103,15 +104,15 @@ pub trait Folder {
noop_fold_type_method(m, self) noop_fold_type_method(m, self)
} }
fn fold_method(&mut self, m: @Method) -> @Method { fn fold_method(&mut self, m: Gc<Method>) -> Gc<Method> {
noop_fold_method(m, self) noop_fold_method(&*m, self)
} }
fn fold_block(&mut self, b: P<Block>) -> P<Block> { fn fold_block(&mut self, b: P<Block>) -> P<Block> {
noop_fold_block(b, self) noop_fold_block(b, self)
} }
fn fold_stmt(&mut self, s: &Stmt) -> SmallVector<@Stmt> { fn fold_stmt(&mut self, s: &Stmt) -> SmallVector<Gc<Stmt>> {
noop_fold_stmt(s, self) noop_fold_stmt(s, self)
} }
@ -124,11 +125,11 @@ pub trait Folder {
} }
} }
fn fold_pat(&mut self, p: @Pat) -> @Pat { fn fold_pat(&mut self, p: Gc<Pat>) -> Gc<Pat> {
noop_fold_pat(p, self) noop_fold_pat(p, self)
} }
fn fold_decl(&mut self, d: @Decl) -> SmallVector<@Decl> { fn fold_decl(&mut self, d: Gc<Decl>) -> SmallVector<Gc<Decl>> {
let node = match d.node { let node = match d.node {
DeclLocal(ref l) => SmallVector::one(DeclLocal(self.fold_local(*l))), DeclLocal(ref l) => SmallVector::one(DeclLocal(self.fold_local(*l))),
DeclItem(it) => { DeclItem(it) => {
@ -137,14 +138,14 @@ pub trait Folder {
}; };
node.move_iter().map(|node| { node.move_iter().map(|node| {
@Spanned { box(GC) Spanned {
node: node, node: node,
span: self.new_span(d.span), span: self.new_span(d.span),
} }
}).collect() }).collect()
} }
fn fold_expr(&mut self, e: @Expr) -> @Expr { fn fold_expr(&mut self, e: Gc<Expr>) -> Gc<Expr> {
noop_fold_expr(e, self) noop_fold_expr(e, self)
} }
@ -160,29 +161,29 @@ pub trait Folder {
TyRptr(fold_opt_lifetime(region, self), fold_mt(mt, self)) TyRptr(fold_opt_lifetime(region, self), fold_mt(mt, self))
} }
TyClosure(ref f, ref region) => { TyClosure(ref f, ref region) => {
TyClosure(@ClosureTy { TyClosure(box(GC) ClosureTy {
fn_style: f.fn_style, fn_style: f.fn_style,
onceness: f.onceness, onceness: f.onceness,
bounds: fold_opt_bounds(&f.bounds, self), bounds: fold_opt_bounds(&f.bounds, self),
decl: self.fold_fn_decl(f.decl), decl: self.fold_fn_decl(&*f.decl),
lifetimes: f.lifetimes.iter().map(|l| self.fold_lifetime(l)).collect(), lifetimes: f.lifetimes.iter().map(|l| self.fold_lifetime(l)).collect(),
}, fold_opt_lifetime(region, self)) }, fold_opt_lifetime(region, self))
} }
TyProc(ref f) => { TyProc(ref f) => {
TyProc(@ClosureTy { TyProc(box(GC) ClosureTy {
fn_style: f.fn_style, fn_style: f.fn_style,
onceness: f.onceness, onceness: f.onceness,
bounds: fold_opt_bounds(&f.bounds, self), bounds: fold_opt_bounds(&f.bounds, self),
decl: self.fold_fn_decl(f.decl), decl: self.fold_fn_decl(&*f.decl),
lifetimes: f.lifetimes.iter().map(|l| self.fold_lifetime(l)).collect(), lifetimes: f.lifetimes.iter().map(|l| self.fold_lifetime(l)).collect(),
}) })
} }
TyBareFn(ref f) => { TyBareFn(ref f) => {
TyBareFn(@BareFnTy { TyBareFn(box(GC) BareFnTy {
lifetimes: f.lifetimes.iter().map(|l| self.fold_lifetime(l)).collect(), lifetimes: f.lifetimes.iter().map(|l| self.fold_lifetime(l)).collect(),
fn_style: f.fn_style, fn_style: f.fn_style,
abi: f.abi, abi: f.abi,
decl: self.fold_fn_decl(f.decl) decl: self.fold_fn_decl(&*f.decl)
}) })
} }
TyUnboxedFn(ref f) => { TyUnboxedFn(ref f) => {
@ -236,7 +237,7 @@ pub trait Folder {
fold_variant_arg_(x, self)).collect()) fold_variant_arg_(x, self)).collect())
} }
StructVariantKind(ref struct_def) => { StructVariantKind(ref struct_def) => {
kind = StructVariantKind(@ast::StructDef { kind = StructVariantKind(box(GC) ast::StructDef {
fields: struct_def.fields.iter() fields: struct_def.fields.iter()
.map(|f| self.fold_struct_field(f)).collect(), .map(|f| self.fold_struct_field(f)).collect(),
ctor_id: struct_def.ctor_id.map(|c| self.new_id(c)), ctor_id: struct_def.ctor_id.map(|c| self.new_id(c)),
@ -285,9 +286,9 @@ pub trait Folder {
} }
} }
fn fold_local(&mut self, l: @Local) -> @Local { fn fold_local(&mut self, l: Gc<Local>) -> Gc<Local> {
let id = self.new_id(l.id); // Needs to be first, for ast_map. let id = self.new_id(l.id); // Needs to be first, for ast_map.
@Local { box(GC) Local {
id: id, id: id,
ty: self.fold_ty(l.ty), ty: self.fold_ty(l.ty),
pat: self.fold_pat(l.pat), pat: self.fold_pat(l.pat),
@ -310,7 +311,8 @@ pub trait Folder {
} }
} }
fn map_exprs(&self, f: |@Expr| -> @Expr, es: &[@Expr]) -> Vec<@Expr> { fn map_exprs(&self, f: |Gc<Expr>| -> Gc<Expr>,
es: &[Gc<Expr>]) -> Vec<Gc<Expr>> {
es.iter().map(|x| f(*x)).collect() es.iter().map(|x| f(*x)).collect()
} }
@ -346,8 +348,8 @@ pub trait Folder {
/* some little folds that probably aren't useful to have in Folder itself*/ /* some little folds that probably aren't useful to have in Folder itself*/
//used in noop_fold_item and noop_fold_crate and noop_fold_crate_directive //used in noop_fold_item and noop_fold_crate and noop_fold_crate_directive
fn fold_meta_item_<T: Folder>(mi: @MetaItem, fld: &mut T) -> @MetaItem { fn fold_meta_item_<T: Folder>(mi: Gc<MetaItem>, fld: &mut T) -> Gc<MetaItem> {
@Spanned { box(GC) Spanned {
node: node:
match mi.node { match mi.node {
MetaWord(ref id) => MetaWord((*id).clone()), MetaWord(ref id) => MetaWord((*id).clone()),
@ -495,8 +497,9 @@ pub fn fold_generics<T: Folder>(generics: &Generics, fld: &mut T) -> Generics {
lifetimes: fold_lifetimes(&generics.lifetimes, fld)} lifetimes: fold_lifetimes(&generics.lifetimes, fld)}
} }
fn fold_struct_def<T: Folder>(struct_def: @StructDef, fld: &mut T) -> @StructDef { fn fold_struct_def<T: Folder>(struct_def: Gc<StructDef>,
@ast::StructDef { fld: &mut T) -> Gc<StructDef> {
box(GC) ast::StructDef {
fields: struct_def.fields.iter().map(|f| fold_struct_field(f, fld)).collect(), fields: struct_def.fields.iter().map(|f| fold_struct_field(f, fld)).collect(),
ctor_id: struct_def.ctor_id.map(|cid| fld.new_id(cid)), ctor_id: struct_def.ctor_id.map(|cid| fld.new_id(cid)),
super_struct: match struct_def.super_struct { super_struct: match struct_def.super_struct {
@ -583,7 +586,7 @@ pub fn noop_fold_view_item<T: Folder>(vi: &ViewItem, folder: &mut T)
pub fn noop_fold_block<T: Folder>(b: P<Block>, folder: &mut T) -> P<Block> { pub fn noop_fold_block<T: Folder>(b: P<Block>, folder: &mut T) -> P<Block> {
let id = folder.new_id(b.id); // Needs to be first, for ast_map. let id = folder.new_id(b.id); // Needs to be first, for ast_map.
let view_items = b.view_items.iter().map(|x| folder.fold_view_item(x)).collect(); let view_items = b.view_items.iter().map(|x| folder.fold_view_item(x)).collect();
let stmts = b.stmts.iter().flat_map(|s| folder.fold_stmt(*s).move_iter()).collect(); let stmts = b.stmts.iter().flat_map(|s| folder.fold_stmt(&**s).move_iter()).collect();
P(Block { P(Block {
id: id, id: id,
view_items: view_items, view_items: view_items,
@ -601,7 +604,7 @@ pub fn noop_fold_item_underscore<T: Folder>(i: &Item_, folder: &mut T) -> Item_
} }
ItemFn(decl, fn_style, abi, ref generics, body) => { ItemFn(decl, fn_style, abi, ref generics, body) => {
ItemFn( ItemFn(
folder.fold_fn_decl(decl), folder.fold_fn_decl(&*decl),
fn_style, fn_style,
abi, abi,
fold_generics(generics, folder), fold_generics(generics, folder),
@ -617,7 +620,7 @@ pub fn noop_fold_item_underscore<T: Folder>(i: &Item_, folder: &mut T) -> Item_
ItemEnum( ItemEnum(
ast::EnumDef { ast::EnumDef {
variants: enum_definition.variants.iter().map(|&x| { variants: enum_definition.variants.iter().map(|&x| {
folder.fold_variant(x) folder.fold_variant(&*x)
}).collect(), }).collect(),
}, },
fold_generics(generics, folder)) fold_generics(generics, folder))
@ -656,7 +659,7 @@ pub fn noop_fold_type_method<T: Folder>(m: &TypeMethod, fld: &mut T) -> TypeMeth
ident: fld.fold_ident(m.ident), ident: fld.fold_ident(m.ident),
attrs: m.attrs.iter().map(|a| fold_attribute_(*a, fld)).collect(), attrs: m.attrs.iter().map(|a| fold_attribute_(*a, fld)).collect(),
fn_style: m.fn_style, fn_style: m.fn_style,
decl: fld.fold_fn_decl(m.decl), decl: fld.fold_fn_decl(&*m.decl),
generics: fold_generics(&m.generics, fld), generics: fold_generics(&m.generics, fld),
explicit_self: fld.fold_explicit_self(&m.explicit_self), explicit_self: fld.fold_explicit_self(&m.explicit_self),
span: fld.new_span(m.span), span: fld.new_span(m.span),
@ -683,18 +686,19 @@ pub fn noop_fold_crate<T: Folder>(c: Crate, folder: &mut T) -> Crate {
} }
} }
pub fn noop_fold_item<T: Folder>(i: &Item, folder: &mut T) -> SmallVector<@Item> { pub fn noop_fold_item<T: Folder>(i: &Item,
folder: &mut T) -> SmallVector<Gc<Item>> {
let id = folder.new_id(i.id); // Needs to be first, for ast_map. let id = folder.new_id(i.id); // Needs to be first, for ast_map.
let node = folder.fold_item_underscore(&i.node); let node = folder.fold_item_underscore(&i.node);
let ident = match node { let ident = match node {
// The node may have changed, recompute the "pretty" impl name. // The node may have changed, recompute the "pretty" impl name.
ItemImpl(_, ref maybe_trait, ty, _) => { ItemImpl(_, ref maybe_trait, ty, _) => {
ast_util::impl_pretty_name(maybe_trait, ty) ast_util::impl_pretty_name(maybe_trait, &*ty)
} }
_ => i.ident _ => i.ident
}; };
SmallVector::one(@Item { SmallVector::one(box(GC) Item {
id: id, id: id,
ident: folder.fold_ident(ident), ident: folder.fold_ident(ident),
attrs: i.attrs.iter().map(|e| fold_attribute_(*e, folder)).collect(), attrs: i.attrs.iter().map(|e| fold_attribute_(*e, folder)).collect(),
@ -704,9 +708,10 @@ pub fn noop_fold_item<T: Folder>(i: &Item, folder: &mut T) -> SmallVector<@Item>
}) })
} }
pub fn noop_fold_foreign_item<T: Folder>(ni: &ForeignItem, folder: &mut T) -> @ForeignItem { pub fn noop_fold_foreign_item<T: Folder>(ni: &ForeignItem,
folder: &mut T) -> Gc<ForeignItem> {
let id = folder.new_id(ni.id); // Needs to be first, for ast_map. let id = folder.new_id(ni.id); // Needs to be first, for ast_map.
@ForeignItem { box(GC) ForeignItem {
id: id, id: id,
ident: folder.fold_ident(ni.ident), ident: folder.fold_ident(ni.ident),
attrs: ni.attrs.iter().map(|x| fold_attribute_(*x, folder)).collect(), attrs: ni.attrs.iter().map(|x| fold_attribute_(*x, folder)).collect(),
@ -728,23 +733,23 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: &ForeignItem, folder: &mut T) -> @F
} }
} }
pub fn noop_fold_method<T: Folder>(m: &Method, folder: &mut T) -> @Method { pub fn noop_fold_method<T: Folder>(m: &Method, folder: &mut T) -> Gc<Method> {
let id = folder.new_id(m.id); // Needs to be first, for ast_map. let id = folder.new_id(m.id); // Needs to be first, for ast_map.
@Method { box(GC) Method {
id: id, id: id,
ident: folder.fold_ident(m.ident), ident: folder.fold_ident(m.ident),
attrs: m.attrs.iter().map(|a| fold_attribute_(*a, folder)).collect(), attrs: m.attrs.iter().map(|a| fold_attribute_(*a, folder)).collect(),
generics: fold_generics(&m.generics, folder), generics: fold_generics(&m.generics, folder),
explicit_self: folder.fold_explicit_self(&m.explicit_self), explicit_self: folder.fold_explicit_self(&m.explicit_self),
fn_style: m.fn_style, fn_style: m.fn_style,
decl: folder.fold_fn_decl(m.decl), decl: folder.fold_fn_decl(&*m.decl),
body: folder.fold_block(m.body), body: folder.fold_block(m.body),
span: folder.new_span(m.span), span: folder.new_span(m.span),
vis: m.vis vis: m.vis
} }
} }
pub fn noop_fold_pat<T: Folder>(p: @Pat, folder: &mut T) -> @Pat { pub fn noop_fold_pat<T: Folder>(p: Gc<Pat>, folder: &mut T) -> Gc<Pat> {
let id = folder.new_id(p.id); let id = folder.new_id(p.id);
let node = match p.node { let node = match p.node {
PatWild => PatWild, PatWild => PatWild,
@ -783,14 +788,14 @@ pub fn noop_fold_pat<T: Folder>(p: @Pat, folder: &mut T) -> @Pat {
PatMac(ref mac) => PatMac(folder.fold_mac(mac)), PatMac(ref mac) => PatMac(folder.fold_mac(mac)),
}; };
@Pat { box(GC) Pat {
id: id, id: id,
span: folder.new_span(p.span), span: folder.new_span(p.span),
node: node, node: node,
} }
} }
pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr { pub fn noop_fold_expr<T: Folder>(e: Gc<Expr>, folder: &mut T) -> Gc<Expr> {
let id = folder.new_id(e.id); let id = folder.new_id(e.id);
let node = match e.node { let node = match e.node {
ExprVstore(e, v) => { ExprVstore(e, v) => {
@ -851,13 +856,15 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
ExprMatch(folder.fold_expr(expr), ExprMatch(folder.fold_expr(expr),
arms.iter().map(|x| folder.fold_arm(x)).collect()) arms.iter().map(|x| folder.fold_arm(x)).collect())
} }
ExprFnBlock(decl, body) => { ExprFnBlock(ref decl, ref body) => {
ExprFnBlock(folder.fold_fn_decl(decl), folder.fold_block(body)) ExprFnBlock(folder.fold_fn_decl(&**decl),
folder.fold_block(body.clone()))
} }
ExprProc(decl, body) => { ExprProc(ref decl, ref body) => {
ExprProc(folder.fold_fn_decl(decl), folder.fold_block(body)) ExprProc(folder.fold_fn_decl(&**decl),
folder.fold_block(body.clone()))
} }
ExprBlock(blk) => ExprBlock(folder.fold_block(blk)), ExprBlock(ref blk) => ExprBlock(folder.fold_block(blk.clone())),
ExprAssign(el, er) => { ExprAssign(el, er) => {
ExprAssign(folder.fold_expr(el), folder.fold_expr(er)) ExprAssign(folder.fold_expr(el), folder.fold_expr(er))
} }
@ -900,14 +907,15 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
ExprParen(ex) => ExprParen(folder.fold_expr(ex)) ExprParen(ex) => ExprParen(folder.fold_expr(ex))
}; };
@Expr { box(GC) Expr {
id: id, id: id,
node: node, node: node,
span: folder.new_span(e.span), span: folder.new_span(e.span),
} }
} }
pub fn noop_fold_stmt<T: Folder>(s: &Stmt, folder: &mut T) -> SmallVector<@Stmt> { pub fn noop_fold_stmt<T: Folder>(s: &Stmt,
folder: &mut T) -> SmallVector<Gc<Stmt>> {
let nodes = match s.node { let nodes = match s.node {
StmtDecl(d, id) => { StmtDecl(d, id) => {
let id = folder.new_id(id); let id = folder.new_id(id);
@ -926,7 +934,7 @@ pub fn noop_fold_stmt<T: Folder>(s: &Stmt, folder: &mut T) -> SmallVector<@Stmt>
StmtMac(ref mac, semi) => SmallVector::one(StmtMac(folder.fold_mac(mac), semi)) StmtMac(ref mac, semi) => SmallVector::one(StmtMac(folder.fold_mac(mac), semi))
}; };
nodes.move_iter().map(|node| @Spanned { nodes.move_iter().map(|node| box(GC) Spanned {
node: node, node: node,
span: folder.new_span(s.span), span: folder.new_span(s.span),
}).collect() }).collect()

View file

@ -16,15 +16,17 @@ use parse::token;
use parse::parser::Parser; use parse::parser::Parser;
use parse::token::INTERPOLATED; use parse::token::INTERPOLATED;
use std::gc::Gc;
// a parser that can parse attributes. // a parser that can parse attributes.
pub trait ParserAttr { pub trait ParserAttr {
fn parse_outer_attributes(&mut self) -> Vec<ast::Attribute> ; fn parse_outer_attributes(&mut self) -> Vec<ast::Attribute>;
fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute; fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute;
fn parse_inner_attrs_and_next(&mut self) fn parse_inner_attrs_and_next(&mut self)
-> (Vec<ast::Attribute> , Vec<ast::Attribute> ); -> (Vec<ast::Attribute>, Vec<ast::Attribute>);
fn parse_meta_item(&mut self) -> @ast::MetaItem; fn parse_meta_item(&mut self) -> Gc<ast::MetaItem>;
fn parse_meta_seq(&mut self) -> Vec<@ast::MetaItem> ; fn parse_meta_seq(&mut self) -> Vec<Gc<ast::MetaItem>>;
fn parse_optional_meta(&mut self) -> Vec<@ast::MetaItem> ; fn parse_optional_meta(&mut self) -> Vec<Gc<ast::MetaItem>>;
} }
impl<'a> ParserAttr for Parser<'a> { impl<'a> ParserAttr for Parser<'a> {
@ -157,7 +159,7 @@ impl<'a> ParserAttr for Parser<'a> {
// matches meta_item = IDENT // matches meta_item = IDENT
// | IDENT = lit // | IDENT = lit
// | IDENT meta_seq // | IDENT meta_seq
fn parse_meta_item(&mut self) -> @ast::MetaItem { fn parse_meta_item(&mut self) -> Gc<ast::MetaItem> {
match self.token { match self.token {
token::INTERPOLATED(token::NtMeta(e)) => { token::INTERPOLATED(token::NtMeta(e)) => {
self.bump(); self.bump();
@ -184,29 +186,29 @@ impl<'a> ParserAttr for Parser<'a> {
} }
} }
let hi = self.span.hi; let hi = self.span.hi;
@spanned(lo, hi, ast::MetaNameValue(name, lit)) box(GC) spanned(lo, hi, ast::MetaNameValue(name, lit))
} }
token::LPAREN => { token::LPAREN => {
let inner_items = self.parse_meta_seq(); let inner_items = self.parse_meta_seq();
let hi = self.span.hi; let hi = self.span.hi;
@spanned(lo, hi, ast::MetaList(name, inner_items)) box(GC) spanned(lo, hi, ast::MetaList(name, inner_items))
} }
_ => { _ => {
let hi = self.last_span.hi; let hi = self.last_span.hi;
@spanned(lo, hi, ast::MetaWord(name)) box(GC) spanned(lo, hi, ast::MetaWord(name))
} }
} }
} }
// matches meta_seq = ( COMMASEP(meta_item) ) // matches meta_seq = ( COMMASEP(meta_item) )
fn parse_meta_seq(&mut self) -> Vec<@ast::MetaItem> { fn parse_meta_seq(&mut self) -> Vec<Gc<ast::MetaItem>> {
self.parse_seq(&token::LPAREN, self.parse_seq(&token::LPAREN,
&token::RPAREN, &token::RPAREN,
seq_sep_trailing_disallowed(token::COMMA), seq_sep_trailing_disallowed(token::COMMA),
|p| p.parse_meta_item()).node |p| p.parse_meta_item()).node
} }
fn parse_optional_meta(&mut self) -> Vec<@ast::MetaItem> { fn parse_optional_meta(&mut self) -> Vec<Gc<ast::MetaItem>> {
match self.token { match self.token {
token::LPAREN => self.parse_meta_seq(), token::LPAREN => self.parse_meta_seq(),
_ => Vec::new() _ => Vec::new()

View file

@ -13,6 +13,7 @@
// Predicates on exprs and stmts that the pretty-printer and parser use // Predicates on exprs and stmts that the pretty-printer and parser use
use ast; use ast;
use std::gc::Gc;
// does this expression require a semicolon to be treated // does this expression require a semicolon to be treated
// as a statement? The negation of this: 'can this expression // as a statement? The negation of this: 'can this expression
@ -21,7 +22,7 @@ use ast;
// 'if true {...} else {...} // 'if true {...} else {...}
// |x| 5 ' // |x| 5 '
// isn't parsed as (if true {...} else {...} | x) | 5 // isn't parsed as (if true {...} else {...} | x) | 5
pub fn expr_requires_semi_to_be_stmt(e: @ast::Expr) -> bool { pub fn expr_requires_semi_to_be_stmt(e: Gc<ast::Expr>) -> bool {
match e.node { match e.node {
ast::ExprIf(..) ast::ExprIf(..)
| ast::ExprMatch(..) | ast::ExprMatch(..)
@ -33,7 +34,7 @@ pub fn expr_requires_semi_to_be_stmt(e: @ast::Expr) -> bool {
} }
} }
pub fn expr_is_simple_block(e: @ast::Expr) -> bool { pub fn expr_is_simple_block(e: Gc<ast::Expr>) -> bool {
match e.node { match e.node {
ast::ExprBlock(block) => block.rules == ast::DefaultBlock, ast::ExprBlock(block) => block.rules == ast::DefaultBlock,
_ => false _ => false

View file

@ -18,6 +18,7 @@ use parse::attr::ParserAttr;
use parse::parser::Parser; use parse::parser::Parser;
use std::cell::RefCell; use std::cell::RefCell;
use std::gc::Gc;
use std::io::File; use std::io::File;
use std::rc::Rc; use std::rc::Rc;
use std::str; use std::str;
@ -105,7 +106,7 @@ pub fn parse_expr_from_source_str(name: String,
source: String, source: String,
cfg: ast::CrateConfig, cfg: ast::CrateConfig,
sess: &ParseSess) sess: &ParseSess)
-> @ast::Expr { -> Gc<ast::Expr> {
let mut p = new_parser_from_source_str(sess, cfg, name, source); let mut p = new_parser_from_source_str(sess, cfg, name, source);
maybe_aborted(p.parse_expr(), p) maybe_aborted(p.parse_expr(), p)
} }
@ -114,7 +115,7 @@ pub fn parse_item_from_source_str(name: String,
source: String, source: String,
cfg: ast::CrateConfig, cfg: ast::CrateConfig,
sess: &ParseSess) sess: &ParseSess)
-> Option<@ast::Item> { -> Option<Gc<ast::Item>> {
let mut p = new_parser_from_source_str(sess, cfg, name, source); let mut p = new_parser_from_source_str(sess, cfg, name, source);
let attrs = p.parse_outer_attributes(); let attrs = p.parse_outer_attributes();
maybe_aborted(p.parse_item(attrs),p) maybe_aborted(p.parse_item(attrs),p)
@ -124,7 +125,7 @@ pub fn parse_meta_from_source_str(name: String,
source: String, source: String,
cfg: ast::CrateConfig, cfg: ast::CrateConfig,
sess: &ParseSess) sess: &ParseSess)
-> @ast::MetaItem { -> Gc<ast::MetaItem> {
let mut p = new_parser_from_source_str(sess, cfg, name, source); let mut p = new_parser_from_source_str(sess, cfg, name, source);
maybe_aborted(p.parse_meta_item(),p) maybe_aborted(p.parse_meta_item(),p)
} }
@ -134,7 +135,7 @@ pub fn parse_stmt_from_source_str(name: String,
cfg: ast::CrateConfig, cfg: ast::CrateConfig,
attrs: Vec<ast::Attribute> , attrs: Vec<ast::Attribute> ,
sess: &ParseSess) sess: &ParseSess)
-> @ast::Stmt { -> Gc<ast::Stmt> {
let mut p = new_parser_from_source_str( let mut p = new_parser_from_source_str(
sess, sess,
cfg, cfg,
@ -306,7 +307,7 @@ mod test {
#[test] fn path_exprs_1() { #[test] fn path_exprs_1() {
assert!(string_to_expr("a".to_string()) == assert!(string_to_expr("a".to_string()) ==
@ast::Expr{ box(GC) ast::Expr{
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::ExprPath(ast::Path { node: ast::ExprPath(ast::Path {
span: sp(0, 1), span: sp(0, 1),
@ -325,7 +326,7 @@ mod test {
#[test] fn path_exprs_2 () { #[test] fn path_exprs_2 () {
assert!(string_to_expr("::a::b".to_string()) == assert!(string_to_expr("::a::b".to_string()) ==
@ast::Expr { box(GC) ast::Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::ExprPath(ast::Path { node: ast::ExprPath(ast::Path {
span: sp(0, 6), span: sp(0, 6),
@ -537,9 +538,9 @@ mod test {
#[test] fn ret_expr() { #[test] fn ret_expr() {
assert!(string_to_expr("return d".to_string()) == assert!(string_to_expr("return d".to_string()) ==
@ast::Expr{ box(GC) ast::Expr{
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node:ast::ExprRet(Some(@ast::Expr{ node:ast::ExprRet(Some(box(GC) ast::Expr{
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node:ast::ExprPath(ast::Path{ node:ast::ExprPath(ast::Path{
span: sp(7, 8), span: sp(7, 8),
@ -560,8 +561,8 @@ mod test {
#[test] fn parse_stmt_1 () { #[test] fn parse_stmt_1 () {
assert!(string_to_stmt("b;".to_string()) == assert!(string_to_stmt("b;".to_string()) ==
@Spanned{ box(GC) Spanned{
node: ast::StmtExpr(@ast::Expr { node: ast::StmtExpr(box(GC) ast::Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::ExprPath(ast::Path { node: ast::ExprPath(ast::Path {
span:sp(0,1), span:sp(0,1),
@ -588,7 +589,7 @@ mod test {
let sess = new_parse_sess(); let sess = new_parse_sess();
let mut parser = string_to_parser(&sess, "b".to_string()); let mut parser = string_to_parser(&sess, "b".to_string());
assert!(parser.parse_pat() == assert!(parser.parse_pat() ==
@ast::Pat{id: ast::DUMMY_NODE_ID, box(GC) ast::Pat{id: ast::DUMMY_NODE_ID,
node: ast::PatIdent( node: ast::PatIdent(
ast::BindByValue(ast::MutImmutable), ast::BindByValue(ast::MutImmutable),
ast::Path { ast::Path {
@ -612,7 +613,7 @@ mod test {
// this test depends on the intern order of "fn" and "int" // this test depends on the intern order of "fn" and "int"
assert!(string_to_item("fn a (b : int) { b; }".to_string()) == assert!(string_to_item("fn a (b : int) { b; }".to_string()) ==
Some( Some(
@ast::Item{ident:str_to_ident("a"), box(GC) ast::Item{ident:str_to_ident("a"),
attrs:Vec::new(), attrs:Vec::new(),
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::ItemFn(ast::P(ast::FnDecl { node: ast::ItemFn(ast::P(ast::FnDecl {
@ -632,7 +633,7 @@ mod test {
}, None, ast::DUMMY_NODE_ID), }, None, ast::DUMMY_NODE_ID),
span:sp(10,13) span:sp(10,13)
}), }),
pat: @ast::Pat { pat: box(GC) ast::Pat {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::PatIdent( node: ast::PatIdent(
ast::BindByValue(ast::MutImmutable), ast::BindByValue(ast::MutImmutable),
@ -668,8 +669,8 @@ mod test {
}, },
ast::P(ast::Block { ast::P(ast::Block {
view_items: Vec::new(), view_items: Vec::new(),
stmts: vec!(@Spanned{ stmts: vec!(box(GC) Spanned{
node: ast::StmtSemi(@ast::Expr{ node: ast::StmtSemi(box(GC) ast::Expr{
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::ExprPath( node: ast::ExprPath(
ast::Path{ ast::Path{
@ -703,12 +704,12 @@ mod test {
#[test] fn parse_exprs () { #[test] fn parse_exprs () {
// just make sure that they parse.... // just make sure that they parse....
string_to_expr("3 + 4".to_string()); string_to_expr("3 + 4".to_string());
string_to_expr("a::z.froob(b,@(987+3))".to_string()); string_to_expr("a::z.froob(b,box(GC)(987+3))".to_string());
} }
#[test] fn attrs_fix_bug () { #[test] fn attrs_fix_bug () {
string_to_item("pub fn mk_file_writer(path: &Path, flags: &[FileFlag]) string_to_item("pub fn mk_file_writer(path: &Path, flags: &[FileFlag])
-> Result<@Writer, String> { -> Result<Gc<Writer>, String> {
#[cfg(windows)] #[cfg(windows)]
fn wb() -> c_int { fn wb() -> c_int {
(O_WRONLY | libc::consts::os::extra::O_BINARY) as c_int (O_WRONLY | libc::consts::os::extra::O_BINARY) as c_int

View file

@ -22,6 +22,8 @@ use codemap::{Span, respan};
use parse::parser; use parse::parser;
use parse::token; use parse::token;
use std::gc::Gc;
/// The specific types of unsupported syntax /// The specific types of unsupported syntax
#[deriving(PartialEq, Eq, Hash)] #[deriving(PartialEq, Eq, Hash)]
pub enum ObsoleteSyntax { pub enum ObsoleteSyntax {
@ -35,7 +37,7 @@ pub trait ParserObsoleteMethods {
fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax); fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax);
// Reports an obsolete syntax non-fatal error, and returns // Reports an obsolete syntax non-fatal error, and returns
// a placeholder expression // a placeholder expression
fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> @Expr; fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> Gc<Expr>;
fn report(&mut self, fn report(&mut self,
sp: Span, sp: Span,
kind: ObsoleteSyntax, kind: ObsoleteSyntax,
@ -68,9 +70,9 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> {
// Reports an obsolete syntax non-fatal error, and returns // Reports an obsolete syntax non-fatal error, and returns
// a placeholder expression // a placeholder expression
fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> @Expr { fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> Gc<Expr> {
self.obsolete(sp, kind); self.obsolete(sp, kind);
self.mk_expr(sp.lo, sp.hi, ExprLit(@respan(sp, LitNil))) self.mk_expr(sp.lo, sp.hi, ExprLit(box(GC) respan(sp, LitNil)))
} }
fn report(&mut self, fn report(&mut self,

View file

@ -79,7 +79,7 @@ use owned_slice::OwnedSlice;
use std::collections::HashSet; use std::collections::HashSet;
use std::mem::replace; use std::mem::replace;
use std::rc::Rc; use std::rc::Rc;
use std::string::String; use std::gc::Gc;
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[deriving(PartialEq)] #[deriving(PartialEq)]
@ -119,9 +119,9 @@ pub struct PathAndBounds {
enum ItemOrViewItem { enum ItemOrViewItem {
// Indicates a failure to parse any kind of item. The attributes are // Indicates a failure to parse any kind of item. The attributes are
// returned. // returned.
IoviNone(Vec<Attribute> ), IoviNone(Vec<Attribute>),
IoviItem(@Item), IoviItem(Gc<Item>),
IoviForeignItem(@ForeignItem), IoviForeignItem(Gc<ForeignItem>),
IoviViewItem(ViewItem) IoviViewItem(ViewItem)
} }
@ -275,9 +275,9 @@ fn maybe_append(lhs: Vec<Attribute> , rhs: Option<Vec<Attribute> >)
struct ParsedItemsAndViewItems { struct ParsedItemsAndViewItems {
attrs_remaining: Vec<Attribute> , attrs_remaining: Vec<Attribute>,
view_items: Vec<ViewItem> , view_items: Vec<ViewItem>,
items: Vec<@Item> , items: Vec<@Item>,
foreign_items: Vec<@ForeignItem> foreign_items: Vec<@ForeignItem>
} }
@ -454,7 +454,8 @@ impl<'a> Parser<'a> {
// Commit to parsing a complete expression `e` expected to be // Commit to parsing a complete expression `e` expected to be
// followed by some token from the set edible + inedible. Recover // followed by some token from the set edible + inedible. Recover
// from anticipated input errors, discarding erroneous characters. // from anticipated input errors, discarding erroneous characters.
pub fn commit_expr(&mut self, e: @Expr, edible: &[token::Token], inedible: &[token::Token]) { pub fn commit_expr(&mut self, e: Gc<Expr>, edible: &[token::Token],
inedible: &[token::Token]) {
debug!("commit_expr {:?}", e); debug!("commit_expr {:?}", e);
match e.node { match e.node {
ExprPath(..) => { ExprPath(..) => {
@ -469,14 +470,15 @@ impl<'a> Parser<'a> {
self.expect_one_of(edible, inedible) self.expect_one_of(edible, inedible)
} }
pub fn commit_expr_expecting(&mut self, e: @Expr, edible: token::Token) { pub fn commit_expr_expecting(&mut self, e: Gc<Expr>, edible: token::Token) {
self.commit_expr(e, &[edible], &[]) self.commit_expr(e, &[edible], &[])
} }
// Commit to parsing a complete statement `s`, which expects to be // Commit to parsing a complete statement `s`, which expects to be
// followed by some token from the set edible + inedible. Check // followed by some token from the set edible + inedible. Check
// for recoverable input errors, discarding erroneous characters. // for recoverable input errors, discarding erroneous characters.
pub fn commit_stmt(&mut self, s: @Stmt, edible: &[token::Token], inedible: &[token::Token]) { pub fn commit_stmt(&mut self, s: Gc<Stmt>, edible: &[token::Token],
inedible: &[token::Token]) {
debug!("commit_stmt {:?}", s); debug!("commit_stmt {:?}", s);
let _s = s; // unused, but future checks might want to inspect `s`. let _s = s; // unused, but future checks might want to inspect `s`.
if self.last_token.as_ref().map_or(false, |t| is_ident_or_path(*t)) { if self.last_token.as_ref().map_or(false, |t| is_ident_or_path(*t)) {
@ -488,7 +490,7 @@ impl<'a> Parser<'a> {
self.expect_one_of(edible, inedible) self.expect_one_of(edible, inedible)
} }
pub fn commit_stmt_expecting(&mut self, s: @Stmt, edible: token::Token) { pub fn commit_stmt_expecting(&mut self, s: Gc<Stmt>, edible: token::Token) {
self.commit_stmt(s, &[edible], &[]) self.commit_stmt(s, &[edible], &[])
} }
@ -980,7 +982,7 @@ impl<'a> Parser<'a> {
self.expect_keyword(keywords::Fn); self.expect_keyword(keywords::Fn);
let (decl, lifetimes) = self.parse_ty_fn_decl(true); let (decl, lifetimes) = self.parse_ty_fn_decl(true);
return TyBareFn(@BareFnTy { return TyBareFn(box(GC) BareFnTy {
abi: abi, abi: abi,
fn_style: fn_style, fn_style: fn_style,
lifetimes: lifetimes, lifetimes: lifetimes,
@ -1021,7 +1023,7 @@ impl<'a> Parser<'a> {
cf: ret_style, cf: ret_style,
variadic: variadic variadic: variadic
}); });
TyProc(@ClosureTy { TyProc(box(GC) ClosureTy {
fn_style: NormalFn, fn_style: NormalFn,
onceness: Once, onceness: Once,
bounds: bounds, bounds: bounds,
@ -1092,11 +1094,11 @@ impl<'a> Parser<'a> {
}); });
if is_unboxed { if is_unboxed {
TyUnboxedFn(@UnboxedFnTy { TyUnboxedFn(box(GC) UnboxedFnTy {
decl: decl, decl: decl,
}) })
} else { } else {
TyClosure(@ClosureTy { TyClosure(box(GC) ClosureTy {
fn_style: fn_style, fn_style: fn_style,
onceness: onceness, onceness: onceness,
bounds: bounds, bounds: bounds,
@ -1192,7 +1194,7 @@ impl<'a> Parser<'a> {
let (inner_attrs, body) = let (inner_attrs, body) =
p.parse_inner_attrs_and_block(); p.parse_inner_attrs_and_block();
let attrs = attrs.append(inner_attrs.as_slice()); let attrs = attrs.append(inner_attrs.as_slice());
Provided(@ast::Method { Provided(box(GC) ast::Method {
ident: ident, ident: ident,
attrs: attrs, attrs: attrs,
generics: generics, generics: generics,
@ -1465,7 +1467,7 @@ impl<'a> Parser<'a> {
} }
} }
pub fn maybe_parse_fixed_vstore(&mut self) -> Option<@ast::Expr> { pub fn maybe_parse_fixed_vstore(&mut self) -> Option<Gc<ast::Expr>> {
if self.token == token::COMMA && if self.token == token::COMMA &&
self.look_ahead(1, |t| *t == token::DOTDOT) { self.look_ahead(1, |t| *t == token::DOTDOT) {
self.bump(); self.bump();
@ -1516,12 +1518,12 @@ impl<'a> Parser<'a> {
} }
// matches '-' lit | lit // matches '-' lit | lit
pub fn parse_literal_maybe_minus(&mut self) -> @Expr { pub fn parse_literal_maybe_minus(&mut self) -> Gc<Expr> {
let minus_lo = self.span.lo; let minus_lo = self.span.lo;
let minus_present = self.eat(&token::BINOP(token::MINUS)); let minus_present = self.eat(&token::BINOP(token::MINUS));
let lo = self.span.lo; let lo = self.span.lo;
let literal = @self.parse_lit(); let literal = box(GC) self.parse_lit();
let hi = self.span.hi; let hi = self.span.hi;
let expr = self.mk_expr(lo, hi, ExprLit(literal)); let expr = self.mk_expr(lo, hi, ExprLit(literal));
@ -1723,62 +1725,65 @@ impl<'a> Parser<'a> {
} }
} }
pub fn mk_expr(&mut self, lo: BytePos, hi: BytePos, node: Expr_) -> @Expr { pub fn mk_expr(&mut self, lo: BytePos, hi: BytePos, node: Expr_) -> Gc<Expr> {
@Expr { box(GC) Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: node, node: node,
span: mk_sp(lo, hi), span: mk_sp(lo, hi),
} }
} }
pub fn mk_unary(&mut self, unop: ast::UnOp, expr: @Expr) -> ast::Expr_ { pub fn mk_unary(&mut self, unop: ast::UnOp, expr: Gc<Expr>) -> ast::Expr_ {
ExprUnary(unop, expr) ExprUnary(unop, expr)
} }
pub fn mk_binary(&mut self, binop: ast::BinOp, lhs: @Expr, rhs: @Expr) -> ast::Expr_ { pub fn mk_binary(&mut self, binop: ast::BinOp,
lhs: Gc<Expr>, rhs: Gc<Expr>) -> ast::Expr_ {
ExprBinary(binop, lhs, rhs) ExprBinary(binop, lhs, rhs)
} }
pub fn mk_call(&mut self, f: @Expr, args: Vec<@Expr> ) -> ast::Expr_ { pub fn mk_call(&mut self, f: Gc<Expr>, args: Vec<Gc<Expr>>) -> ast::Expr_ {
ExprCall(f, args) ExprCall(f, args)
} }
fn mk_method_call(&mut self, fn mk_method_call(&mut self,
ident: ast::SpannedIdent, ident: ast::SpannedIdent,
tps: Vec<P<Ty>>, tps: Vec<P<Ty>>,
args: Vec<@Expr>) args: Vec<Gc<Expr>>)
-> ast::Expr_ { -> ast::Expr_ {
ExprMethodCall(ident, tps, args) ExprMethodCall(ident, tps, args)
} }
pub fn mk_index(&mut self, expr: @Expr, idx: @Expr) -> ast::Expr_ { pub fn mk_index(&mut self, expr: Gc<Expr>, idx: Gc<Expr>) -> ast::Expr_ {
ExprIndex(expr, idx) ExprIndex(expr, idx)
} }
pub fn mk_field(&mut self, expr: @Expr, ident: Ident, tys: Vec<P<Ty>> ) -> ast::Expr_ { pub fn mk_field(&mut self, expr: Gc<Expr>, ident: Ident,
tys: Vec<P<Ty>>) -> ast::Expr_ {
ExprField(expr, ident, tys) ExprField(expr, ident, tys)
} }
pub fn mk_assign_op(&mut self, binop: ast::BinOp, lhs: @Expr, rhs: @Expr) -> ast::Expr_ { pub fn mk_assign_op(&mut self, binop: ast::BinOp,
lhs: Gc<Expr>, rhs: Gc<Expr>) -> ast::Expr_ {
ExprAssignOp(binop, lhs, rhs) ExprAssignOp(binop, lhs, rhs)
} }
pub fn mk_mac_expr(&mut self, lo: BytePos, hi: BytePos, m: Mac_) -> @Expr { pub fn mk_mac_expr(&mut self, lo: BytePos, hi: BytePos, m: Mac_) -> Gc<Expr> {
@Expr { box(GC) Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ExprMac(codemap::Spanned {node: m, span: mk_sp(lo, hi)}), node: ExprMac(codemap::Spanned {node: m, span: mk_sp(lo, hi)}),
span: mk_sp(lo, hi), span: mk_sp(lo, hi),
} }
} }
pub fn mk_lit_u32(&mut self, i: u32) -> @Expr { pub fn mk_lit_u32(&mut self, i: u32) -> Gc<Expr> {
let span = &self.span; let span = &self.span;
let lv_lit = @codemap::Spanned { let lv_lit = box(GC) codemap::Spanned {
node: LitUint(i as u64, TyU32), node: LitUint(i as u64, TyU32),
span: *span span: *span
}; };
@Expr { box(GC) Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ExprLit(lv_lit), node: ExprLit(lv_lit),
span: *span, span: *span,
@ -1788,7 +1793,7 @@ impl<'a> Parser<'a> {
// at the bottom (top?) of the precedence hierarchy, // at the bottom (top?) of the precedence hierarchy,
// parse things like parenthesized exprs, // parse things like parenthesized exprs,
// macros, return, etc. // macros, return, etc.
pub fn parse_bottom_expr(&mut self) -> @Expr { pub fn parse_bottom_expr(&mut self) -> Gc<Expr> {
maybe_whole_expr!(self); maybe_whole_expr!(self);
let lo = self.span.lo; let lo = self.span.lo;
@ -1804,7 +1809,7 @@ impl<'a> Parser<'a> {
if self.token == token::RPAREN { if self.token == token::RPAREN {
hi = self.span.hi; hi = self.span.hi;
self.bump(); self.bump();
let lit = @spanned(lo, hi, LitNil); let lit = box(GC) spanned(lo, hi, LitNil);
return self.mk_expr(lo, hi, ExprLit(lit)); return self.mk_expr(lo, hi, ExprLit(lit));
} }
let mut es = vec!(self.parse_expr()); let mut es = vec!(self.parse_expr());
@ -1991,7 +1996,7 @@ impl<'a> Parser<'a> {
// other literal expression // other literal expression
let lit = self.parse_lit(); let lit = self.parse_lit();
hi = lit.span.hi; hi = lit.span.hi;
ex = ExprLit(@lit); ex = ExprLit(box(GC) lit);
} }
return self.mk_expr(lo, hi, ex); return self.mk_expr(lo, hi, ex);
@ -1999,19 +2004,19 @@ impl<'a> Parser<'a> {
// parse a block or unsafe block // parse a block or unsafe block
pub fn parse_block_expr(&mut self, lo: BytePos, blk_mode: BlockCheckMode) pub fn parse_block_expr(&mut self, lo: BytePos, blk_mode: BlockCheckMode)
-> @Expr { -> Gc<Expr> {
self.expect(&token::LBRACE); self.expect(&token::LBRACE);
let blk = self.parse_block_tail(lo, blk_mode); let blk = self.parse_block_tail(lo, blk_mode);
return self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk)); return self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk));
} }
// parse a.b or a(13) or a[4] or just a // parse a.b or a(13) or a[4] or just a
pub fn parse_dot_or_call_expr(&mut self) -> @Expr { pub fn parse_dot_or_call_expr(&mut self) -> Gc<Expr> {
let b = self.parse_bottom_expr(); let b = self.parse_bottom_expr();
self.parse_dot_or_call_expr_with(b) self.parse_dot_or_call_expr_with(b)
} }
pub fn parse_dot_or_call_expr_with(&mut self, e0: @Expr) -> @Expr { pub fn parse_dot_or_call_expr_with(&mut self, e0: Gc<Expr>) -> Gc<Expr> {
let mut e = e0; let mut e = e0;
let lo = e.span.lo; let lo = e.span.lo;
let mut hi; let mut hi;
@ -2282,7 +2287,7 @@ impl<'a> Parser<'a> {
} }
// parse a prefix-operator expr // parse a prefix-operator expr
pub fn parse_prefix_expr(&mut self) -> @Expr { pub fn parse_prefix_expr(&mut self) -> Gc<Expr> {
let lo = self.span.lo; let lo = self.span.lo;
let hi; let hi;
@ -2384,13 +2389,14 @@ impl<'a> Parser<'a> {
} }
// parse an expression of binops // parse an expression of binops
pub fn parse_binops(&mut self) -> @Expr { pub fn parse_binops(&mut self) -> Gc<Expr> {
let prefix_expr = self.parse_prefix_expr(); let prefix_expr = self.parse_prefix_expr();
self.parse_more_binops(prefix_expr, 0) self.parse_more_binops(prefix_expr, 0)
} }
// parse an expression of binops of at least min_prec precedence // parse an expression of binops of at least min_prec precedence
pub fn parse_more_binops(&mut self, lhs: @Expr, min_prec: uint) -> @Expr { pub fn parse_more_binops(&mut self, lhs: Gc<Expr>,
min_prec: uint) -> Gc<Expr> {
if self.expr_is_complete(lhs) { return lhs; } if self.expr_is_complete(lhs) { return lhs; }
// Prevent dynamic borrow errors later on by limiting the // Prevent dynamic borrow errors later on by limiting the
@ -2439,7 +2445,7 @@ impl<'a> Parser<'a> {
// parse an assignment expression.... // parse an assignment expression....
// actually, this seems to be the main entry point for // actually, this seems to be the main entry point for
// parsing an arbitrary expression. // parsing an arbitrary expression.
pub fn parse_assign_expr(&mut self) -> @Expr { pub fn parse_assign_expr(&mut self) -> Gc<Expr> {
let lo = self.span.lo; let lo = self.span.lo;
let lhs = self.parse_binops(); let lhs = self.parse_binops();
match self.token { match self.token {
@ -2473,11 +2479,11 @@ impl<'a> Parser<'a> {
} }
// parse an 'if' expression ('if' token already eaten) // parse an 'if' expression ('if' token already eaten)
pub fn parse_if_expr(&mut self) -> @Expr { pub fn parse_if_expr(&mut self) -> Gc<Expr> {
let lo = self.last_span.lo; let lo = self.last_span.lo;
let cond = self.parse_expr(); let cond = self.parse_expr();
let thn = self.parse_block(); let thn = self.parse_block();
let mut els: Option<@Expr> = None; let mut els: Option<Gc<Expr>> = None;
let mut hi = thn.span.hi; let mut hi = thn.span.hi;
if self.eat_keyword(keywords::Else) { if self.eat_keyword(keywords::Else) {
let elexpr = self.parse_else_expr(); let elexpr = self.parse_else_expr();
@ -2488,7 +2494,7 @@ impl<'a> Parser<'a> {
} }
// `|args| { ... }` or `{ ...}` like in `do` expressions // `|args| { ... }` or `{ ...}` like in `do` expressions
pub fn parse_lambda_block_expr(&mut self) -> @Expr { pub fn parse_lambda_block_expr(&mut self) -> Gc<Expr> {
self.parse_lambda_expr_( self.parse_lambda_expr_(
|p| { |p| {
match p.token { match p.token {
@ -2517,7 +2523,7 @@ impl<'a> Parser<'a> {
} }
// `|args| expr` // `|args| expr`
pub fn parse_lambda_expr(&mut self) -> @Expr { pub fn parse_lambda_expr(&mut self) -> Gc<Expr> {
self.parse_lambda_expr_(|p| p.parse_fn_block_decl(), self.parse_lambda_expr_(|p| p.parse_fn_block_decl(),
|p| p.parse_expr()) |p| p.parse_expr())
} }
@ -2527,8 +2533,8 @@ impl<'a> Parser<'a> {
// and in parsing a block expr as e.g. in for... // and in parsing a block expr as e.g. in for...
pub fn parse_lambda_expr_(&mut self, pub fn parse_lambda_expr_(&mut self,
parse_decl: |&mut Parser| -> P<FnDecl>, parse_decl: |&mut Parser| -> P<FnDecl>,
parse_body: |&mut Parser| -> @Expr) parse_body: |&mut Parser| -> Gc<Expr>)
-> @Expr { -> Gc<Expr> {
let lo = self.span.lo; let lo = self.span.lo;
let decl = parse_decl(self); let decl = parse_decl(self);
let body = parse_body(self); let body = parse_body(self);
@ -2544,7 +2550,7 @@ impl<'a> Parser<'a> {
return self.mk_expr(lo, body.span.hi, ExprFnBlock(decl, fakeblock)); return self.mk_expr(lo, body.span.hi, ExprFnBlock(decl, fakeblock));
} }
pub fn parse_else_expr(&mut self) -> @Expr { pub fn parse_else_expr(&mut self) -> Gc<Expr> {
if self.eat_keyword(keywords::If) { if self.eat_keyword(keywords::If) {
return self.parse_if_expr(); return self.parse_if_expr();
} else { } else {
@ -2554,7 +2560,7 @@ impl<'a> Parser<'a> {
} }
// parse a 'for' .. 'in' expression ('for' token already eaten) // parse a 'for' .. 'in' expression ('for' token already eaten)
pub fn parse_for_expr(&mut self, opt_ident: Option<ast::Ident>) -> @Expr { pub fn parse_for_expr(&mut self, opt_ident: Option<ast::Ident>) -> Gc<Expr> {
// Parse: `for <src_pat> in <src_expr> <src_loop_block>` // Parse: `for <src_pat> in <src_expr> <src_loop_block>`
let lo = self.last_span.lo; let lo = self.last_span.lo;
@ -2567,7 +2573,7 @@ impl<'a> Parser<'a> {
self.mk_expr(lo, hi, ExprForLoop(pat, expr, loop_block, opt_ident)) self.mk_expr(lo, hi, ExprForLoop(pat, expr, loop_block, opt_ident))
} }
pub fn parse_while_expr(&mut self) -> @Expr { pub fn parse_while_expr(&mut self) -> Gc<Expr> {
let lo = self.last_span.lo; let lo = self.last_span.lo;
let cond = self.parse_expr(); let cond = self.parse_expr();
let body = self.parse_block(); let body = self.parse_block();
@ -2575,7 +2581,7 @@ impl<'a> Parser<'a> {
return self.mk_expr(lo, hi, ExprWhile(cond, body)); return self.mk_expr(lo, hi, ExprWhile(cond, body));
} }
pub fn parse_loop_expr(&mut self, opt_ident: Option<ast::Ident>) -> @Expr { pub fn parse_loop_expr(&mut self, opt_ident: Option<ast::Ident>) -> Gc<Expr> {
let lo = self.last_span.lo; let lo = self.last_span.lo;
let body = self.parse_block(); let body = self.parse_block();
let hi = body.span.hi; let hi = body.span.hi;
@ -2590,7 +2596,7 @@ impl<'a> Parser<'a> {
|| self.look_ahead(1, |t| *t == token::DOTDOT)) || self.look_ahead(1, |t| *t == token::DOTDOT))
} }
fn parse_match_expr(&mut self) -> @Expr { fn parse_match_expr(&mut self) -> Gc<Expr> {
let lo = self.last_span.lo; let lo = self.last_span.lo;
let discriminant = self.parse_expr(); let discriminant = self.parse_expr();
self.commit_expr_expecting(discriminant, token::LBRACE); self.commit_expr_expecting(discriminant, token::LBRACE);
@ -2628,12 +2634,12 @@ impl<'a> Parser<'a> {
} }
// parse an expression // parse an expression
pub fn parse_expr(&mut self) -> @Expr { pub fn parse_expr(&mut self) -> Gc<Expr> {
return self.parse_expr_res(UNRESTRICTED); return self.parse_expr_res(UNRESTRICTED);
} }
// parse an expression, subject to the given restriction // parse an expression, subject to the given restriction
fn parse_expr_res(&mut self, r: restriction) -> @Expr { fn parse_expr_res(&mut self, r: restriction) -> Gc<Expr> {
let old = self.restriction; let old = self.restriction;
self.restriction = r; self.restriction = r;
let e = self.parse_assign_expr(); let e = self.parse_assign_expr();
@ -2642,7 +2648,7 @@ impl<'a> Parser<'a> {
} }
// parse the RHS of a local variable declaration (e.g. '= 14;') // parse the RHS of a local variable declaration (e.g. '= 14;')
fn parse_initializer(&mut self) -> Option<@Expr> { fn parse_initializer(&mut self) -> Option<Gc<Expr>> {
if self.token == token::EQ { if self.token == token::EQ {
self.bump(); self.bump();
Some(self.parse_expr()) Some(self.parse_expr())
@ -2652,7 +2658,7 @@ impl<'a> Parser<'a> {
} }
// parse patterns, separated by '|' s // parse patterns, separated by '|' s
fn parse_pats(&mut self) -> Vec<@Pat> { fn parse_pats(&mut self) -> Vec<Gc<Pat>> {
let mut pats = Vec::new(); let mut pats = Vec::new();
loop { loop {
pats.push(self.parse_pat()); pats.push(self.parse_pat());
@ -2663,7 +2669,7 @@ impl<'a> Parser<'a> {
fn parse_pat_vec_elements( fn parse_pat_vec_elements(
&mut self, &mut self,
) -> (Vec<@Pat> , Option<@Pat>, Vec<@Pat> ) { ) -> (Vec<Gc<Pat>> , Option<Gc<Pat>>, Vec<Gc<Pat>> ) {
let mut before = Vec::new(); let mut before = Vec::new();
let mut slice = None; let mut slice = None;
let mut after = Vec::new(); let mut after = Vec::new();
@ -2685,7 +2691,7 @@ impl<'a> Parser<'a> {
if is_slice { if is_slice {
if self.token == token::COMMA || self.token == token::RBRACKET { if self.token == token::COMMA || self.token == token::RBRACKET {
slice = Some(@ast::Pat { slice = Some(box(GC) ast::Pat {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: PatWildMulti, node: PatWildMulti,
span: self.span, span: self.span,
@ -2764,7 +2770,7 @@ impl<'a> Parser<'a> {
} else { } else {
let fieldpath = ast_util::ident_to_path(self.last_span, let fieldpath = ast_util::ident_to_path(self.last_span,
fieldname); fieldname);
@ast::Pat { box(GC) ast::Pat {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: PatIdent(bind_type, fieldpath, None), node: PatIdent(bind_type, fieldpath, None),
span: self.last_span span: self.last_span
@ -2776,7 +2782,7 @@ impl<'a> Parser<'a> {
} }
// parse a pattern. // parse a pattern.
pub fn parse_pat(&mut self) -> @Pat { pub fn parse_pat(&mut self) -> Gc<Pat> {
maybe_whole!(self, NtPat); maybe_whole!(self, NtPat);
let lo = self.span.lo; let lo = self.span.lo;
@ -2788,7 +2794,7 @@ impl<'a> Parser<'a> {
self.bump(); self.bump();
pat = PatWild; pat = PatWild;
hi = self.last_span.hi; hi = self.last_span.hi;
return @ast::Pat { return box(GC) ast::Pat {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: pat, node: pat,
span: mk_sp(lo, hi) span: mk_sp(lo, hi)
@ -2801,7 +2807,7 @@ impl<'a> Parser<'a> {
pat = PatBox(sub); pat = PatBox(sub);
hi = self.last_span.hi; hi = self.last_span.hi;
self.obsolete(self.last_span, ObsoleteOwnedPattern); self.obsolete(self.last_span, ObsoleteOwnedPattern);
return @ast::Pat { return box(GC) ast::Pat {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: pat, node: pat,
span: mk_sp(lo, hi) span: mk_sp(lo, hi)
@ -2814,7 +2820,7 @@ impl<'a> Parser<'a> {
let sub = self.parse_pat(); let sub = self.parse_pat();
pat = PatRegion(sub); pat = PatRegion(sub);
hi = self.last_span.hi; hi = self.last_span.hi;
return @ast::Pat { return box(GC) ast::Pat {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: pat, node: pat,
span: mk_sp(lo, hi) span: mk_sp(lo, hi)
@ -2826,7 +2832,7 @@ impl<'a> Parser<'a> {
if self.token == token::RPAREN { if self.token == token::RPAREN {
hi = self.span.hi; hi = self.span.hi;
self.bump(); self.bump();
let lit = @codemap::Spanned { let lit = box(GC) codemap::Spanned {
node: LitNil, node: LitNil,
span: mk_sp(lo, hi)}; span: mk_sp(lo, hi)};
let expr = self.mk_expr(lo, hi, ExprLit(lit)); let expr = self.mk_expr(lo, hi, ExprLit(lit));
@ -2845,7 +2851,7 @@ impl<'a> Parser<'a> {
pat = PatTup(fields); pat = PatTup(fields);
} }
hi = self.last_span.hi; hi = self.last_span.hi;
return @ast::Pat { return box(GC) ast::Pat {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: pat, node: pat,
span: mk_sp(lo, hi) span: mk_sp(lo, hi)
@ -2860,7 +2866,7 @@ impl<'a> Parser<'a> {
self.expect(&token::RBRACKET); self.expect(&token::RBRACKET);
pat = ast::PatVec(before, slice, after); pat = ast::PatVec(before, slice, after);
hi = self.last_span.hi; hi = self.last_span.hi;
return @ast::Pat { return box(GC) ast::Pat {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: pat, node: pat,
span: mk_sp(lo, hi) span: mk_sp(lo, hi)
@ -2904,7 +2910,7 @@ impl<'a> Parser<'a> {
let sub = self.parse_pat(); let sub = self.parse_pat();
pat = PatBox(sub); pat = PatBox(sub);
hi = self.last_span.hi; hi = self.last_span.hi;
return @ast::Pat { return box(GC) ast::Pat {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: pat, node: pat,
span: mk_sp(lo, hi) span: mk_sp(lo, hi)
@ -2960,7 +2966,7 @@ impl<'a> Parser<'a> {
pat = PatStruct(enum_path, fields, etc); pat = PatStruct(enum_path, fields, etc);
} }
_ => { _ => {
let mut args: Vec<@Pat> = Vec::new(); let mut args: Vec<Gc<Pat>> = Vec::new();
match self.token { match self.token {
token::LPAREN => { token::LPAREN => {
let is_dotdot = self.look_ahead(1, |t| { let is_dotdot = self.look_ahead(1, |t| {
@ -3003,7 +3009,7 @@ impl<'a> Parser<'a> {
} }
} }
hi = self.last_span.hi; hi = self.last_span.hi;
@ast::Pat { box(GC) ast::Pat {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: pat, node: pat,
span: mk_sp(lo, hi), span: mk_sp(lo, hi),
@ -3044,7 +3050,7 @@ impl<'a> Parser<'a> {
} }
// parse a local variable declaration // parse a local variable declaration
fn parse_local(&mut self) -> @Local { fn parse_local(&mut self) -> Gc<Local> {
let lo = self.span.lo; let lo = self.span.lo;
let pat = self.parse_pat(); let pat = self.parse_pat();
@ -3055,7 +3061,7 @@ impl<'a> Parser<'a> {
}); });
if self.eat(&token::COLON) { ty = self.parse_ty(false); } if self.eat(&token::COLON) { ty = self.parse_ty(false); }
let init = self.parse_initializer(); let init = self.parse_initializer();
@ast::Local { box(GC) ast::Local {
ty: ty, ty: ty,
pat: pat, pat: pat,
init: init, init: init,
@ -3066,10 +3072,10 @@ impl<'a> Parser<'a> {
} }
// parse a "let" stmt // parse a "let" stmt
fn parse_let(&mut self) -> @Decl { fn parse_let(&mut self) -> Gc<Decl> {
let lo = self.span.lo; let lo = self.span.lo;
let local = self.parse_local(); let local = self.parse_local();
return @spanned(lo, self.last_span.hi, DeclLocal(local)); box(GC) spanned(lo, self.last_span.hi, DeclLocal(local))
} }
// parse a structure field // parse a structure field
@ -3092,7 +3098,7 @@ impl<'a> Parser<'a> {
// parse a statement. may include decl. // parse a statement. may include decl.
// precondition: any attributes are parsed already // precondition: any attributes are parsed already
pub fn parse_stmt(&mut self, item_attrs: Vec<Attribute> ) -> @Stmt { pub fn parse_stmt(&mut self, item_attrs: Vec<Attribute>) -> Gc<Stmt> {
maybe_whole!(self, NtStmt); maybe_whole!(self, NtStmt);
fn check_expected_item(p: &mut Parser, found_attrs: bool) { fn check_expected_item(p: &mut Parser, found_attrs: bool) {
@ -3107,7 +3113,7 @@ impl<'a> Parser<'a> {
check_expected_item(self, !item_attrs.is_empty()); check_expected_item(self, !item_attrs.is_empty());
self.expect_keyword(keywords::Let); self.expect_keyword(keywords::Let);
let decl = self.parse_let(); let decl = self.parse_let();
return @spanned(lo, decl.span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID)); return box(GC) spanned(lo, decl.span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID));
} else if is_ident(&self.token) } else if is_ident(&self.token)
&& !token::is_any_keyword(&self.token) && !token::is_any_keyword(&self.token)
&& self.look_ahead(1, |t| *t == token::NOT) { && self.look_ahead(1, |t| *t == token::NOT) {
@ -3166,12 +3172,12 @@ impl<'a> Parser<'a> {
let hi = self.span.hi; let hi = self.span.hi;
if id == token::special_idents::invalid { if id == token::special_idents::invalid {
return @spanned(lo, hi, StmtMac( return box(GC) spanned(lo, hi, StmtMac(
spanned(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT)), false)); spanned(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT)), false));
} else { } else {
// if it has a special ident, it's definitely an item // if it has a special ident, it's definitely an item
return @spanned(lo, hi, StmtDecl( return box(GC) spanned(lo, hi, StmtDecl(
@spanned(lo, hi, DeclItem( box(GC) spanned(lo, hi, DeclItem(
self.mk_item( self.mk_item(
lo, hi, id /*id is good here*/, lo, hi, id /*id is good here*/,
ItemMac(spanned(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT))), ItemMac(spanned(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT))),
@ -3184,8 +3190,8 @@ impl<'a> Parser<'a> {
match self.parse_item_or_view_item(item_attrs, false) { match self.parse_item_or_view_item(item_attrs, false) {
IoviItem(i) => { IoviItem(i) => {
let hi = i.span.hi; let hi = i.span.hi;
let decl = @spanned(lo, hi, DeclItem(i)); let decl = box(GC) spanned(lo, hi, DeclItem(i));
return @spanned(lo, hi, StmtDecl(decl, ast::DUMMY_NODE_ID)); return box(GC) spanned(lo, hi, StmtDecl(decl, ast::DUMMY_NODE_ID));
} }
IoviViewItem(vi) => { IoviViewItem(vi) => {
self.span_fatal(vi.span, self.span_fatal(vi.span,
@ -3201,12 +3207,12 @@ impl<'a> Parser<'a> {
// Remainder are line-expr stmts. // Remainder are line-expr stmts.
let e = self.parse_expr_res(RESTRICT_STMT_EXPR); let e = self.parse_expr_res(RESTRICT_STMT_EXPR);
return @spanned(lo, e.span.hi, StmtExpr(e, ast::DUMMY_NODE_ID)); return box(GC) spanned(lo, e.span.hi, StmtExpr(e, ast::DUMMY_NODE_ID));
} }
} }
// is this expression a successfully-parsed statement? // is this expression a successfully-parsed statement?
fn expr_is_complete(&mut self, e: @Expr) -> bool { fn expr_is_complete(&mut self, e: Gc<Expr>) -> bool {
return self.restriction == RESTRICT_STMT_EXPR && return self.restriction == RESTRICT_STMT_EXPR &&
!classify::expr_requires_semi_to_be_stmt(e); !classify::expr_requires_semi_to_be_stmt(e);
} }
@ -3258,8 +3264,8 @@ impl<'a> Parser<'a> {
false, false); false, false);
for item in items.iter() { for item in items.iter() {
let decl = @spanned(item.span.lo, item.span.hi, DeclItem(*item)); let decl = box(GC) spanned(item.span.lo, item.span.hi, DeclItem(*item));
stmts.push(@spanned(item.span.lo, item.span.hi, stmts.push(box(GC) spanned(item.span.lo, item.span.hi,
StmtDecl(decl, ast::DUMMY_NODE_ID))); StmtDecl(decl, ast::DUMMY_NODE_ID)));
} }
@ -3286,7 +3292,7 @@ impl<'a> Parser<'a> {
match stmt.node { match stmt.node {
StmtExpr(e, stmt_id) => { StmtExpr(e, stmt_id) => {
// expression without semicolon // expression without semicolon
if classify::stmt_ends_with_semi(stmt) { if classify::stmt_ends_with_semi(&*stmt) {
// Just check for errors and recover; do not eat semicolon yet. // Just check for errors and recover; do not eat semicolon yet.
self.commit_stmt(stmt, &[], &[token::SEMI, token::RBRACE]); self.commit_stmt(stmt, &[], &[token::SEMI, token::RBRACE]);
} }
@ -3299,7 +3305,7 @@ impl<'a> Parser<'a> {
hi: self.last_span.hi, hi: self.last_span.hi,
expn_info: stmt.span.expn_info, expn_info: stmt.span.expn_info,
}; };
stmts.push(@codemap::Spanned { stmts.push(box(GC) codemap::Spanned {
node: StmtSemi(e, stmt_id), node: StmtSemi(e, stmt_id),
span: span_with_semi, span: span_with_semi,
}); });
@ -3317,7 +3323,7 @@ impl<'a> Parser<'a> {
match self.token { match self.token {
token::SEMI => { token::SEMI => {
self.bump(); self.bump();
stmts.push(@codemap::Spanned { stmts.push(box(GC) codemap::Spanned {
node: StmtMac((*m).clone(), true), node: StmtMac((*m).clone(), true),
span: stmt.span, span: stmt.span,
}); });
@ -3336,9 +3342,9 @@ impl<'a> Parser<'a> {
} }
} }
_ => { // all other kinds of statements: _ => { // all other kinds of statements:
stmts.push(stmt); stmts.push(stmt.clone());
if classify::stmt_ends_with_semi(stmt) { if classify::stmt_ends_with_semi(&*stmt) {
self.commit_stmt_expecting(stmt, token::SEMI); self.commit_stmt_expecting(stmt, token::SEMI);
} }
} }
@ -3827,8 +3833,8 @@ impl<'a> Parser<'a> {
fn mk_item(&mut self, lo: BytePos, hi: BytePos, ident: Ident, fn mk_item(&mut self, lo: BytePos, hi: BytePos, ident: Ident,
node: Item_, vis: Visibility, node: Item_, vis: Visibility,
attrs: Vec<Attribute> ) -> @Item { attrs: Vec<Attribute>) -> Gc<Item> {
@Item { box(GC) Item {
ident: ident, ident: ident,
attrs: attrs, attrs: attrs,
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
@ -3847,7 +3853,8 @@ impl<'a> Parser<'a> {
} }
// parse a method in a trait impl, starting with `attrs` attributes. // parse a method in a trait impl, starting with `attrs` attributes.
fn parse_method(&mut self, already_parsed_attrs: Option<Vec<Attribute> >) -> @Method { fn parse_method(&mut self,
already_parsed_attrs: Option<Vec<Attribute>>) -> Gc<Method> {
let next_attrs = self.parse_outer_attributes(); let next_attrs = self.parse_outer_attributes();
let attrs = match already_parsed_attrs { let attrs = match already_parsed_attrs {
Some(mut a) => { a.push_all_move(next_attrs); a } Some(mut a) => { a.push_all_move(next_attrs); a }
@ -3867,7 +3874,7 @@ impl<'a> Parser<'a> {
let (inner_attrs, body) = self.parse_inner_attrs_and_block(); let (inner_attrs, body) = self.parse_inner_attrs_and_block();
let hi = body.span.hi; let hi = body.span.hi;
let attrs = attrs.append(inner_attrs.as_slice()); let attrs = attrs.append(inner_attrs.as_slice());
@ast::Method { box(GC) ast::Method {
ident: ident, ident: ident,
attrs: attrs, attrs: attrs,
generics: generics, generics: generics,
@ -3950,7 +3957,7 @@ impl<'a> Parser<'a> {
method_attrs = None; method_attrs = None;
} }
let ident = ast_util::impl_pretty_name(&opt_trait, ty); let ident = ast_util::impl_pretty_name(&opt_trait, &*ty);
(ident, ItemImpl(generics, opt_trait, ty, meths), Some(inner_attrs)) (ident, ItemImpl(generics, opt_trait, ty, meths), Some(inner_attrs))
} }
@ -4041,7 +4048,7 @@ impl<'a> Parser<'a> {
let _ = ast::DUMMY_NODE_ID; // FIXME: Workaround for crazy bug. let _ = ast::DUMMY_NODE_ID; // FIXME: Workaround for crazy bug.
let new_id = ast::DUMMY_NODE_ID; let new_id = ast::DUMMY_NODE_ID;
(class_name, (class_name,
ItemStruct(@ast::StructDef { ItemStruct(box(GC) ast::StructDef {
fields: fields, fields: fields,
ctor_id: if is_tuple_like { Some(new_id) } else { None }, ctor_id: if is_tuple_like { Some(new_id) } else { None },
super_struct: super_struct, super_struct: super_struct,
@ -4121,7 +4128,7 @@ impl<'a> Parser<'a> {
items: starting_items, items: starting_items,
.. ..
} = self.parse_items_and_view_items(first_item_attrs, true, true); } = self.parse_items_and_view_items(first_item_attrs, true, true);
let mut items: Vec<@Item> = starting_items; let mut items: Vec<Gc<Item>> = starting_items;
let attrs_remaining_len = attrs_remaining.len(); let attrs_remaining_len = attrs_remaining.len();
// don't think this other loop is even necessary.... // don't think this other loop is even necessary....
@ -4322,7 +4329,7 @@ impl<'a> Parser<'a> {
// parse a function declaration from a foreign module // parse a function declaration from a foreign module
fn parse_item_foreign_fn(&mut self, vis: ast::Visibility, fn parse_item_foreign_fn(&mut self, vis: ast::Visibility,
attrs: Vec<Attribute> ) -> @ForeignItem { attrs: Vec<Attribute>) -> Gc<ForeignItem> {
let lo = self.span.lo; let lo = self.span.lo;
self.expect_keyword(keywords::Fn); self.expect_keyword(keywords::Fn);
@ -4330,7 +4337,7 @@ impl<'a> Parser<'a> {
let decl = self.parse_fn_decl(true); let decl = self.parse_fn_decl(true);
let hi = self.span.hi; let hi = self.span.hi;
self.expect(&token::SEMI); self.expect(&token::SEMI);
@ast::ForeignItem { ident: ident, box(GC) ast::ForeignItem { ident: ident,
attrs: attrs, attrs: attrs,
node: ForeignItemFn(decl, generics), node: ForeignItemFn(decl, generics),
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
@ -4340,7 +4347,7 @@ impl<'a> Parser<'a> {
// parse a static item from a foreign module // parse a static item from a foreign module
fn parse_item_foreign_static(&mut self, vis: ast::Visibility, fn parse_item_foreign_static(&mut self, vis: ast::Visibility,
attrs: Vec<Attribute> ) -> @ForeignItem { attrs: Vec<Attribute> ) -> Gc<ForeignItem> {
let lo = self.span.lo; let lo = self.span.lo;
self.expect_keyword(keywords::Static); self.expect_keyword(keywords::Static);
@ -4351,7 +4358,7 @@ impl<'a> Parser<'a> {
let ty = self.parse_ty(false); let ty = self.parse_ty(false);
let hi = self.span.hi; let hi = self.span.hi;
self.expect(&token::SEMI); self.expect(&token::SEMI);
@ast::ForeignItem { box(GC) ast::ForeignItem {
ident: ident, ident: ident,
attrs: attrs, attrs: attrs,
node: ForeignItemStatic(ty, mutbl), node: ForeignItemStatic(ty, mutbl),
@ -4483,14 +4490,14 @@ impl<'a> Parser<'a> {
// parse a structure-like enum variant definition // parse a structure-like enum variant definition
// this should probably be renamed or refactored... // this should probably be renamed or refactored...
fn parse_struct_def(&mut self) -> @StructDef { fn parse_struct_def(&mut self) -> Gc<StructDef> {
let mut fields: Vec<StructField> = Vec::new(); let mut fields: Vec<StructField> = Vec::new();
while self.token != token::RBRACE { while self.token != token::RBRACE {
fields.push(self.parse_struct_decl_field()); fields.push(self.parse_struct_decl_field());
} }
self.bump(); self.bump();
return @ast::StructDef { return box(GC) ast::StructDef {
fields: fields, fields: fields,
ctor_id: None, ctor_id: None,
super_struct: None, super_struct: None,
@ -4617,7 +4624,7 @@ impl<'a> Parser<'a> {
INTERPOLATED(token::NtItem(item)) => { INTERPOLATED(token::NtItem(item)) => {
self.bump(); self.bump();
let new_attrs = attrs.append(item.attrs.as_slice()); let new_attrs = attrs.append(item.attrs.as_slice());
return IoviItem(@Item { return IoviItem(box(GC) Item {
attrs: new_attrs, attrs: new_attrs,
..(*item).clone() ..(*item).clone()
}); });
@ -4892,7 +4899,7 @@ impl<'a> Parser<'a> {
return IoviNone(attrs); return IoviNone(attrs);
} }
pub fn parse_item(&mut self, attrs: Vec<Attribute> ) -> Option<@Item> { pub fn parse_item(&mut self, attrs: Vec<Attribute> ) -> Option<Gc<Item>> {
match self.parse_item_or_view_item(attrs, true) { match self.parse_item_or_view_item(attrs, true) {
IoviNone(_) => None, IoviNone(_) => None,
IoviViewItem(_) => IoviViewItem(_) =>
@ -4914,7 +4921,7 @@ impl<'a> Parser<'a> {
// | MOD? non_global_path MOD_SEP LBRACE ident_seq RBRACE // | MOD? non_global_path MOD_SEP LBRACE ident_seq RBRACE
// | MOD? non_global_path MOD_SEP STAR // | MOD? non_global_path MOD_SEP STAR
// | MOD? non_global_path // | MOD? non_global_path
fn parse_view_path(&mut self) -> @ViewPath { fn parse_view_path(&mut self) -> Gc<ViewPath> {
let lo = self.span.lo; let lo = self.span.lo;
if self.token == token::LBRACE { if self.token == token::LBRACE {
@ -4928,7 +4935,7 @@ impl<'a> Parser<'a> {
global: false, global: false,
segments: Vec::new() segments: Vec::new()
}; };
return @spanned(lo, self.span.hi, return box(GC) spanned(lo, self.span.hi,
ViewPathList(path, idents, ast::DUMMY_NODE_ID)); ViewPathList(path, idents, ast::DUMMY_NODE_ID));
} }
@ -4956,7 +4963,7 @@ impl<'a> Parser<'a> {
} }
}).collect() }).collect()
}; };
return @spanned(lo, self.span.hi, return box(GC) spanned(lo, self.span.hi,
ViewPathSimple(first_ident, path, ViewPathSimple(first_ident, path,
ast::DUMMY_NODE_ID)); ast::DUMMY_NODE_ID));
} }
@ -4991,7 +4998,7 @@ impl<'a> Parser<'a> {
} }
}).collect() }).collect()
}; };
return @spanned(lo, self.span.hi, return box(GC) spanned(lo, self.span.hi,
ViewPathList(path, idents, ast::DUMMY_NODE_ID)); ViewPathList(path, idents, ast::DUMMY_NODE_ID));
} }
@ -5009,7 +5016,7 @@ impl<'a> Parser<'a> {
} }
}).collect() }).collect()
}; };
return @spanned(lo, self.span.hi, return box(GC) spanned(lo, self.span.hi,
ViewPathGlob(path, ast::DUMMY_NODE_ID)); ViewPathGlob(path, ast::DUMMY_NODE_ID));
} }
@ -5031,7 +5038,7 @@ impl<'a> Parser<'a> {
} }
}).collect() }).collect()
}; };
return @spanned(lo, return box(GC) spanned(lo,
self.last_span.hi, self.last_span.hi,
ViewPathSimple(last, path, ast::DUMMY_NODE_ID)); ViewPathSimple(last, path, ast::DUMMY_NODE_ID));
} }

View file

@ -18,10 +18,10 @@ use util::interner;
use serialize::{Decodable, Decoder, Encodable, Encoder}; use serialize::{Decodable, Decoder, Encodable, Encoder};
use std::fmt; use std::fmt;
use std::path::BytesContainer; use std::gc::Gc;
use std::mem; use std::mem;
use std::path::BytesContainer;
use std::rc::Rc; use std::rc::Rc;
use std::string::String;
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[deriving(Clone, Encodable, Decodable, PartialEq, Eq, Hash, Show)] #[deriving(Clone, Encodable, Decodable, PartialEq, Eq, Hash, Show)]
@ -105,16 +105,16 @@ pub enum Token {
#[deriving(Clone, Encodable, Decodable, PartialEq, Eq, Hash)] #[deriving(Clone, Encodable, Decodable, PartialEq, Eq, Hash)]
/// For interpolation during macro expansion. /// For interpolation during macro expansion.
pub enum Nonterminal { pub enum Nonterminal {
NtItem(@ast::Item), NtItem(Gc<ast::Item>),
NtBlock(P<ast::Block>), NtBlock(P<ast::Block>),
NtStmt(@ast::Stmt), NtStmt(Gc<ast::Stmt>),
NtPat( @ast::Pat), NtPat( Gc<ast::Pat>),
NtExpr(@ast::Expr), NtExpr(Gc<ast::Expr>),
NtTy( P<ast::Ty>), NtTy( P<ast::Ty>),
NtIdent(Box<ast::Ident>, bool), NtIdent(Box<ast::Ident>, bool),
NtMeta(@ast::MetaItem), // stuff inside brackets for attributes NtMeta(Gc<ast::MetaItem>), // stuff inside brackets for attributes
NtPath(Box<ast::Path>), NtPath(Box<ast::Path>),
NtTT( @ast::TokenTree), // needs @ed to break a circularity NtTT( Gc<ast::TokenTree>), // needs @ed to break a circularity
NtMatchers(Vec<ast::Matcher> ) NtMatchers(Vec<ast::Matcher> )
} }
@ -241,8 +241,8 @@ pub fn to_str(t: &Token) -> String {
EOF => "<eof>".to_string(), EOF => "<eof>".to_string(),
INTERPOLATED(ref nt) => { INTERPOLATED(ref nt) => {
match nt { match nt {
&NtExpr(e) => ::print::pprust::expr_to_str(e), &NtExpr(ref e) => ::print::pprust::expr_to_str(&**e),
&NtMeta(e) => ::print::pprust::meta_item_to_str(e), &NtMeta(ref e) => ::print::pprust::meta_item_to_str(&**e),
_ => { _ => {
let mut s = "an interpolated ".to_string(); let mut s = "an interpolated ".to_string();
match *nt { match *nt {

File diff suppressed because it is too large Load diff

View file

@ -15,6 +15,8 @@ use codemap::Span;
use parse; use parse;
use owned_slice::OwnedSlice; use owned_slice::OwnedSlice;
use std::gc::Gc;
// Context-passing AST walker. Each overridden visit method has full control // Context-passing AST walker. Each overridden visit method has full control
// over what happens with its node, it can do its own traversal of the node's // over what happens with its node, it can do its own traversal of the node's
// children (potentially passing in different contexts to each), call // children (potentially passing in different contexts to each), call
@ -135,9 +137,9 @@ pub fn walk_inlined_item<E: Clone, V: Visitor<E>>(visitor: &mut V,
item: &ast::InlinedItem, item: &ast::InlinedItem,
env: E) { env: E) {
match *item { match *item {
IIItem(i) => visitor.visit_item(i, env), IIItem(i) => visitor.visit_item(&*i, env),
IIForeign(i) => visitor.visit_foreign_item(i, env), IIForeign(i) => visitor.visit_foreign_item(&*i, env),
IIMethod(_, _, m) => walk_method_helper(visitor, m, env), IIMethod(_, _, m) => walk_method_helper(visitor, &*m, env),
} }
} }
@ -155,7 +157,7 @@ pub fn walk_mod<E: Clone, V: Visitor<E>>(visitor: &mut V, module: &Mod, env: E)
} }
for item in module.items.iter() { for item in module.items.iter() {
visitor.visit_item(*item, env.clone()) visitor.visit_item(&**item, env.clone())
} }
} }
@ -188,11 +190,11 @@ pub fn walk_view_item<E: Clone, V: Visitor<E>>(visitor: &mut V, vi: &ViewItem, e
} }
pub fn walk_local<E: Clone, V: Visitor<E>>(visitor: &mut V, local: &Local, env: E) { pub fn walk_local<E: Clone, V: Visitor<E>>(visitor: &mut V, local: &Local, env: E) {
visitor.visit_pat(local.pat, env.clone()); visitor.visit_pat(&*local.pat, env.clone());
visitor.visit_ty(local.ty, env.clone()); visitor.visit_ty(&*local.ty, env.clone());
match local.init { match local.init {
None => {} None => {}
Some(initializer) => visitor.visit_expr(initializer, env), Some(initializer) => visitor.visit_expr(&*initializer, env),
} }
} }
@ -219,13 +221,13 @@ pub fn walk_item<E: Clone, V: Visitor<E>>(visitor: &mut V, item: &Item, env: E)
visitor.visit_ident(item.span, item.ident, env.clone()); visitor.visit_ident(item.span, item.ident, env.clone());
match item.node { match item.node {
ItemStatic(typ, _, expr) => { ItemStatic(typ, _, expr) => {
visitor.visit_ty(typ, env.clone()); visitor.visit_ty(&*typ, env.clone());
visitor.visit_expr(expr, env.clone()); visitor.visit_expr(&*expr, env);
} }
ItemFn(declaration, fn_style, abi, ref generics, body) => { ItemFn(declaration, fn_style, abi, ref generics, body) => {
visitor.visit_fn(&FkItemFn(item.ident, generics, fn_style, abi), visitor.visit_fn(&FkItemFn(item.ident, generics, fn_style, abi),
declaration, &*declaration,
body, &*body,
item.span, item.span,
item.id, item.id,
env.clone()) env.clone())
@ -238,12 +240,12 @@ pub fn walk_item<E: Clone, V: Visitor<E>>(visitor: &mut V, item: &Item, env: E)
visitor.visit_view_item(view_item, env.clone()) visitor.visit_view_item(view_item, env.clone())
} }
for foreign_item in foreign_module.items.iter() { for foreign_item in foreign_module.items.iter() {
visitor.visit_foreign_item(*foreign_item, env.clone()) visitor.visit_foreign_item(&**foreign_item, env.clone())
} }
} }
ItemTy(typ, ref type_parameters) => { ItemTy(typ, ref type_parameters) => {
visitor.visit_ty(typ, env.clone()); visitor.visit_ty(&*typ, env.clone());
visitor.visit_generics(type_parameters, env.clone()) visitor.visit_generics(type_parameters, env)
} }
ItemEnum(ref enum_definition, ref type_parameters) => { ItemEnum(ref enum_definition, ref type_parameters) => {
visitor.visit_generics(type_parameters, env.clone()); visitor.visit_generics(type_parameters, env.clone());
@ -259,14 +261,14 @@ pub fn walk_item<E: Clone, V: Visitor<E>>(visitor: &mut V, item: &Item, env: E)
trait_reference, env.clone()), trait_reference, env.clone()),
None => () None => ()
} }
visitor.visit_ty(typ, env.clone()); visitor.visit_ty(&*typ, env.clone());
for method in methods.iter() { for method in methods.iter() {
walk_method_helper(visitor, *method, env.clone()) walk_method_helper(visitor, &**method, env.clone())
} }
} }
ItemStruct(struct_definition, ref generics) => { ItemStruct(ref struct_definition, ref generics) => {
visitor.visit_generics(generics, env.clone()); visitor.visit_generics(generics, env.clone());
visitor.visit_struct_def(struct_definition, visitor.visit_struct_def(&**struct_definition,
item.ident, item.ident,
generics, generics,
item.id, item.id,
@ -295,7 +297,7 @@ pub fn walk_enum_def<E: Clone, V:Visitor<E>>(visitor: &mut V,
generics: &Generics, generics: &Generics,
env: E) { env: E) {
for &variant in enum_definition.variants.iter() { for &variant in enum_definition.variants.iter() {
visitor.visit_variant(variant, generics, env.clone()); visitor.visit_variant(&*variant, generics, env.clone());
} }
} }
@ -308,11 +310,11 @@ pub fn walk_variant<E: Clone, V: Visitor<E>>(visitor: &mut V,
match variant.node.kind { match variant.node.kind {
TupleVariantKind(ref variant_arguments) => { TupleVariantKind(ref variant_arguments) => {
for variant_argument in variant_arguments.iter() { for variant_argument in variant_arguments.iter() {
visitor.visit_ty(variant_argument.ty, env.clone()) visitor.visit_ty(&*variant_argument.ty, env.clone())
} }
} }
StructVariantKind(struct_definition) => { StructVariantKind(ref struct_definition) => {
visitor.visit_struct_def(struct_definition, visitor.visit_struct_def(&**struct_definition,
variant.node.name, variant.node.name,
generics, generics,
variant.node.id, variant.node.id,
@ -320,7 +322,7 @@ pub fn walk_variant<E: Clone, V: Visitor<E>>(visitor: &mut V,
} }
} }
match variant.node.disr_expr { match variant.node.disr_expr {
Some(expr) => visitor.visit_expr(expr, env.clone()), Some(ref expr) => visitor.visit_expr(&**expr, env.clone()),
None => () None => ()
} }
for attr in variant.node.attrs.iter() { for attr in variant.node.attrs.iter() {
@ -335,25 +337,25 @@ pub fn skip_ty<E, V: Visitor<E>>(_: &mut V, _: &Ty, _: E) {
pub fn walk_ty<E: Clone, V: Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) { pub fn walk_ty<E: Clone, V: Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
match typ.node { match typ.node {
TyUniq(ty) | TyVec(ty) | TyBox(ty) => { TyUniq(ty) | TyVec(ty) | TyBox(ty) => {
visitor.visit_ty(ty, env) visitor.visit_ty(&*ty, env)
} }
TyPtr(ref mutable_type) => { TyPtr(ref mutable_type) => {
visitor.visit_ty(mutable_type.ty, env) visitor.visit_ty(&*mutable_type.ty, env)
} }
TyRptr(ref lifetime, ref mutable_type) => { TyRptr(ref lifetime, ref mutable_type) => {
visitor.visit_opt_lifetime_ref(typ.span, lifetime, env.clone()); visitor.visit_opt_lifetime_ref(typ.span, lifetime, env.clone());
visitor.visit_ty(mutable_type.ty, env) visitor.visit_ty(&*mutable_type.ty, env)
} }
TyTup(ref tuple_element_types) => { TyTup(ref tuple_element_types) => {
for &tuple_element_type in tuple_element_types.iter() { for &tuple_element_type in tuple_element_types.iter() {
visitor.visit_ty(tuple_element_type, env.clone()) visitor.visit_ty(&*tuple_element_type, env.clone())
} }
} }
TyClosure(ref function_declaration, ref region) => { TyClosure(ref function_declaration, ref region) => {
for argument in function_declaration.decl.inputs.iter() { for argument in function_declaration.decl.inputs.iter() {
visitor.visit_ty(argument.ty, env.clone()) visitor.visit_ty(&*argument.ty, env.clone())
} }
visitor.visit_ty(function_declaration.decl.output, env.clone()); visitor.visit_ty(&*function_declaration.decl.output, env.clone());
for bounds in function_declaration.bounds.iter() { for bounds in function_declaration.bounds.iter() {
walk_ty_param_bounds(visitor, bounds, env.clone()) walk_ty_param_bounds(visitor, bounds, env.clone())
} }
@ -366,9 +368,9 @@ pub fn walk_ty<E: Clone, V: Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
} }
TyProc(ref function_declaration) => { TyProc(ref function_declaration) => {
for argument in function_declaration.decl.inputs.iter() { for argument in function_declaration.decl.inputs.iter() {
visitor.visit_ty(argument.ty, env.clone()) visitor.visit_ty(&*argument.ty, env.clone())
} }
visitor.visit_ty(function_declaration.decl.output, env.clone()); visitor.visit_ty(&*function_declaration.decl.output, env.clone());
for bounds in function_declaration.bounds.iter() { for bounds in function_declaration.bounds.iter() {
walk_ty_param_bounds(visitor, bounds, env.clone()) walk_ty_param_bounds(visitor, bounds, env.clone())
} }
@ -377,9 +379,9 @@ pub fn walk_ty<E: Clone, V: Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
} }
TyBareFn(ref function_declaration) => { TyBareFn(ref function_declaration) => {
for argument in function_declaration.decl.inputs.iter() { for argument in function_declaration.decl.inputs.iter() {
visitor.visit_ty(argument.ty, env.clone()) visitor.visit_ty(&*argument.ty, env.clone())
} }
visitor.visit_ty(function_declaration.decl.output, env.clone()); visitor.visit_ty(&*function_declaration.decl.output, env.clone());
walk_lifetime_decls(visitor, &function_declaration.lifetimes, walk_lifetime_decls(visitor, &function_declaration.lifetimes,
env.clone()); env.clone());
} }
@ -395,12 +397,12 @@ pub fn walk_ty<E: Clone, V: Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
walk_ty_param_bounds(visitor, bounds, env.clone()) walk_ty_param_bounds(visitor, bounds, env.clone())
} }
} }
TyFixedLengthVec(ty, expression) => { TyFixedLengthVec(ref ty, ref expression) => {
visitor.visit_ty(ty, env.clone()); visitor.visit_ty(&**ty, env.clone());
visitor.visit_expr(expression, env) visitor.visit_expr(&**expression, env)
} }
TyTypeof(expression) => { TyTypeof(ref expression) => {
visitor.visit_expr(expression, env) visitor.visit_expr(&**expression, env)
} }
TyNil | TyBot | TyInfer => {} TyNil | TyBot | TyInfer => {}
} }
@ -418,8 +420,8 @@ pub fn walk_path<E: Clone, V: Visitor<E>>(visitor: &mut V, path: &Path, env: E)
for segment in path.segments.iter() { for segment in path.segments.iter() {
visitor.visit_ident(path.span, segment.identifier, env.clone()); visitor.visit_ident(path.span, segment.identifier, env.clone());
for &typ in segment.types.iter() { for typ in segment.types.iter() {
visitor.visit_ty(typ, env.clone()); visitor.visit_ty(&**typ, env.clone());
} }
for lifetime in segment.lifetimes.iter() { for lifetime in segment.lifetimes.iter() {
visitor.visit_lifetime_ref(lifetime, env.clone()); visitor.visit_lifetime_ref(lifetime, env.clone());
@ -433,47 +435,47 @@ pub fn walk_pat<E: Clone, V: Visitor<E>>(visitor: &mut V, pattern: &Pat, env: E)
visitor.visit_path(path, pattern.id, env.clone()); visitor.visit_path(path, pattern.id, env.clone());
for children in children.iter() { for children in children.iter() {
for child in children.iter() { for child in children.iter() {
visitor.visit_pat(*child, env.clone()) visitor.visit_pat(&**child, env.clone())
} }
} }
} }
PatStruct(ref path, ref fields, _) => { PatStruct(ref path, ref fields, _) => {
visitor.visit_path(path, pattern.id, env.clone()); visitor.visit_path(path, pattern.id, env.clone());
for field in fields.iter() { for field in fields.iter() {
visitor.visit_pat(field.pat, env.clone()) visitor.visit_pat(&*field.pat, env.clone())
} }
} }
PatTup(ref tuple_elements) => { PatTup(ref tuple_elements) => {
for tuple_element in tuple_elements.iter() { for tuple_element in tuple_elements.iter() {
visitor.visit_pat(*tuple_element, env.clone()) visitor.visit_pat(&**tuple_element, env.clone())
} }
} }
PatBox(subpattern) | PatBox(ref subpattern) |
PatRegion(subpattern) => { PatRegion(ref subpattern) => {
visitor.visit_pat(subpattern, env) visitor.visit_pat(&**subpattern, env)
} }
PatIdent(_, ref path, ref optional_subpattern) => { PatIdent(_, ref path, ref optional_subpattern) => {
visitor.visit_path(path, pattern.id, env.clone()); visitor.visit_path(path, pattern.id, env.clone());
match *optional_subpattern { match *optional_subpattern {
None => {} None => {}
Some(subpattern) => visitor.visit_pat(subpattern, env), Some(ref subpattern) => visitor.visit_pat(&**subpattern, env),
} }
} }
PatLit(expression) => visitor.visit_expr(expression, env), PatLit(ref expression) => visitor.visit_expr(&**expression, env),
PatRange(lower_bound, upper_bound) => { PatRange(ref lower_bound, ref upper_bound) => {
visitor.visit_expr(lower_bound, env.clone()); visitor.visit_expr(&**lower_bound, env.clone());
visitor.visit_expr(upper_bound, env) visitor.visit_expr(&**upper_bound, env)
} }
PatWild | PatWildMulti => (), PatWild | PatWildMulti => (),
PatVec(ref prepattern, ref slice_pattern, ref postpatterns) => { PatVec(ref prepattern, ref slice_pattern, ref postpatterns) => {
for prepattern in prepattern.iter() { for prepattern in prepattern.iter() {
visitor.visit_pat(*prepattern, env.clone()) visitor.visit_pat(&**prepattern, env.clone())
} }
for slice_pattern in slice_pattern.iter() { for slice_pattern in slice_pattern.iter() {
visitor.visit_pat(*slice_pattern, env.clone()) visitor.visit_pat(&**slice_pattern, env.clone())
} }
for postpattern in postpatterns.iter() { for postpattern in postpatterns.iter() {
visitor.visit_pat(*postpattern, env.clone()) visitor.visit_pat(&**postpattern, env.clone())
} }
} }
PatMac(ref macro) => visitor.visit_mac(macro, env), PatMac(ref macro) => visitor.visit_mac(macro, env),
@ -486,8 +488,8 @@ pub fn walk_foreign_item<E: Clone, V: Visitor<E>>(visitor: &mut V,
visitor.visit_ident(foreign_item.span, foreign_item.ident, env.clone()); visitor.visit_ident(foreign_item.span, foreign_item.ident, env.clone());
match foreign_item.node { match foreign_item.node {
ForeignItemFn(function_declaration, ref generics) => { ForeignItemFn(ref function_declaration, ref generics) => {
walk_fn_decl(visitor, function_declaration, env.clone()); walk_fn_decl(visitor, &**function_declaration, env.clone());
visitor.visit_generics(generics, env.clone()) visitor.visit_generics(generics, env.clone())
} }
ForeignItemStatic(typ, _) => visitor.visit_ty(typ, env.clone()), ForeignItemStatic(typ, _) => visitor.visit_ty(typ, env.clone()),
@ -525,7 +527,7 @@ pub fn walk_generics<E: Clone, V: Visitor<E>>(visitor: &mut V,
for type_parameter in generics.ty_params.iter() { for type_parameter in generics.ty_params.iter() {
walk_ty_param_bounds(visitor, &type_parameter.bounds, env.clone()); walk_ty_param_bounds(visitor, &type_parameter.bounds, env.clone());
match type_parameter.default { match type_parameter.default {
Some(ty) => visitor.visit_ty(ty, env.clone()), Some(ref ty) => visitor.visit_ty(&**ty, env.clone()),
None => {} None => {}
} }
} }
@ -536,10 +538,10 @@ pub fn walk_fn_decl<E: Clone, V: Visitor<E>>(visitor: &mut V,
function_declaration: &FnDecl, function_declaration: &FnDecl,
env: E) { env: E) {
for argument in function_declaration.inputs.iter() { for argument in function_declaration.inputs.iter() {
visitor.visit_pat(argument.pat, env.clone()); visitor.visit_pat(&*argument.pat, env.clone());
visitor.visit_ty(argument.ty, env.clone()) visitor.visit_ty(&*argument.ty, env.clone())
} }
visitor.visit_ty(function_declaration.output, env) visitor.visit_ty(&*function_declaration.output, env)
} }
// Note: there is no visit_method() method in the visitor, instead override // Note: there is no visit_method() method in the visitor, instead override
@ -551,8 +553,8 @@ pub fn walk_method_helper<E: Clone, V: Visitor<E>>(visitor: &mut V,
env: E) { env: E) {
visitor.visit_ident(method.span, method.ident, env.clone()); visitor.visit_ident(method.span, method.ident, env.clone());
visitor.visit_fn(&FkMethod(method.ident, &method.generics, method), visitor.visit_fn(&FkMethod(method.ident, &method.generics, method),
method.decl, &*method.decl,
method.body, &*method.body,
method.span, method.span,
method.id, method.id,
env.clone()); env.clone());
@ -590,7 +592,7 @@ pub fn walk_ty_method<E: Clone, V: Visitor<E>>(visitor: &mut V,
visitor.visit_ident(method_type.span, method_type.ident, env.clone()); visitor.visit_ident(method_type.span, method_type.ident, env.clone());
visitor.visit_explicit_self(&method_type.explicit_self, env.clone()); visitor.visit_explicit_self(&method_type.explicit_self, env.clone());
for argument_type in method_type.decl.inputs.iter() { for argument_type in method_type.decl.inputs.iter() {
visitor.visit_ty(argument_type.ty, env.clone()) visitor.visit_ty(&*argument_type.ty, env.clone())
} }
visitor.visit_generics(&method_type.generics, env.clone()); visitor.visit_generics(&method_type.generics, env.clone());
visitor.visit_ty(method_type.decl.output, env.clone()); visitor.visit_ty(method_type.decl.output, env.clone());
@ -606,7 +608,7 @@ pub fn walk_trait_method<E: Clone, V: Visitor<E>>(visitor: &mut V,
Required(ref method_type) => { Required(ref method_type) => {
visitor.visit_ty_method(method_type, env) visitor.visit_ty_method(method_type, env)
} }
Provided(method) => walk_method_helper(visitor, method, env), Provided(ref method) => walk_method_helper(visitor, &**method, env),
} }
} }
@ -614,7 +616,7 @@ pub fn walk_struct_def<E: Clone, V: Visitor<E>>(visitor: &mut V,
struct_definition: &StructDef, struct_definition: &StructDef,
env: E) { env: E) {
match struct_definition.super_struct { match struct_definition.super_struct {
Some(t) => visitor.visit_ty(t, env.clone()), Some(ref t) => visitor.visit_ty(&**t, env.clone()),
None => {}, None => {},
} }
for field in struct_definition.fields.iter() { for field in struct_definition.fields.iter() {
@ -644,16 +646,16 @@ pub fn walk_block<E: Clone, V: Visitor<E>>(visitor: &mut V, block: &Block, env:
visitor.visit_view_item(view_item, env.clone()) visitor.visit_view_item(view_item, env.clone())
} }
for statement in block.stmts.iter() { for statement in block.stmts.iter() {
visitor.visit_stmt(*statement, env.clone()) visitor.visit_stmt(&**statement, env.clone())
} }
walk_expr_opt(visitor, block.expr, env) walk_expr_opt(visitor, block.expr, env)
} }
pub fn walk_stmt<E: Clone, V: Visitor<E>>(visitor: &mut V, statement: &Stmt, env: E) { pub fn walk_stmt<E: Clone, V: Visitor<E>>(visitor: &mut V, statement: &Stmt, env: E) {
match statement.node { match statement.node {
StmtDecl(declaration, _) => visitor.visit_decl(declaration, env), StmtDecl(ref declaration, _) => visitor.visit_decl(&**declaration, env),
StmtExpr(expression, _) | StmtSemi(expression, _) => { StmtExpr(ref expression, _) | StmtSemi(ref expression, _) => {
visitor.visit_expr(expression, env) visitor.visit_expr(&**expression, env)
} }
StmtMac(ref macro, _) => visitor.visit_mac(macro, env), StmtMac(ref macro, _) => visitor.visit_mac(macro, env),
} }
@ -661,25 +663,25 @@ pub fn walk_stmt<E: Clone, V: Visitor<E>>(visitor: &mut V, statement: &Stmt, env
pub fn walk_decl<E: Clone, V: Visitor<E>>(visitor: &mut V, declaration: &Decl, env: E) { pub fn walk_decl<E: Clone, V: Visitor<E>>(visitor: &mut V, declaration: &Decl, env: E) {
match declaration.node { match declaration.node {
DeclLocal(ref local) => visitor.visit_local(*local, env), DeclLocal(ref local) => visitor.visit_local(&**local, env),
DeclItem(item) => visitor.visit_item(item, env), DeclItem(ref item) => visitor.visit_item(&**item, env),
} }
} }
pub fn walk_expr_opt<E: Clone, V: Visitor<E>>(visitor: &mut V, pub fn walk_expr_opt<E: Clone, V: Visitor<E>>(visitor: &mut V,
optional_expression: Option<@Expr>, optional_expression: Option<Gc<Expr>>,
env: E) { env: E) {
match optional_expression { match optional_expression {
None => {} None => {}
Some(expression) => visitor.visit_expr(expression, env), Some(ref expression) => visitor.visit_expr(&**expression, env),
} }
} }
pub fn walk_exprs<E: Clone, V: Visitor<E>>(visitor: &mut V, pub fn walk_exprs<E: Clone, V: Visitor<E>>(visitor: &mut V,
expressions: &[@Expr], expressions: &[Gc<Expr>],
env: E) { env: E) {
for expression in expressions.iter() { for expression in expressions.iter() {
visitor.visit_expr(*expression, env.clone()) visitor.visit_expr(&**expression, env.clone())
} }
} }
@ -689,111 +691,111 @@ pub fn walk_mac<E, V: Visitor<E>>(_: &mut V, _: &Mac, _: E) {
pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, env: E) { pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, env: E) {
match expression.node { match expression.node {
ExprVstore(subexpression, _) => { ExprVstore(ref subexpression, _) => {
visitor.visit_expr(subexpression, env.clone()) visitor.visit_expr(&**subexpression, env.clone())
} }
ExprBox(place, subexpression) => { ExprBox(ref place, ref subexpression) => {
visitor.visit_expr(place, env.clone()); visitor.visit_expr(&**place, env.clone());
visitor.visit_expr(subexpression, env.clone()) visitor.visit_expr(&**subexpression, env.clone())
} }
ExprVec(ref subexpressions) => { ExprVec(ref subexpressions) => {
walk_exprs(visitor, subexpressions.as_slice(), env.clone()) walk_exprs(visitor, subexpressions.as_slice(), env.clone())
} }
ExprRepeat(element, count) => { ExprRepeat(ref element, ref count) => {
visitor.visit_expr(element, env.clone()); visitor.visit_expr(&**element, env.clone());
visitor.visit_expr(count, env.clone()) visitor.visit_expr(&**count, env.clone())
} }
ExprStruct(ref path, ref fields, optional_base) => { ExprStruct(ref path, ref fields, optional_base) => {
visitor.visit_path(path, expression.id, env.clone()); visitor.visit_path(path, expression.id, env.clone());
for field in fields.iter() { for field in fields.iter() {
visitor.visit_expr(field.expr, env.clone()) visitor.visit_expr(&*field.expr, env.clone())
} }
walk_expr_opt(visitor, optional_base, env.clone()) walk_expr_opt(visitor, optional_base, env.clone())
} }
ExprTup(ref subexpressions) => { ExprTup(ref subexpressions) => {
for subexpression in subexpressions.iter() { for subexpression in subexpressions.iter() {
visitor.visit_expr(*subexpression, env.clone()) visitor.visit_expr(&**subexpression, env.clone())
} }
} }
ExprCall(callee_expression, ref arguments) => { ExprCall(ref callee_expression, ref arguments) => {
for argument in arguments.iter() { for argument in arguments.iter() {
visitor.visit_expr(*argument, env.clone()) visitor.visit_expr(&**argument, env.clone())
} }
visitor.visit_expr(callee_expression, env.clone()) visitor.visit_expr(&**callee_expression, env.clone())
} }
ExprMethodCall(_, ref types, ref arguments) => { ExprMethodCall(_, ref types, ref arguments) => {
walk_exprs(visitor, arguments.as_slice(), env.clone()); walk_exprs(visitor, arguments.as_slice(), env.clone());
for &typ in types.iter() { for typ in types.iter() {
visitor.visit_ty(typ, env.clone()) visitor.visit_ty(&**typ, env.clone())
} }
} }
ExprBinary(_, left_expression, right_expression) => { ExprBinary(_, ref left_expression, ref right_expression) => {
visitor.visit_expr(left_expression, env.clone()); visitor.visit_expr(&**left_expression, env.clone());
visitor.visit_expr(right_expression, env.clone()) visitor.visit_expr(&**right_expression, env.clone())
} }
ExprAddrOf(_, subexpression) | ExprUnary(_, subexpression) => { ExprAddrOf(_, ref subexpression) | ExprUnary(_, ref subexpression) => {
visitor.visit_expr(subexpression, env.clone()) visitor.visit_expr(&**subexpression, env.clone())
} }
ExprLit(_) => {} ExprLit(_) => {}
ExprCast(subexpression, typ) => { ExprCast(ref subexpression, ref typ) => {
visitor.visit_expr(subexpression, env.clone()); visitor.visit_expr(&**subexpression, env.clone());
visitor.visit_ty(typ, env.clone()) visitor.visit_ty(&**typ, env.clone())
} }
ExprIf(head_expression, if_block, optional_else) => { ExprIf(ref head_expression, ref if_block, optional_else) => {
visitor.visit_expr(head_expression, env.clone()); visitor.visit_expr(&**head_expression, env.clone());
visitor.visit_block(if_block, env.clone()); visitor.visit_block(&**if_block, env.clone());
walk_expr_opt(visitor, optional_else, env.clone()) walk_expr_opt(visitor, optional_else, env.clone())
} }
ExprWhile(subexpression, block) => { ExprWhile(ref subexpression, ref block) => {
visitor.visit_expr(subexpression, env.clone()); visitor.visit_expr(&**subexpression, env.clone());
visitor.visit_block(block, env.clone()) visitor.visit_block(&**block, env.clone())
} }
ExprForLoop(pattern, subexpression, block, _) => { ExprForLoop(ref pattern, ref subexpression, ref block, _) => {
visitor.visit_pat(pattern, env.clone()); visitor.visit_pat(&**pattern, env.clone());
visitor.visit_expr(subexpression, env.clone()); visitor.visit_expr(&**subexpression, env.clone());
visitor.visit_block(block, env.clone()) visitor.visit_block(&**block, env.clone())
} }
ExprLoop(block, _) => visitor.visit_block(block, env.clone()), ExprLoop(ref block, _) => visitor.visit_block(&**block, env.clone()),
ExprMatch(subexpression, ref arms) => { ExprMatch(ref subexpression, ref arms) => {
visitor.visit_expr(subexpression, env.clone()); visitor.visit_expr(&**subexpression, env.clone());
for arm in arms.iter() { for arm in arms.iter() {
visitor.visit_arm(arm, env.clone()) visitor.visit_arm(arm, env.clone())
} }
} }
ExprFnBlock(function_declaration, body) => { ExprFnBlock(ref function_declaration, ref body) => {
visitor.visit_fn(&FkFnBlock, visitor.visit_fn(&FkFnBlock,
function_declaration, &**function_declaration,
body, &**body,
expression.span, expression.span,
expression.id, expression.id,
env.clone()) env.clone())
} }
ExprProc(function_declaration, body) => { ExprProc(ref function_declaration, ref body) => {
visitor.visit_fn(&FkFnBlock, visitor.visit_fn(&FkFnBlock,
function_declaration, &**function_declaration,
body, &**body,
expression.span, expression.span,
expression.id, expression.id,
env.clone()) env.clone())
} }
ExprBlock(block) => visitor.visit_block(block, env.clone()), ExprBlock(ref block) => visitor.visit_block(&**block, env.clone()),
ExprAssign(left_hand_expression, right_hand_expression) => { ExprAssign(ref left_hand_expression, ref right_hand_expression) => {
visitor.visit_expr(right_hand_expression, env.clone()); visitor.visit_expr(&**right_hand_expression, env.clone());
visitor.visit_expr(left_hand_expression, env.clone()) visitor.visit_expr(&**left_hand_expression, env.clone())
} }
ExprAssignOp(_, left_expression, right_expression) => { ExprAssignOp(_, ref left_expression, ref right_expression) => {
visitor.visit_expr(right_expression, env.clone()); visitor.visit_expr(&**right_expression, env.clone());
visitor.visit_expr(left_expression, env.clone()) visitor.visit_expr(&**left_expression, env.clone())
} }
ExprField(subexpression, _, ref types) => { ExprField(ref subexpression, _, ref types) => {
visitor.visit_expr(subexpression, env.clone()); visitor.visit_expr(&**subexpression, env.clone());
for &typ in types.iter() { for typ in types.iter() {
visitor.visit_ty(typ, env.clone()) visitor.visit_ty(&**typ, env.clone())
} }
} }
ExprIndex(main_expression, index_expression) => { ExprIndex(ref main_expression, ref index_expression) => {
visitor.visit_expr(main_expression, env.clone()); visitor.visit_expr(&**main_expression, env.clone());
visitor.visit_expr(index_expression, env.clone()) visitor.visit_expr(&**index_expression, env.clone())
} }
ExprPath(ref path) => { ExprPath(ref path) => {
visitor.visit_path(path, expression.id, env.clone()) visitor.visit_path(path, expression.id, env.clone())
@ -803,15 +805,15 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en
walk_expr_opt(visitor, optional_expression, env.clone()) walk_expr_opt(visitor, optional_expression, env.clone())
} }
ExprMac(ref macro) => visitor.visit_mac(macro, env.clone()), ExprMac(ref macro) => visitor.visit_mac(macro, env.clone()),
ExprParen(subexpression) => { ExprParen(ref subexpression) => {
visitor.visit_expr(subexpression, env.clone()) visitor.visit_expr(&**subexpression, env.clone())
} }
ExprInlineAsm(ref assembler) => { ExprInlineAsm(ref assembler) => {
for &(_, input) in assembler.inputs.iter() { for &(_, ref input) in assembler.inputs.iter() {
visitor.visit_expr(input, env.clone()) visitor.visit_expr(&**input, env.clone())
} }
for &(_, output) in assembler.outputs.iter() { for &(_, ref output) in assembler.outputs.iter() {
visitor.visit_expr(output, env.clone()) visitor.visit_expr(&**output, env.clone())
} }
} }
} }
@ -821,7 +823,7 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en
pub fn walk_arm<E: Clone, V: Visitor<E>>(visitor: &mut V, arm: &Arm, env: E) { pub fn walk_arm<E: Clone, V: Visitor<E>>(visitor: &mut V, arm: &Arm, env: E) {
for pattern in arm.pats.iter() { for pattern in arm.pats.iter() {
visitor.visit_pat(*pattern, env.clone()) visitor.visit_pat(&**pattern, env.clone())
} }
walk_expr_opt(visitor, arm.guard, env.clone()); walk_expr_opt(visitor, arm.guard, env.clone());
visitor.visit_expr(arm.body, env.clone()); visitor.visit_expr(arm.body, env.clone());