Extended syntax::{fold, ast_map} to include lifetimes.

Part of this required added an override of `fold_type_method` in the
Folder for Ctx impl; it follows the same pattern as `fold_method`.

Also, as a drive-by fix, I moved all of the calls to `folder.new_id`
in syntax::fold's no-op default traversal to really be the first
statement in each function.

  * This is to uphold the invariant that `folder.new_id` is always
    called first (an unfortunate requirement of the current `ast_map`
    code), an invariant that we seemingly were breaking in e.g. the
    previous `noop_fold_block`.

  * Now it should be easier to see when adding new code that this
    invariant must be upheld.

  * (note that the breakage in `noop_fold_block` may not have mattered
    so much previously, since the only thing that blocks can bind are
    lifetimes, which I am only adding support for now.)
This commit is contained in:
Felix S. Klock II
2014-04-11 11:28:43 +02:00
parent 0e30f07abc
commit b25fe99331
3 changed files with 86 additions and 33 deletions

View File

@@ -272,6 +272,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
} }
// Ugh -- but this ensures any new variants won't be forgotten // Ugh -- but this ensures any new variants won't be forgotten
ast_map::NodeLifetime(..) |
ast_map::NodeExpr(..) | ast_map::NodeExpr(..) |
ast_map::NodeStmt(..) | ast_map::NodeStmt(..) |
ast_map::NodeArg(..) | ast_map::NodeArg(..) |

View File

@@ -107,6 +107,8 @@ pub enum Node {
/// NodeStructCtor represents a tuple struct. /// NodeStructCtor represents a tuple struct.
NodeStructCtor(@StructDef), NodeStructCtor(@StructDef),
NodeLifetime(@Lifetime),
} }
// The odd layout is to bring down the total size. // The odd layout is to bring down the total size.
@@ -127,6 +129,7 @@ enum MapEntry {
EntryLocal(NodeId, @Pat), EntryLocal(NodeId, @Pat),
EntryBlock(NodeId, P<Block>), EntryBlock(NodeId, P<Block>),
EntryStructCtor(NodeId, @StructDef), EntryStructCtor(NodeId, @StructDef),
EntryLifetime(NodeId, @Lifetime),
// Roots for node trees. // Roots for node trees.
RootCrate, RootCrate,
@@ -153,6 +156,7 @@ impl MapEntry {
EntryLocal(id, _) => id, EntryLocal(id, _) => id,
EntryBlock(id, _) => id, EntryBlock(id, _) => id,
EntryStructCtor(id, _) => id, EntryStructCtor(id, _) => id,
EntryLifetime(id, _) => id,
_ => return None _ => return None
}) })
} }
@@ -170,6 +174,7 @@ impl MapEntry {
EntryLocal(_, p) => NodeLocal(p), EntryLocal(_, p) => NodeLocal(p),
EntryBlock(_, p) => NodeBlock(p), EntryBlock(_, p) => NodeBlock(p),
EntryStructCtor(_, p) => NodeStructCtor(p), EntryStructCtor(_, p) => NodeStructCtor(p),
EntryLifetime(_, p) => NodeLifetime(p),
_ => return None _ => return None
}) })
} }
@@ -213,6 +218,8 @@ impl Map {
self.find_entry(id).and_then(|x| x.to_node()) self.find_entry(id).and_then(|x| x.to_node())
} }
/// Retrieve the parent NodeId for `id`, or `id` itself if no
/// parent is registered in this map.
pub fn get_parent(&self, id: NodeId) -> NodeId { pub fn get_parent(&self, id: NodeId) -> NodeId {
self.find_entry(id).and_then(|x| x.parent()).unwrap_or(id) self.find_entry(id).and_then(|x| x.parent()).unwrap_or(id)
} }
@@ -500,6 +507,15 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
SmallVector::one(stmt) SmallVector::one(stmt)
} }
fn fold_type_method(&mut self, m: &TypeMethod) -> TypeMethod {
let parent = self.parent;
self.parent = DUMMY_NODE_ID;
let m = fold::noop_fold_type_method(m, self);
assert_eq!(self.parent, m.id);
self.parent = parent;
m
}
fn fold_method(&mut self, m: @Method) -> @Method { fn fold_method(&mut self, m: @Method) -> @Method {
let parent = self.parent; let parent = self.parent;
self.parent = DUMMY_NODE_ID; self.parent = DUMMY_NODE_ID;
@@ -522,6 +538,12 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
self.insert(block.id, EntryBlock(self.parent, block)); self.insert(block.id, EntryBlock(self.parent, block));
block block
} }
fn fold_lifetime(&mut self, lifetime: &Lifetime) -> Lifetime {
let lifetime = fold::noop_fold_lifetime(lifetime, self);
self.insert(lifetime.id, EntryLifetime(self.parent, @lifetime));
lifetime
}
} }
pub fn map_crate<F: FoldOps>(krate: Crate, fold_ops: F) -> (Crate, Map) { pub fn map_crate<F: FoldOps>(krate: Crate, fold_ops: F) -> (Crate, Map) {
@@ -658,6 +680,9 @@ fn node_id_to_str(map: &Map, id: NodeId) -> ~str {
Some(NodeStructCtor(_)) => { Some(NodeStructCtor(_)) => {
format!("struct_ctor {} (id={})", map.path_to_str(id), id) format!("struct_ctor {} (id={})", map.path_to_str(id), id)
} }
Some(NodeLifetime(ref l)) => {
format!("lifetime {} (id={})", pprust::lifetime_to_str(*l), id)
}
None => { None => {
format!("unknown node (id={})", id) format!("unknown node (id={})", id)
} }

View File

@@ -32,14 +32,17 @@ pub trait Folder {
view_paths.iter().map(|view_path| { view_paths.iter().map(|view_path| {
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);
ViewPathSimple(ident.clone(), ViewPathSimple(ident.clone(),
self.fold_path(path), self.fold_path(path),
self.new_id(node_id)) id)
} }
ViewPathGlob(ref path, node_id) => { ViewPathGlob(ref path, node_id) => {
ViewPathGlob(self.fold_path(path), self.new_id(node_id)) let id = self.new_id(node_id);
ViewPathGlob(self.fold_path(path), id)
} }
ViewPathList(ref path, ref path_list_idents, node_id) => { ViewPathList(ref path, ref path_list_idents, node_id) => {
let id = self.new_id(node_id);
ViewPathList(self.fold_path(path), ViewPathList(self.fold_path(path),
path_list_idents.iter().map(|path_list_ident| { path_list_idents.iter().map(|path_list_ident| {
let id = self.new_id(path_list_ident.node let id = self.new_id(path_list_ident.node
@@ -55,7 +58,7 @@ pub trait Folder {
path_list_ident.span) path_list_ident.span)
} }
}).collect(), }).collect(),
self.new_id(node_id)) id)
} }
}; };
@Spanned { @Spanned {
@@ -78,10 +81,11 @@ pub trait Folder {
} }
fn fold_struct_field(&mut self, sf: &StructField) -> StructField { fn fold_struct_field(&mut self, sf: &StructField) -> StructField {
let id = self.new_id(sf.node.id);
Spanned { Spanned {
node: ast::StructField_ { node: ast::StructField_ {
kind: sf.node.kind, kind: sf.node.kind,
id: self.new_id(sf.node.id), id: id,
ty: self.fold_ty(sf.node.ty), ty: self.fold_ty(sf.node.ty),
attrs: sf.node.attrs.iter().map(|e| fold_attribute_(*e, self)).collect() attrs: sf.node.attrs.iter().map(|e| fold_attribute_(*e, self)).collect()
}, },
@@ -146,6 +150,7 @@ pub trait Folder {
} }
fn fold_ty(&mut self, t: P<Ty>) -> P<Ty> { fn fold_ty(&mut self, t: P<Ty>) -> P<Ty> {
let id = self.new_id(t.id);
let node = match t.node { let node = match t.node {
TyNil | TyBot | TyInfer => t.node.clone(), TyNil | TyBot | TyInfer => t.node.clone(),
TyBox(ty) => TyBox(self.fold_ty(ty)), TyBox(ty) => TyBox(self.fold_ty(ty)),
@@ -161,7 +166,7 @@ pub trait Folder {
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| fold_lifetime(l, self)).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) => {
@@ -170,12 +175,12 @@ pub trait Folder {
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| fold_lifetime(l, self)).collect(), lifetimes: f.lifetimes.iter().map(|l| self.fold_lifetime(l)).collect(),
}) })
} }
TyBareFn(ref f) => { TyBareFn(ref f) => {
TyBareFn(@BareFnTy { TyBareFn(@BareFnTy {
lifetimes: f.lifetimes.iter().map(|l| fold_lifetime(l, self)).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)
@@ -183,9 +188,10 @@ pub trait Folder {
} }
TyTup(ref tys) => TyTup(tys.iter().map(|&ty| self.fold_ty(ty)).collect()), TyTup(ref tys) => TyTup(tys.iter().map(|&ty| self.fold_ty(ty)).collect()),
TyPath(ref path, ref bounds, id) => { TyPath(ref path, ref bounds, id) => {
let id = self.new_id(id);
TyPath(self.fold_path(path), TyPath(self.fold_path(path),
fold_opt_bounds(bounds, self), fold_opt_bounds(bounds, self),
self.new_id(id)) id)
} }
TyFixedLengthVec(ty, e) => { TyFixedLengthVec(ty, e) => {
TyFixedLengthVec(self.fold_ty(ty), self.fold_expr(e)) TyFixedLengthVec(self.fold_ty(ty), self.fold_expr(e))
@@ -193,7 +199,7 @@ pub trait Folder {
TyTypeof(expr) => TyTypeof(self.fold_expr(expr)), TyTypeof(expr) => TyTypeof(self.fold_expr(expr)),
}; };
P(Ty { P(Ty {
id: self.new_id(t.id), id: id,
span: self.new_span(t.span), span: self.new_span(t.span),
node: node, node: node,
}) })
@@ -218,6 +224,7 @@ pub trait Folder {
} }
fn fold_variant(&mut self, v: &Variant) -> P<Variant> { fn fold_variant(&mut self, v: &Variant) -> P<Variant> {
let id = self.new_id(v.node.id);
let kind; let kind;
match v.node.kind { match v.node.kind {
TupleVariantKind(ref variant_args) => { TupleVariantKind(ref variant_args) => {
@@ -243,7 +250,7 @@ pub trait Folder {
name: v.node.name, name: v.node.name,
attrs: attrs, attrs: attrs,
kind: kind, kind: kind,
id: self.new_id(v.node.id), id: id,
disr_expr: de, disr_expr: de,
vis: v.node.vis, vis: v.node.vis,
}; };
@@ -263,15 +270,16 @@ pub trait Folder {
global: p.global, global: p.global,
segments: p.segments.iter().map(|segment| ast::PathSegment { segments: p.segments.iter().map(|segment| ast::PathSegment {
identifier: self.fold_ident(segment.identifier), identifier: self.fold_ident(segment.identifier),
lifetimes: segment.lifetimes.iter().map(|l| fold_lifetime(l, self)).collect(), lifetimes: segment.lifetimes.iter().map(|l| self.fold_lifetime(l)).collect(),
types: segment.types.iter().map(|&typ| self.fold_ty(typ)).collect(), types: segment.types.iter().map(|&typ| self.fold_ty(typ)).collect(),
}).collect() }).collect()
} }
} }
fn fold_local(&mut self, l: @Local) -> @Local { fn fold_local(&mut self, l: @Local) -> @Local {
let id = self.new_id(l.id); // Needs to be first, for ast_map.
@Local { @Local {
id: self.new_id(l.id), // Needs to be first, for ast_map. 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),
init: l.init.map(|e| self.fold_expr(e)), init: l.init.map(|e| self.fold_expr(e)),
@@ -319,6 +327,10 @@ pub trait Folder {
} }
} }
} }
fn fold_lifetime(&mut self, l: &Lifetime) -> Lifetime {
noop_fold_lifetime(l, self)
}
} }
/* 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*/
@@ -353,8 +365,9 @@ fn fold_attribute_<T: Folder>(at: Attribute, fld: &mut T) -> Attribute {
//used in noop_fold_foreign_item and noop_fold_fn_decl //used in noop_fold_foreign_item and noop_fold_fn_decl
fn fold_arg_<T: Folder>(a: &Arg, fld: &mut T) -> Arg { fn fold_arg_<T: Folder>(a: &Arg, fld: &mut T) -> Arg {
let id = fld.new_id(a.id); // Needs to be first, for ast_map.
Arg { Arg {
id: fld.new_id(a.id), // Needs to be first, for ast_map. id: id,
ty: fld.fold_ty(a.ty), ty: fld.fold_ty(a.ty),
pat: fld.fold_pat(a.pat), pat: fld.fold_pat(a.pat),
} }
@@ -425,9 +438,10 @@ fn fold_ty_param_bound<T: Folder>(tpb: &TyParamBound, fld: &mut T)
} }
pub fn fold_ty_param<T: Folder>(tp: &TyParam, fld: &mut T) -> TyParam { pub fn fold_ty_param<T: Folder>(tp: &TyParam, fld: &mut T) -> TyParam {
let id = fld.new_id(tp.id);
TyParam { TyParam {
ident: tp.ident, ident: tp.ident,
id: fld.new_id(tp.id), id: id,
bounds: tp.bounds.map(|x| fold_ty_param_bound(x, fld)), bounds: tp.bounds.map(|x| fold_ty_param_bound(x, fld)),
default: tp.default.map(|x| fld.fold_ty(x)) default: tp.default.map(|x| fld.fold_ty(x))
} }
@@ -438,9 +452,10 @@ pub fn fold_ty_params<T: Folder>(tps: &OwnedSlice<TyParam>, fld: &mut T)
tps.map(|tp| fold_ty_param(tp, fld)) tps.map(|tp| fold_ty_param(tp, fld))
} }
pub fn fold_lifetime<T: Folder>(l: &Lifetime, fld: &mut T) -> Lifetime { pub fn noop_fold_lifetime<T: Folder>(l: &Lifetime, fld: &mut T) -> Lifetime {
let id = fld.new_id(l.id);
Lifetime { Lifetime {
id: fld.new_id(l.id), id: id,
span: fld.new_span(l.span), span: fld.new_span(l.span),
name: l.name name: l.name
} }
@@ -448,12 +463,12 @@ pub fn fold_lifetime<T: Folder>(l: &Lifetime, fld: &mut T) -> Lifetime {
pub fn fold_lifetimes<T: Folder>(lts: &Vec<Lifetime>, fld: &mut T) pub fn fold_lifetimes<T: Folder>(lts: &Vec<Lifetime>, fld: &mut T)
-> Vec<Lifetime> { -> Vec<Lifetime> {
lts.iter().map(|l| fold_lifetime(l, fld)).collect() lts.iter().map(|l| fld.fold_lifetime(l)).collect()
} }
pub fn fold_opt_lifetime<T: Folder>(o_lt: &Option<Lifetime>, fld: &mut T) pub fn fold_opt_lifetime<T: Folder>(o_lt: &Option<Lifetime>, fld: &mut T)
-> Option<Lifetime> { -> Option<Lifetime> {
o_lt.as_ref().map(|lt| fold_lifetime(lt, fld)) o_lt.as_ref().map(|lt| fld.fold_lifetime(lt))
} }
pub fn fold_generics<T: Folder>(generics: &Generics, fld: &mut T) -> Generics { pub fn fold_generics<T: Folder>(generics: &Generics, fld: &mut T) -> Generics {
@@ -469,17 +484,19 @@ fn fold_struct_def<T: Folder>(struct_def: @StructDef, fld: &mut T) -> @StructDef
} }
fn fold_trait_ref<T: Folder>(p: &TraitRef, fld: &mut T) -> TraitRef { fn fold_trait_ref<T: Folder>(p: &TraitRef, fld: &mut T) -> TraitRef {
let id = fld.new_id(p.ref_id);
ast::TraitRef { ast::TraitRef {
path: fld.fold_path(&p.path), path: fld.fold_path(&p.path),
ref_id: fld.new_id(p.ref_id), ref_id: id,
} }
} }
fn fold_struct_field<T: Folder>(f: &StructField, fld: &mut T) -> StructField { fn fold_struct_field<T: Folder>(f: &StructField, fld: &mut T) -> StructField {
let id = fld.new_id(f.node.id);
Spanned { Spanned {
node: ast::StructField_ { node: ast::StructField_ {
kind: f.node.kind, kind: f.node.kind,
id: fld.new_id(f.node.id), id: id,
ty: fld.fold_ty(f.node.ty), ty: fld.fold_ty(f.node.ty),
attrs: f.node.attrs.iter().map(|a| fold_attribute_(*a, fld)).collect(), attrs: f.node.attrs.iter().map(|a| fold_attribute_(*a, fld)).collect(),
}, },
@@ -512,9 +529,10 @@ fn fold_opt_bounds<T: Folder>(b: &Option<OwnedSlice<TyParamBound>>, folder: &mut
} }
fn fold_variant_arg_<T: Folder>(va: &VariantArg, folder: &mut T) -> VariantArg { fn fold_variant_arg_<T: Folder>(va: &VariantArg, folder: &mut T) -> VariantArg {
let id = folder.new_id(va.id);
ast::VariantArg { ast::VariantArg {
ty: folder.fold_ty(va.ty), ty: folder.fold_ty(va.ty),
id: folder.new_id(va.id) id: id,
} }
} }
@@ -539,10 +557,11 @@ 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 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: folder.new_id(b.id), // Needs to be first, for ast_map. id: id,
view_items: view_items, view_items: view_items,
stmts: stmts, stmts: stmts,
expr: b.expr.map(|x| folder.fold_expr(x)), expr: b.expr.map(|x| folder.fold_expr(x)),
@@ -606,8 +625,9 @@ pub fn noop_fold_item_underscore<T: Folder>(i: &Item_, folder: &mut T) -> Item_
} }
pub fn noop_fold_type_method<T: Folder>(m: &TypeMethod, fld: &mut T) -> TypeMethod { pub fn noop_fold_type_method<T: Folder>(m: &TypeMethod, fld: &mut T) -> TypeMethod {
let id = fld.new_id(m.id); // Needs to be first, for ast_map.
TypeMethod { TypeMethod {
id: fld.new_id(m.id), // Needs to be first, for ast_map. id: id,
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,
@@ -658,8 +678,9 @@ 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) -> @ForeignItem {
let id = folder.new_id(ni.id); // Needs to be first, for ast_map.
@ForeignItem { @ForeignItem {
id: folder.new_id(ni.id), // Needs to be first, for ast_map. 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(),
node: match ni.node { node: match ni.node {
@@ -681,8 +702,9 @@ 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) -> @Method {
let id = folder.new_id(m.id); // Needs to be first, for ast_map.
@Method { @Method {
id: folder.new_id(m.id), // Needs to be first, for ast_map. 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),
@@ -696,6 +718,7 @@ pub fn noop_fold_method<T: Folder>(m: &Method, folder: &mut T) -> @Method {
} }
pub fn noop_fold_pat<T: Folder>(p: @Pat, folder: &mut T) -> @Pat { pub fn noop_fold_pat<T: Folder>(p: @Pat, folder: &mut T) -> @Pat {
let id = folder.new_id(p.id);
let node = match p.node { let node = match p.node {
PatWild => PatWild, PatWild => PatWild,
PatWildMulti => PatWildMulti, PatWildMulti => PatWildMulti,
@@ -733,13 +756,14 @@ pub fn noop_fold_pat<T: Folder>(p: @Pat, folder: &mut T) -> @Pat {
}; };
@Pat { @Pat {
id: folder.new_id(p.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: @Expr, folder: &mut T) -> @Expr {
let id = folder.new_id(e.id);
let node = match e.node { let node = match e.node {
ExprVstore(e, v) => { ExprVstore(e, v) => {
ExprVstore(folder.fold_expr(e), v) ExprVstore(folder.fold_expr(e), v)
@@ -849,7 +873,7 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
}; };
@Expr { @Expr {
id: folder.new_id(e.id), id: id,
node: node, node: node,
span: folder.new_span(e.span), span: folder.new_span(e.span),
} }
@@ -857,16 +881,19 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
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<@Stmt> {
let nodes = match s.node { let nodes = match s.node {
StmtDecl(d, nid) => { StmtDecl(d, id) => {
let id = folder.new_id(id);
folder.fold_decl(d).move_iter() folder.fold_decl(d).move_iter()
.map(|d| StmtDecl(d, folder.new_id(nid))) .map(|d| StmtDecl(d, id))
.collect() .collect()
} }
StmtExpr(e, nid) => { StmtExpr(e, id) => {
SmallVector::one(StmtExpr(folder.fold_expr(e), folder.new_id(nid))) let id = folder.new_id(id);
SmallVector::one(StmtExpr(folder.fold_expr(e), id))
} }
StmtSemi(e, nid) => { StmtSemi(e, id) => {
SmallVector::one(StmtSemi(folder.fold_expr(e), folder.new_id(nid))) let id = folder.new_id(id);
SmallVector::one(StmtSemi(folder.fold_expr(e), id))
} }
StmtMac(ref mac, semi) => SmallVector::one(StmtMac(folder.fold_mac(mac), semi)) StmtMac(ref mac, semi) => SmallVector::one(StmtMac(folder.fold_mac(mac), semi))
}; };