diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 30b7317fa56..8e32191f22a 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -23,11 +23,28 @@ use ast; use ast_util; use codemap::{respan, Span, Spanned}; use parse::token; +use ptr::P; use owned_slice::OwnedSlice; use util::small_vector::SmallVector; use std::rc::Rc; -use std::gc::{Gc, GC}; + +// This could have a better place to live. +pub trait MoveMap { + fn move_map(self, f: |T| -> T) -> Self; +} + +impl MoveMap for Vec { + fn move_map(self, f: |T| -> T) -> Vec { + self.move_iter().map(f).collect() + } +} + +impl MoveMap for OwnedSlice { + fn move_map(self, f: |T| -> T) -> OwnedSlice { + OwnedSlice::from_vec(self.into_vec().move_map(f)) + } +} pub trait Folder { // Any additions to this trait should happen in form @@ -42,91 +59,91 @@ pub trait Folder { noop_fold_crate(c, self) } - fn fold_meta_items(&mut self, meta_items: &[Gc]) -> Vec> { + fn fold_meta_items(&mut self, meta_items: Vec>) -> Vec> { noop_fold_meta_items(meta_items, self) } - fn fold_meta_item(&mut self, meta_item: &MetaItem) -> MetaItem { + fn fold_meta_item(&mut self, meta_item: P) -> P { noop_fold_meta_item(meta_item, self) } - fn fold_view_path(&mut self, view_path: Gc) -> Gc { + fn fold_view_path(&mut self, view_path: P) -> P { noop_fold_view_path(view_path, self) } - fn fold_view_item(&mut self, vi: &ViewItem) -> ViewItem { + fn fold_view_item(&mut self, vi: ViewItem) -> ViewItem { noop_fold_view_item(vi, self) } - fn fold_foreign_item(&mut self, ni: Gc) -> Gc { - noop_fold_foreign_item(&*ni, self) + fn fold_foreign_item(&mut self, ni: P) -> P { + noop_fold_foreign_item(ni, self) } - fn fold_item(&mut self, i: Gc) -> SmallVector> { - noop_fold_item(&*i, self) + fn fold_item(&mut self, i: P) -> SmallVector> { + noop_fold_item(i, self) } - fn fold_item_simple(&mut self, i: &Item) -> Item { + fn fold_item_simple(&mut self, i: Item) -> Item { noop_fold_item_simple(i, self) } - fn fold_struct_field(&mut self, sf: &StructField) -> StructField { + fn fold_struct_field(&mut self, sf: StructField) -> StructField { noop_fold_struct_field(sf, self) } - fn fold_item_underscore(&mut self, i: &Item_) -> Item_ { + fn fold_item_underscore(&mut self, i: Item_) -> Item_ { noop_fold_item_underscore(i, self) } - fn fold_fn_decl(&mut self, d: &FnDecl) -> P { + fn fold_fn_decl(&mut self, d: P) -> P { noop_fold_fn_decl(d, self) } - fn fold_type_method(&mut self, m: &TypeMethod) -> TypeMethod { + fn fold_type_method(&mut self, m: TypeMethod) -> TypeMethod { noop_fold_type_method(m, self) } - fn fold_method(&mut self, m: Gc) -> SmallVector> { - noop_fold_method(&*m, self) + fn fold_method(&mut self, m: P) -> SmallVector> { + noop_fold_method(m, self) } fn fold_block(&mut self, b: P) -> P { noop_fold_block(b, self) } - fn fold_stmt(&mut self, s: &Stmt) -> SmallVector> { - noop_fold_stmt(s, self) + fn fold_stmt(&mut self, s: P) -> SmallVector> { + s.and_then(|s| noop_fold_stmt(s, self)) } - fn fold_arm(&mut self, a: &Arm) -> Arm { + fn fold_arm(&mut self, a: Arm) -> Arm { noop_fold_arm(a, self) } - fn fold_pat(&mut self, p: Gc) -> Gc { + fn fold_pat(&mut self, p: P) -> P { noop_fold_pat(p, self) } - fn fold_decl(&mut self, d: Gc) -> SmallVector> { + fn fold_decl(&mut self, d: P) -> SmallVector> { noop_fold_decl(d, self) } - fn fold_expr(&mut self, e: Gc) -> Gc { - noop_fold_expr(e, self) + fn fold_expr(&mut self, e: P) -> P { + e.map(|e| noop_fold_expr(e, self)) } fn fold_ty(&mut self, t: P) -> P { noop_fold_ty(t, self) } - fn fold_mod(&mut self, m: &Mod) -> Mod { + fn fold_mod(&mut self, m: Mod) -> Mod { noop_fold_mod(m, self) } - fn fold_foreign_mod(&mut self, nm: &ForeignMod) -> ForeignMod { + fn fold_foreign_mod(&mut self, nm: ForeignMod) -> ForeignMod { noop_fold_foreign_mod(nm, self) } - fn fold_variant(&mut self, v: &Variant) -> P { + fn fold_variant(&mut self, v: P) -> P { noop_fold_variant(v, self) } @@ -138,15 +155,15 @@ pub trait Folder { noop_fold_uint(i, self) } - fn fold_path(&mut self, p: &Path) -> Path { + fn fold_path(&mut self, p: Path) -> Path { noop_fold_path(p, self) } - fn fold_local(&mut self, l: Gc) -> Gc { + fn fold_local(&mut self, l: P) -> P { noop_fold_local(l, self) } - fn fold_mac(&mut self, _macro: &Mac) -> Mac { + fn fold_mac(&mut self, _macro: Mac) -> Mac { fail!("fold_mac disabled by default"); // NB: see note about macros above. // if you really want a folder that @@ -155,19 +172,19 @@ pub trait Folder { // fold::noop_fold_mac(_macro, self) } - fn fold_explicit_self(&mut self, es: &ExplicitSelf) -> ExplicitSelf { + fn fold_explicit_self(&mut self, es: ExplicitSelf) -> ExplicitSelf { noop_fold_explicit_self(es, self) } - fn fold_explicit_self_underscore(&mut self, es: &ExplicitSelf_) -> ExplicitSelf_ { + fn fold_explicit_self_underscore(&mut self, es: ExplicitSelf_) -> ExplicitSelf_ { noop_fold_explicit_self_underscore(es, self) } - fn fold_lifetime(&mut self, l: &Lifetime) -> Lifetime { + fn fold_lifetime(&mut self, l: Lifetime) -> Lifetime { noop_fold_lifetime(l, self) } - fn fold_lifetime_def(&mut self, l: &LifetimeDef) -> LifetimeDef { + fn fold_lifetime_def(&mut self, l: LifetimeDef) -> LifetimeDef { noop_fold_lifetime_def(l, self) } @@ -175,35 +192,35 @@ pub trait Folder { noop_fold_attribute(at, self) } - fn fold_arg(&mut self, a: &Arg) -> Arg { + fn fold_arg(&mut self, a: Arg) -> Arg { noop_fold_arg(a, self) } - fn fold_generics(&mut self, generics: &Generics) -> Generics { + fn fold_generics(&mut self, generics: Generics) -> Generics { noop_fold_generics(generics, self) } - fn fold_trait_ref(&mut self, p: &TraitRef) -> TraitRef { + fn fold_trait_ref(&mut self, p: TraitRef) -> TraitRef { noop_fold_trait_ref(p, self) } - fn fold_struct_def(&mut self, struct_def: Gc) -> Gc { + fn fold_struct_def(&mut self, struct_def: P) -> P { noop_fold_struct_def(struct_def, self) } - fn fold_lifetimes(&mut self, lts: &[Lifetime]) -> Vec { + fn fold_lifetimes(&mut self, lts: Vec) -> Vec { noop_fold_lifetimes(lts, self) } - fn fold_lifetime_defs(&mut self, lts: &[LifetimeDef]) -> Vec { + fn fold_lifetime_defs(&mut self, lts: Vec) -> Vec { noop_fold_lifetime_defs(lts, self) } - fn fold_ty_param(&mut self, tp: &TyParam) -> TyParam { + fn fold_ty_param(&mut self, tp: TyParam) -> TyParam { noop_fold_ty_param(tp, self) } - fn fold_ty_params(&mut self, tps: &[TyParam]) -> OwnedSlice { + fn fold_ty_params(&mut self, tps: OwnedSlice) -> OwnedSlice { noop_fold_ty_params(tps, self) } @@ -215,37 +232,37 @@ pub trait Folder { noop_fold_tts(tts, self) } - fn fold_token(&mut self, t: &token::Token) -> token::Token { + fn fold_token(&mut self, t: token::Token) -> token::Token { noop_fold_token(t, self) } - fn fold_interpolated(&mut self, nt : &token::Nonterminal) -> token::Nonterminal { + fn fold_interpolated(&mut self, nt: token::Nonterminal) -> token::Nonterminal { noop_fold_interpolated(nt, self) } - fn fold_opt_lifetime(&mut self, o_lt: &Option) -> Option { + fn fold_opt_lifetime(&mut self, o_lt: Option) -> Option { noop_fold_opt_lifetime(o_lt, self) } - fn fold_variant_arg(&mut self, va: &VariantArg) -> VariantArg { + fn fold_variant_arg(&mut self, va: VariantArg) -> VariantArg { noop_fold_variant_arg(va, self) } - fn fold_opt_bounds(&mut self, b: &Option>) + fn fold_opt_bounds(&mut self, b: Option>) -> Option> { noop_fold_opt_bounds(b, self) } - fn fold_bounds(&mut self, b: &OwnedSlice) + fn fold_bounds(&mut self, b: OwnedSlice) -> OwnedSlice { noop_fold_bounds(b, self) } - fn fold_ty_param_bound(&mut self, tpb: &TyParamBound) -> TyParamBound { + fn fold_ty_param_bound(&mut self, tpb: TyParamBound) -> TyParamBound { noop_fold_ty_param_bound(tpb, self) } - fn fold_mt(&mut self, mt: &MutTy) -> MutTy { + fn fold_mt(&mut self, mt: MutTy) -> MutTy { noop_fold_mt(mt, self) } @@ -253,23 +270,16 @@ pub trait Folder { noop_fold_field(field, self) } - fn fold_where_clause(&mut self, where_clause: &WhereClause) + fn fold_where_clause(&mut self, where_clause: WhereClause) -> WhereClause { noop_fold_where_clause(where_clause, self) } - fn fold_where_predicate(&mut self, where_predicate: &WherePredicate) + fn fold_where_predicate(&mut self, where_predicate: WherePredicate) -> WherePredicate { noop_fold_where_predicate(where_predicate, self) } -// Helper methods: - - fn map_exprs(&self, f: |Gc| -> Gc, - es: &[Gc]) -> Vec> { - es.iter().map(|x| f(*x)).collect() - } - fn new_id(&mut self, i: NodeId) -> NodeId { i } @@ -279,190 +289,161 @@ pub trait Folder { } } -pub fn noop_fold_meta_items(meta_items: &[Gc], fld: &mut T) - -> Vec> { - meta_items.iter().map(|x| box (GC) fld.fold_meta_item(&**x)).collect() +pub fn noop_fold_meta_items(meta_items: Vec>, fld: &mut T) + -> Vec> { + meta_items.move_map(|x| fld.fold_meta_item(x)) } -pub fn noop_fold_view_path(view_path: Gc, fld: &mut T) -> Gc { - let inner_view_path = match view_path.node { - ViewPathSimple(ref ident, ref path, node_id) => { - let id = fld.new_id(node_id); - ViewPathSimple(ident.clone(), - fld.fold_path(path), - id) - } - ViewPathGlob(ref path, node_id) => { - let id = fld.new_id(node_id); - ViewPathGlob(fld.fold_path(path), id) - } - ViewPathList(ref path, ref path_list_idents, node_id) => { - let id = fld.new_id(node_id); - ViewPathList(fld.fold_path(path), - path_list_idents.iter().map(|path_list_ident| { - Spanned { - node: match path_list_ident.node { - PathListIdent { id, name } => - PathListIdent { - id: fld.new_id(id), - name: name.clone() - }, - PathListMod { id } => - PathListMod { id: fld.new_id(id) } - }, - span: fld.new_span(path_list_ident.span) - } - }).collect(), - id) - } - }; - box(GC) Spanned { - node: inner_view_path, - span: fld.new_span(view_path.span), - } -} - -pub fn noop_fold_arm(a: &Arm, fld: &mut T) -> Arm { - Arm { - attrs: a.attrs.iter().map(|x| fld.fold_attribute(*x)).collect(), - pats: a.pats.iter().map(|x| fld.fold_pat(*x)).collect(), - guard: a.guard.map(|x| fld.fold_expr(x)), - body: fld.fold_expr(a.body), - } -} - -pub fn noop_fold_decl(d: Gc, fld: &mut T) -> SmallVector> { - let node = match d.node { - DeclLocal(ref l) => SmallVector::one(DeclLocal(fld.fold_local(*l))), - DeclItem(it) => { - fld.fold_item(it).move_iter().map(|i| DeclItem(i)).collect() - } - }; - - node.move_iter().map(|node| { - box(GC) Spanned { - node: node, - span: fld.new_span(d.span), - } - }).collect() -} - -pub fn noop_fold_ty(t: P, fld: &mut T) -> P { - let id = fld.new_id(t.id); - let node = match t.node { - TyNil | TyBot | TyInfer => t.node.clone(), - TyBox(ty) => TyBox(fld.fold_ty(ty)), - TyUniq(ty) => TyUniq(fld.fold_ty(ty)), - TyVec(ty) => TyVec(fld.fold_ty(ty)), - TyPtr(ref mt) => TyPtr(fld.fold_mt(mt)), - TyRptr(ref region, ref mt) => { - TyRptr(fld.fold_opt_lifetime(region), fld.fold_mt(mt)) - } - TyClosure(ref f) => { - TyClosure(box(GC) ClosureTy { - fn_style: f.fn_style, - onceness: f.onceness, - bounds: fld.fold_bounds(&f.bounds), - decl: fld.fold_fn_decl(&*f.decl), - lifetimes: fld.fold_lifetime_defs(f.lifetimes.as_slice()), - }) - } - TyProc(ref f) => { - TyProc(box(GC) ClosureTy { - fn_style: f.fn_style, - onceness: f.onceness, - bounds: fld.fold_bounds(&f.bounds), - decl: fld.fold_fn_decl(&*f.decl), - lifetimes: fld.fold_lifetime_defs(f.lifetimes.as_slice()), - }) - } - TyBareFn(ref f) => { - TyBareFn(box(GC) BareFnTy { - lifetimes: fld.fold_lifetime_defs(f.lifetimes.as_slice()), - fn_style: f.fn_style, - abi: f.abi, - decl: fld.fold_fn_decl(&*f.decl) - }) - } - TyUnboxedFn(ref f) => { - TyUnboxedFn(box(GC) UnboxedFnTy { - decl: fld.fold_fn_decl(&*f.decl), - kind: f.kind, - }) - } - TyTup(ref tys) => TyTup(tys.iter().map(|&ty| fld.fold_ty(ty)).collect()), - TyParen(ref ty) => TyParen(fld.fold_ty(*ty)), - TyPath(ref path, ref bounds, id) => { - let id = fld.new_id(id); - TyPath(fld.fold_path(path), - fld.fold_opt_bounds(bounds), - id) - } - TyFixedLengthVec(ty, e) => { - TyFixedLengthVec(fld.fold_ty(ty), fld.fold_expr(e)) - } - TyTypeof(expr) => TyTypeof(fld.fold_expr(expr)), - }; - P(Ty { - id: id, - span: fld.new_span(t.span), - node: node, +pub fn noop_fold_view_path(view_path: P, fld: &mut T) -> P { + view_path.map(|Spanned {node, span}| Spanned { + node: match node { + ViewPathSimple(ident, path, node_id) => { + let id = fld.new_id(node_id); + ViewPathSimple(ident, fld.fold_path(path), id) + } + ViewPathGlob(path, node_id) => { + let id = fld.new_id(node_id); + ViewPathGlob(fld.fold_path(path), id) + } + ViewPathList(path, path_list_idents, node_id) => { + let id = fld.new_id(node_id); + ViewPathList(fld.fold_path(path), + path_list_idents.move_map(|path_list_ident| { + Spanned { + node: match path_list_ident.node { + PathListIdent { id, name } => + PathListIdent { + id: fld.new_id(id), + name: name + }, + PathListMod { id } => + PathListMod { id: fld.new_id(id) } + }, + span: fld.new_span(path_list_ident.span) + } + }), + id) + } + }, + span: fld.new_span(span) }) } -pub fn noop_fold_foreign_mod(nm: &ForeignMod, fld: &mut T) -> ForeignMod { - ast::ForeignMod { - abi: nm.abi, - view_items: nm.view_items - .iter() - .map(|x| fld.fold_view_item(x)) - .collect(), - items: nm.items - .iter() - .map(|x| fld.fold_foreign_item(*x)) - .collect(), +pub fn noop_fold_arm(Arm {attrs, pats, guard, body}: Arm, fld: &mut T) -> Arm { + Arm { + attrs: attrs.move_map(|x| fld.fold_attribute(x)), + pats: pats.move_map(|x| fld.fold_pat(x)), + guard: guard.map(|x| fld.fold_expr(x)), + body: fld.fold_expr(body), } } -pub fn noop_fold_variant(v: &Variant, fld: &mut T) -> P { - let id = fld.new_id(v.node.id); - let kind; - match v.node.kind { - TupleVariantKind(ref variant_args) => { - kind = TupleVariantKind(variant_args.iter().map(|x| - fld.fold_variant_arg(x)).collect()) - } - StructVariantKind(ref struct_def) => { - kind = StructVariantKind(box(GC) ast::StructDef { - fields: struct_def.fields.iter() - .map(|f| fld.fold_struct_field(f)).collect(), - ctor_id: struct_def.ctor_id.map(|c| fld.new_id(c)), - super_struct: match struct_def.super_struct { - Some(t) => Some(fld.fold_ty(t)), - None => None - }, - is_virtual: struct_def.is_virtual, - }) - } +pub fn noop_fold_decl(d: P, fld: &mut T) -> SmallVector> { + d.and_then(|Spanned {node, span}| match node { + DeclLocal(l) => SmallVector::one(P(Spanned { + node: DeclLocal(fld.fold_local(l)), + span: fld.new_span(span) + })), + DeclItem(it) => fld.fold_item(it).move_iter().map(|i| P(Spanned { + node: DeclItem(i), + span: fld.new_span(span) + })).collect() + }) +} + +pub fn noop_fold_ty(t: P, fld: &mut T) -> P { + t.map(|Ty {id, node, span}| Ty { + id: fld.new_id(id), + node: match node { + TyNil | TyBot | TyInfer => node, + TyBox(ty) => TyBox(fld.fold_ty(ty)), + TyUniq(ty) => TyUniq(fld.fold_ty(ty)), + TyVec(ty) => TyVec(fld.fold_ty(ty)), + TyPtr(mt) => TyPtr(fld.fold_mt(mt)), + TyRptr(region, mt) => { + TyRptr(fld.fold_opt_lifetime(region), fld.fold_mt(mt)) + } + TyClosure(f) => { + TyClosure(f.map(|ClosureTy {fn_style, onceness, bounds, decl, lifetimes}| { + ClosureTy { + fn_style: fn_style, + onceness: onceness, + bounds: fld.fold_bounds(bounds), + decl: fld.fold_fn_decl(decl), + lifetimes: fld.fold_lifetime_defs(lifetimes) + } + })) + } + TyProc(f) => { + TyProc(f.map(|ClosureTy {fn_style, onceness, bounds, decl, lifetimes}| { + ClosureTy { + fn_style: fn_style, + onceness: onceness, + bounds: fld.fold_bounds(bounds), + decl: fld.fold_fn_decl(decl), + lifetimes: fld.fold_lifetime_defs(lifetimes) + } + })) + } + TyBareFn(f) => { + TyBareFn(f.map(|BareFnTy {lifetimes, fn_style, abi, decl}| BareFnTy { + lifetimes: fld.fold_lifetime_defs(lifetimes), + fn_style: fn_style, + abi: abi, + decl: fld.fold_fn_decl(decl) + })) + } + TyUnboxedFn(f) => { + TyUnboxedFn(f.map(|UnboxedFnTy {decl, kind}| UnboxedFnTy { + decl: fld.fold_fn_decl(decl), + kind: kind, + })) + } + TyTup(tys) => TyTup(tys.move_map(|ty| fld.fold_ty(ty))), + TyParen(ty) => TyParen(fld.fold_ty(ty)), + TyPath(path, bounds, id) => { + let id = fld.new_id(id); + TyPath(fld.fold_path(path), + fld.fold_opt_bounds(bounds), + id) + } + TyFixedLengthVec(ty, e) => { + TyFixedLengthVec(fld.fold_ty(ty), fld.fold_expr(e)) + } + TyTypeof(expr) => TyTypeof(fld.fold_expr(expr)) + }, + span: fld.new_span(span) + }) +} + +pub fn noop_fold_foreign_mod(ForeignMod {abi, view_items, items}: ForeignMod, + fld: &mut T) -> ForeignMod { + ForeignMod { + abi: abi, + view_items: view_items.move_map(|x| fld.fold_view_item(x)), + items: items.move_map(|x| fld.fold_foreign_item(x)), } +} - let attrs = v.node.attrs.iter().map(|x| fld.fold_attribute(*x)).collect(); - - let de = match v.node.disr_expr { - Some(e) => Some(fld.fold_expr(e)), - None => None - }; - let node = ast::Variant_ { - name: v.node.name, - attrs: attrs, - kind: kind, - id: id, - disr_expr: de, - vis: v.node.vis, - }; - P(Spanned { - node: node, - span: fld.new_span(v.span), +pub fn noop_fold_variant(v: P, fld: &mut T) -> P { + v.map(|Spanned {node: Variant_ {id, name, attrs, kind, disr_expr, vis}, span}| Spanned { + node: Variant_ { + id: fld.new_id(id), + name: name, + attrs: attrs.move_map(|x| fld.fold_attribute(x)), + kind: match kind { + TupleVariantKind(variant_args) => { + TupleVariantKind(variant_args.move_map(|x| + fld.fold_variant_arg(x))) + } + StructVariantKind(struct_def) => { + StructVariantKind(fld.fold_struct_def(struct_def)) + } + }, + disr_expr: disr_expr.map(|e| fld.fold_expr(e)), + vis: vis, + }, + span: fld.new_span(span), }) } @@ -474,109 +455,103 @@ pub fn noop_fold_uint(i: uint, _: &mut T) -> uint { i } -pub fn noop_fold_path(p: &Path, fld: &mut T) -> Path { - ast::Path { - span: fld.new_span(p.span), - global: p.global, - segments: p.segments.iter().map(|segment| ast::PathSegment { - identifier: fld.fold_ident(segment.identifier), - lifetimes: segment.lifetimes.iter().map(|l| fld.fold_lifetime(l)).collect(), - types: segment.types.iter().map(|&typ| fld.fold_ty(typ)).collect(), - }).collect() +pub fn noop_fold_path(Path {global, segments, span}: Path, fld: &mut T) -> Path { + Path { + global: global, + segments: segments.move_map(|PathSegment {identifier, lifetimes, types}| PathSegment { + identifier: fld.fold_ident(identifier), + lifetimes: fld.fold_lifetimes(lifetimes), + types: types.move_map(|typ| fld.fold_ty(typ)), + }), + span: fld.new_span(span) } } -pub fn noop_fold_local(l: Gc, fld: &mut T) -> Gc { - let id = fld.new_id(l.id); // Needs to be first, for ast_map. - box(GC) Local { - id: id, - ty: fld.fold_ty(l.ty), - pat: fld.fold_pat(l.pat), - init: l.init.map(|e| fld.fold_expr(e)), - span: fld.new_span(l.span), - source: l.source, - } +pub fn noop_fold_local(l: P, fld: &mut T) -> P { + l.map(|Local {id, pat, ty, init, source, span}| Local { + id: fld.new_id(id), // Needs to be first, for ast_map. + ty: fld.fold_ty(ty), + pat: fld.fold_pat(pat), + init: init.map(|e| fld.fold_expr(e)), + source: source, + span: fld.new_span(span) + }) } pub fn noop_fold_attribute(at: Attribute, fld: &mut T) -> Attribute { + let Spanned {node: Attribute_ {id, style, value, is_sugared_doc}, span} = at; Spanned { - span: fld.new_span(at.span), - node: ast::Attribute_ { - id: at.node.id, - style: at.node.style, - value: box (GC) fld.fold_meta_item(&*at.node.value), - is_sugared_doc: at.node.is_sugared_doc - } + node: Attribute_ { + id: id, + style: style, + value: fld.fold_meta_item(value), + is_sugared_doc: is_sugared_doc + }, + span: fld.new_span(span) } } -pub fn noop_fold_explicit_self_underscore(es: &ExplicitSelf_, fld: &mut T) +pub fn noop_fold_explicit_self_underscore(es: ExplicitSelf_, fld: &mut T) -> ExplicitSelf_ { - match *es { - SelfStatic | SelfValue(_) => *es, - SelfRegion(ref lifetime, m, id) => { + match es { + SelfStatic | SelfValue(_) => es, + SelfRegion(lifetime, m, id) => { SelfRegion(fld.fold_opt_lifetime(lifetime), m, id) } - SelfExplicit(ref typ, id) => SelfExplicit(fld.fold_ty(*typ), id), + SelfExplicit(typ, id) => SelfExplicit(fld.fold_ty(typ), id), } } -pub fn noop_fold_explicit_self(es: &ExplicitSelf, fld: &mut T) -> ExplicitSelf { +pub fn noop_fold_explicit_self(Spanned {span, node}: ExplicitSelf, fld: &mut T) + -> ExplicitSelf { Spanned { - span: fld.new_span(es.span), - node: fld.fold_explicit_self_underscore(&es.node) + node: fld.fold_explicit_self_underscore(node), + span: fld.new_span(span) } } -pub fn noop_fold_mac(macro: &Mac, fld: &mut T) -> Mac { +pub fn noop_fold_mac(Spanned {node, span}: Mac, fld: &mut T) -> Mac { Spanned { - node: match macro.node { - MacInvocTT(ref p, ref tts, ctxt) => { - MacInvocTT(fld.fold_path(p), - fld.fold_tts(tts.as_slice()), - ctxt) + node: match node { + MacInvocTT(p, tts, ctxt) => { + MacInvocTT(fld.fold_path(p), fld.fold_tts(tts.as_slice()), ctxt) } }, - span: fld.new_span(macro.span) + span: fld.new_span(span) } } -pub fn noop_fold_meta_item(mi: &MetaItem, fld: &mut T) -> MetaItem { - Spanned { - node: - match mi.node { - MetaWord(ref id) => MetaWord((*id).clone()), - MetaList(ref id, ref mis) => { - MetaList((*id).clone(), - mis.iter() - .map(|e| box (GC) fld.fold_meta_item(&**e)).collect()) - } - MetaNameValue(ref id, ref s) => { - MetaNameValue((*id).clone(), (*s).clone()) - } - }, - span: fld.new_span(mi.span) } +pub fn noop_fold_meta_item(mi: P, fld: &mut T) -> P { + mi.map(|Spanned {node, span}| Spanned { + node: match node { + MetaWord(id) => MetaWord(id), + MetaList(id, mis) => { + MetaList(id, mis.move_map(|e| fld.fold_meta_item(e))) + } + MetaNameValue(id, s) => MetaNameValue(id, s) + }, + span: fld.new_span(span) + }) } -pub fn noop_fold_arg(a: &Arg, fld: &mut T) -> Arg { - let id = fld.new_id(a.id); // Needs to be first, for ast_map. +pub fn noop_fold_arg(Arg {id, pat, ty}: Arg, fld: &mut T) -> Arg { Arg { - id: id, - ty: fld.fold_ty(a.ty), - pat: fld.fold_pat(a.pat), + id: fld.new_id(id), // Needs to be first, for ast_map. + pat: fld.fold_pat(pat), + ty: fld.fold_ty(ty) } } pub fn noop_fold_tt(tt: &TokenTree, fld: &mut T) -> TokenTree { match *tt { TTTok(span, ref tok) => - TTTok(span, fld.fold_token(tok)), + TTTok(span, fld.fold_token(tok.clone())), TTDelim(ref tts) => TTDelim(Rc::new(fld.fold_tts(tts.as_slice()))), TTSeq(span, ref pattern, ref sep, is_optional) => TTSeq(span, Rc::new(fld.fold_tts(pattern.as_slice())), - sep.as_ref().map(|tok| fld.fold_token(tok)), + sep.clone().map(|tok| fld.fold_token(tok)), is_optional), TTNonterminal(sp,ref ident) => TTNonterminal(sp,fld.fold_ident(*ident)) @@ -588,14 +563,14 @@ pub fn noop_fold_tts(tts: &[TokenTree], fld: &mut T) -> Vec(t: &token::Token, fld: &mut T) -> token::Token { - match *t { +pub fn noop_fold_token(t: token::Token, fld: &mut T) -> token::Token { + match t { token::IDENT(id, followed_by_colons) => { token::IDENT(fld.fold_ident(id), followed_by_colons) } token::LIFETIME(id) => token::LIFETIME(fld.fold_ident(id)), - token::INTERPOLATED(ref nt) => token::INTERPOLATED(fld.fold_interpolated(nt)), - _ => (*t).clone() + token::INTERPOLATED(nt) => token::INTERPOLATED(fld.fold_interpolated(nt)), + _ => t } } @@ -619,9 +594,9 @@ pub fn noop_fold_token(t: &token::Token, fld: &mut T) -> token::Token // BTW, design choice: I considered just changing the type of, e.g., NtItem to contain // multiple items, but decided against it when I looked at parse_item_or_view_item and // tried to figure out what I would do with multiple items there.... -pub fn noop_fold_interpolated(nt : &token::Nonterminal, fld: &mut T) +pub fn noop_fold_interpolated(nt: token::Nonterminal, fld: &mut T) -> token::Nonterminal { - match *nt { + match nt { token::NtItem(item) => token::NtItem(fld.fold_item(item) // this is probably okay, because the only folds likely @@ -630,7 +605,7 @@ pub fn noop_fold_interpolated(nt : &token::Nonterminal, fld: &mut T) .expect_one("expected fold to produce exactly one item")), token::NtBlock(block) => token::NtBlock(fld.fold_block(block)), token::NtStmt(stmt) => - token::NtStmt(fld.fold_stmt(&*stmt) + token::NtStmt(fld.fold_stmt(stmt) // this is probably okay, because the only folds likely // to peek inside interpolated nodes will be renamings/markings, // which map single items to single items @@ -638,403 +613,373 @@ pub fn noop_fold_interpolated(nt : &token::Nonterminal, fld: &mut T) token::NtPat(pat) => token::NtPat(fld.fold_pat(pat)), token::NtExpr(expr) => token::NtExpr(fld.fold_expr(expr)), token::NtTy(ty) => token::NtTy(fld.fold_ty(ty)), - token::NtIdent(ref id, is_mod_name) => - token::NtIdent(box fld.fold_ident(**id),is_mod_name), - token::NtMeta(meta_item) => token::NtMeta(box (GC) fld.fold_meta_item(&*meta_item)), - token::NtPath(ref path) => token::NtPath(box fld.fold_path(&**path)), - token::NtTT(tt) => token::NtTT(box (GC) fld.fold_tt(&*tt)), + token::NtIdent(box id, is_mod_name) => + token::NtIdent(box fld.fold_ident(id), is_mod_name), + token::NtMeta(meta_item) => token::NtMeta(fld.fold_meta_item(meta_item)), + token::NtPath(box path) => token::NtPath(box fld.fold_path(path)), + token::NtTT(tt) => token::NtTT(P(fld.fold_tt(&*tt))), // it looks to me like we can leave out the matchers: token::NtMatchers(matchers) - _ => (*nt).clone() + _ => nt } } -pub fn noop_fold_fn_decl(decl: &FnDecl, fld: &mut T) -> P { - P(FnDecl { - inputs: decl.inputs.iter().map(|x| fld.fold_arg(x)).collect(), // bad copy - output: fld.fold_ty(decl.output), - cf: decl.cf, - variadic: decl.variadic +pub fn noop_fold_fn_decl(decl: P, fld: &mut T) -> P { + decl.map(|FnDecl {inputs, output, cf, variadic}| FnDecl { + inputs: inputs.move_map(|x| fld.fold_arg(x)), + output: fld.fold_ty(output), + cf: cf, + variadic: variadic }) } -pub fn noop_fold_ty_param_bound(tpb: &TyParamBound, fld: &mut T) +pub fn noop_fold_ty_param_bound(tpb: TyParamBound, fld: &mut T) -> TyParamBound { - match *tpb { - TraitTyParamBound(ref ty) => TraitTyParamBound(fld.fold_trait_ref(ty)), - RegionTyParamBound(ref lifetime) => RegionTyParamBound(fld.fold_lifetime(lifetime)), - UnboxedFnTyParamBound(ref unboxed_function_type) => { + match tpb { + TraitTyParamBound(ty) => TraitTyParamBound(fld.fold_trait_ref(ty)), + RegionTyParamBound(lifetime) => RegionTyParamBound(fld.fold_lifetime(lifetime)), + UnboxedFnTyParamBound(UnboxedFnTy {decl, kind}) => { UnboxedFnTyParamBound(UnboxedFnTy { - decl: fld.fold_fn_decl(&*unboxed_function_type.decl), - kind: unboxed_function_type.kind, + decl: fld.fold_fn_decl(decl), + kind: kind, }) } } } -pub fn noop_fold_ty_param(tp: &TyParam, fld: &mut T) -> TyParam { - let id = fld.new_id(tp.id); +pub fn noop_fold_ty_param(tp: TyParam, fld: &mut T) -> TyParam { + let TyParam {id, ident, bounds, unbound, default, span} = tp; TyParam { - ident: tp.ident, - id: id, - bounds: fld.fold_bounds(&tp.bounds), - unbound: tp.unbound.as_ref().map(|x| fld.fold_ty_param_bound(x)), - default: tp.default.map(|x| fld.fold_ty(x)), - span: tp.span + id: fld.new_id(id), + ident: ident, + bounds: fld.fold_bounds(bounds), + unbound: unbound.map(|x| fld.fold_ty_param_bound(x)), + default: default.map(|x| fld.fold_ty(x)), + span: span } } -pub fn noop_fold_ty_params(tps: &[TyParam], fld: &mut T) +pub fn noop_fold_ty_params(tps: OwnedSlice, fld: &mut T) -> OwnedSlice { - tps.iter().map(|tp| fld.fold_ty_param(tp)).collect() + tps.move_map(|tp| fld.fold_ty_param(tp)) } -pub fn noop_fold_lifetime(l: &Lifetime, fld: &mut T) -> Lifetime { - let id = fld.new_id(l.id); +pub fn noop_fold_lifetime(l: Lifetime, fld: &mut T) -> Lifetime { Lifetime { - id: id, - span: fld.new_span(l.span), - name: l.name + id: fld.new_id(l.id), + name: l.name, + span: fld.new_span(l.span) } } -pub fn noop_fold_lifetime_def(l: &LifetimeDef, fld: &mut T) - -> LifetimeDef -{ +pub fn noop_fold_lifetime_def(l: LifetimeDef, fld: &mut T) + -> LifetimeDef { LifetimeDef { - lifetime: fld.fold_lifetime(&l.lifetime), - bounds: fld.fold_lifetimes(l.bounds.as_slice()), + lifetime: fld.fold_lifetime(l.lifetime), + bounds: fld.fold_lifetimes(l.bounds), } } -pub fn noop_fold_lifetimes(lts: &[Lifetime], fld: &mut T) -> Vec { - lts.iter().map(|l| fld.fold_lifetime(l)).collect() +pub fn noop_fold_lifetimes(lts: Vec, fld: &mut T) -> Vec { + lts.move_map(|l| fld.fold_lifetime(l)) } -pub fn noop_fold_lifetime_defs(lts: &[LifetimeDef], fld: &mut T) -> Vec { - lts.iter().map(|l| fld.fold_lifetime_def(l)).collect() +pub fn noop_fold_lifetime_defs(lts: Vec, fld: &mut T) + -> Vec { + lts.move_map(|l| fld.fold_lifetime_def(l)) } -pub fn noop_fold_opt_lifetime(o_lt: &Option, fld: &mut T) - -> Option { - o_lt.as_ref().map(|lt| fld.fold_lifetime(lt)) +pub fn noop_fold_opt_lifetime(o_lt: Option, fld: &mut T) + -> Option { + o_lt.map(|lt| fld.fold_lifetime(lt)) } -pub fn noop_fold_generics(generics: &Generics, fld: &mut T) -> Generics { +pub fn noop_fold_generics(Generics {ty_params, lifetimes, where_clause}: Generics, + fld: &mut T) -> Generics { Generics { - ty_params: fld.fold_ty_params(generics.ty_params.as_slice()), - lifetimes: fld.fold_lifetime_defs(generics.lifetimes.as_slice()), - where_clause: fld.fold_where_clause(&generics.where_clause), + ty_params: fld.fold_ty_params(ty_params), + lifetimes: fld.fold_lifetime_defs(lifetimes), + where_clause: fld.fold_where_clause(where_clause), } } pub fn noop_fold_where_clause( - where_clause: &WhereClause, + WhereClause {id, predicates}: WhereClause, fld: &mut T) -> WhereClause { WhereClause { - id: fld.new_id(where_clause.id), - predicates: where_clause.predicates.iter().map(|predicate| { + id: fld.new_id(id), + predicates: predicates.move_map(|predicate| { fld.fold_where_predicate(predicate) - }).collect(), + }) } } pub fn noop_fold_where_predicate( - predicate: &WherePredicate, + WherePredicate {id, ident, bounds, span}: WherePredicate, fld: &mut T) -> WherePredicate { WherePredicate { - id: fld.new_id(predicate.id), - span: fld.new_span(predicate.span), - ident: fld.fold_ident(predicate.ident), - bounds: predicate.bounds.map(|x| { - fld.fold_ty_param_bound(x) - }), + id: fld.new_id(id), + ident: fld.fold_ident(ident), + bounds: bounds.move_map(|x| fld.fold_ty_param_bound(x)), + span: fld.new_span(span) } } -pub fn noop_fold_struct_def(struct_def: Gc, - fld: &mut T) -> Gc { - box(GC) ast::StructDef { - fields: struct_def.fields.iter().map(|f| fld.fold_struct_field(f)).collect(), - ctor_id: struct_def.ctor_id.map(|cid| fld.new_id(cid)), - super_struct: match struct_def.super_struct { - Some(t) => Some(fld.fold_ty(t)), - None => None - }, - is_virtual: struct_def.is_virtual, +pub fn noop_fold_struct_def(struct_def: P, fld: &mut T) -> P { + struct_def.map(|StructDef {fields, ctor_id, super_struct, is_virtual}| StructDef { + fields: fields.move_map(|f| fld.fold_struct_field(f)), + ctor_id: ctor_id.map(|cid| fld.new_id(cid)), + super_struct: super_struct.map(|t| fld.fold_ty(t)), + is_virtual: is_virtual + }) +} + +pub fn noop_fold_trait_ref(TraitRef {ref_id, path}: TraitRef, fld: &mut T) -> TraitRef { + TraitRef { + ref_id: fld.new_id(ref_id), + path: fld.fold_path(path), } } -pub fn noop_fold_trait_ref(p: &TraitRef, fld: &mut T) -> TraitRef { - let id = fld.new_id(p.ref_id); - ast::TraitRef { - path: fld.fold_path(&p.path), - ref_id: id, - } -} - -pub fn noop_fold_struct_field(f: &StructField, fld: &mut T) -> StructField { - let id = fld.new_id(f.node.id); +pub fn noop_fold_struct_field(f: StructField, fld: &mut T) -> StructField { + let StructField {node: StructField_ {id, kind, ty, attrs}, span} = f; Spanned { - node: ast::StructField_ { - kind: f.node.kind, - id: id, - ty: fld.fold_ty(f.node.ty), - attrs: f.node.attrs.iter().map(|a| fld.fold_attribute(*a)).collect(), + node: StructField_ { + id: fld.new_id(id), + kind: kind, + ty: fld.fold_ty(ty), + attrs: attrs.move_map(|a| fld.fold_attribute(a)) }, - span: fld.new_span(f.span), + span: fld.new_span(span) } } -pub fn noop_fold_field(field: Field, folder: &mut T) -> Field { - ast::Field { - ident: respan(field.ident.span, folder.fold_ident(field.ident.node)), - expr: folder.fold_expr(field.expr), - span: folder.new_span(field.span), +pub fn noop_fold_field(Field {ident, expr, span}: Field, folder: &mut T) -> Field { + Field { + ident: respan(ident.span, folder.fold_ident(ident.node)), + expr: folder.fold_expr(expr), + span: folder.new_span(span) } } -pub fn noop_fold_mt(mt: &MutTy, folder: &mut T) -> MutTy { +pub fn noop_fold_mt(MutTy {ty, mutbl}: MutTy, folder: &mut T) -> MutTy { MutTy { - ty: folder.fold_ty(mt.ty), - mutbl: mt.mutbl, + ty: folder.fold_ty(ty), + mutbl: mutbl, } } -pub fn noop_fold_opt_bounds(b: &Option>, folder: &mut T) - -> Option> { - b.as_ref().map(|bounds| folder.fold_bounds(bounds)) +pub fn noop_fold_opt_bounds(b: Option>, folder: &mut T) + -> Option> { + b.map(|bounds| folder.fold_bounds(bounds)) } -fn noop_fold_bounds(bounds: &TyParamBounds, folder: &mut T) +fn noop_fold_bounds(bounds: TyParamBounds, folder: &mut T) -> TyParamBounds { - bounds.map(|bound| folder.fold_ty_param_bound(bound)) + bounds.move_map(|bound| folder.fold_ty_param_bound(bound)) } -pub fn noop_fold_variant_arg(va: &VariantArg, folder: &mut T) -> VariantArg { - let id = folder.new_id(va.id); - ast::VariantArg { - ty: folder.fold_ty(va.ty), - id: id, +fn noop_fold_variant_arg(VariantArg {id, ty}: VariantArg, folder: &mut T) + -> VariantArg { + VariantArg { + id: folder.new_id(id), + ty: folder.fold_ty(ty) } } -pub fn noop_fold_view_item(vi: &ViewItem, folder: &mut T) - -> ViewItem{ - let inner_view_item = match vi.node { - ViewItemExternCrate(ref ident, ref string, node_id) => { - ViewItemExternCrate(ident.clone(), - (*string).clone(), - folder.new_id(node_id)) - } - ViewItemUse(ref view_path) => { - ViewItemUse(folder.fold_view_path(*view_path)) - } - }; +pub fn noop_fold_view_item(ViewItem {node, attrs, vis, span}: ViewItem, + folder: &mut T) -> ViewItem { ViewItem { - node: inner_view_item, - attrs: vi.attrs.iter().map(|a| folder.fold_attribute(*a)).collect(), - vis: vi.vis, - span: folder.new_span(vi.span), + node: match node { + ViewItemExternCrate(ident, string, node_id) => { + ViewItemExternCrate(ident, string, + folder.new_id(node_id)) + } + ViewItemUse(view_path) => { + ViewItemUse(folder.fold_view_path(view_path)) + } + }, + attrs: attrs.move_map(|a| folder.fold_attribute(a)), + vis: vis, + span: folder.new_span(span) } } pub fn noop_fold_block(b: P, folder: &mut T) -> P { - 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 stmts = b.stmts.iter().flat_map(|s| folder.fold_stmt(&**s).move_iter()).collect(); - P(Block { - id: id, - view_items: view_items, - stmts: stmts, - expr: b.expr.map(|x| folder.fold_expr(x)), - rules: b.rules, - span: folder.new_span(b.span), + b.map(|Block {id, view_items, stmts, expr, rules, span}| Block { + id: folder.new_id(id), // Needs to be first, for ast_map. + view_items: view_items.move_map(|x| folder.fold_view_item(x)), + stmts: stmts.move_iter().flat_map(|s| folder.fold_stmt(s).move_iter()).collect(), + expr: expr.map(|x| folder.fold_expr(x)), + rules: rules, + span: folder.new_span(span), }) } -pub fn noop_fold_item_underscore(i: &Item_, folder: &mut T) -> Item_ { - match *i { +pub fn noop_fold_item_underscore(i: Item_, folder: &mut T) -> Item_ { + match i { ItemStatic(t, m, e) => { ItemStatic(folder.fold_ty(t), m, folder.fold_expr(e)) } - ItemFn(decl, fn_style, abi, ref generics, body) => { + ItemFn(decl, fn_style, abi, generics, body) => { ItemFn( - folder.fold_fn_decl(&*decl), + folder.fold_fn_decl(decl), fn_style, abi, folder.fold_generics(generics), folder.fold_block(body) ) } - ItemMod(ref m) => ItemMod(folder.fold_mod(m)), - ItemForeignMod(ref nm) => ItemForeignMod(folder.fold_foreign_mod(nm)), - ItemTy(t, ref generics) => { + ItemMod(m) => ItemMod(folder.fold_mod(m)), + ItemForeignMod(nm) => ItemForeignMod(folder.fold_foreign_mod(nm)), + ItemTy(t, generics) => { ItemTy(folder.fold_ty(t), folder.fold_generics(generics)) } - ItemEnum(ref enum_definition, ref generics) => { + ItemEnum(enum_definition, generics) => { ItemEnum( ast::EnumDef { - variants: enum_definition.variants.iter().map(|&x| { - folder.fold_variant(&*x) - }).collect(), + variants: enum_definition.variants.move_map(|x| folder.fold_variant(x)), }, folder.fold_generics(generics)) } - ItemStruct(ref struct_def, ref generics) => { - let struct_def = folder.fold_struct_def(*struct_def); + ItemStruct(struct_def, generics) => { + let struct_def = folder.fold_struct_def(struct_def); ItemStruct(struct_def, folder.fold_generics(generics)) } - ItemImpl(ref generics, ref ifce, ty, ref impl_items) => { + ItemImpl(generics, ifce, ty, impl_items) => { ItemImpl(folder.fold_generics(generics), - ifce.as_ref().map(|p| folder.fold_trait_ref(p)), + ifce.map(|p| folder.fold_trait_ref(p)), folder.fold_ty(ty), - impl_items.iter() - .flat_map(|impl_item| { - match *impl_item { - MethodImplItem(x) => { - folder.fold_method(x) - .move_iter() - .map(|x| MethodImplItem(x)) - } - } - }).collect() - ) - } - ItemTrait(ref generics, ref unbound, ref bounds, ref methods) => { - let bounds = folder.fold_bounds(bounds); - let methods = methods.iter().flat_map(|method| { - let r = match *method { - RequiredMethod(ref m) => { - SmallVector::one(RequiredMethod( - folder.fold_type_method(m))).move_iter() - } - ProvidedMethod(method) => { - // the awkward collect/iter idiom here is because - // even though an iter and a map satisfy the same trait bound, - // they're not actually the same type, so the method arms - // don't unify. - let methods : SmallVector = - folder.fold_method(method).move_iter() - .map(|m| ProvidedMethod(m)).collect(); - methods.move_iter() + impl_items.move_iter().flat_map(|impl_item| match impl_item { + MethodImplItem(x) => { + folder.fold_method(x).move_iter().map(|x| MethodImplItem(x)) } - }; - r + }).collect()) + } + ItemTrait(generics, unbound, bounds, methods) => { + let bounds = folder.fold_bounds(bounds); + let methods = methods.move_iter().flat_map(|method| match method { + RequiredMethod(m) => { + SmallVector::one(RequiredMethod(folder.fold_type_method(m))).move_iter() + } + ProvidedMethod(method) => { + // the awkward collect/iter idiom here is because + // even though an iter and a map satisfy the same trait bound, + // they're not actually the same type, so the method arms + // don't unify. + let methods: SmallVector = + folder.fold_method(method).move_iter() + .map(|m| ProvidedMethod(m)).collect(); + methods.move_iter() + } }).collect(); ItemTrait(folder.fold_generics(generics), - unbound.clone(), + unbound, bounds, methods) } - ItemMac(ref m) => ItemMac(folder.fold_mac(m)), + ItemMac(m) => ItemMac(folder.fold_mac(m)), } } -pub fn noop_fold_type_method(m: &TypeMethod, fld: &mut T) -> TypeMethod { - let id = fld.new_id(m.id); // Needs to be first, for ast_map. +pub fn noop_fold_type_method(m: TypeMethod, fld: &mut T) -> TypeMethod { + let TypeMethod {id, ident, attrs, fn_style, abi, decl, generics, explicit_self, vis, span} = m; TypeMethod { - id: id, - ident: fld.fold_ident(m.ident), - attrs: m.attrs.iter().map(|a| fld.fold_attribute(*a)).collect(), - fn_style: m.fn_style, - abi: m.abi, - decl: fld.fold_fn_decl(&*m.decl), - generics: fld.fold_generics(&m.generics), - explicit_self: fld.fold_explicit_self(&m.explicit_self), - span: fld.new_span(m.span), - vis: m.vis, + id: fld.new_id(id), // Needs to be first, for ast_map. + ident: fld.fold_ident(ident), + attrs: attrs.move_map(|a| fld.fold_attribute(a)), + fn_style: fn_style, + abi: abi, + decl: fld.fold_fn_decl(decl), + generics: fld.fold_generics(generics), + explicit_self: fld.fold_explicit_self(explicit_self), + vis: vis, + span: fld.new_span(span) } } -pub fn noop_fold_mod(m: &Mod, folder: &mut T) -> Mod { - ast::Mod { - inner: folder.new_span(m.inner), - view_items: m.view_items - .iter() - .map(|x| folder.fold_view_item(x)).collect(), - items: m.items.iter().flat_map(|x| folder.fold_item(*x).move_iter()).collect(), +pub fn noop_fold_mod(Mod {inner, view_items, items}: Mod, folder: &mut T) -> Mod { + Mod { + inner: folder.new_span(inner), + view_items: view_items.move_map(|x| folder.fold_view_item(x)), + items: items.move_iter().flat_map(|x| folder.fold_item(x).move_iter()).collect(), } } -pub fn noop_fold_crate(c: Crate, folder: &mut T) -> Crate { +pub fn noop_fold_crate(Crate {module, attrs, config, exported_macros, span}: Crate, + folder: &mut T) -> Crate { Crate { - module: folder.fold_mod(&c.module), - attrs: c.attrs.iter().map(|x| folder.fold_attribute(*x)).collect(), - config: c.config.iter().map(|x| box (GC) folder.fold_meta_item(&**x)).collect(), - span: folder.new_span(c.span), - exported_macros: c.exported_macros + module: folder.fold_mod(module), + attrs: attrs.move_map(|x| folder.fold_attribute(x)), + config: folder.fold_meta_items(config), + exported_macros: exported_macros, + span: folder.new_span(span) } } // fold one item into possibly many items -pub fn noop_fold_item(i: &Item, - folder: &mut T) -> SmallVector> { - SmallVector::one(box(GC) folder.fold_item_simple(i)) +pub fn noop_fold_item(i: P, folder: &mut T) -> SmallVector> { + SmallVector::one(i.map(|i| folder.fold_item_simple(i))) } - // fold one item into exactly one item -pub fn noop_fold_item_simple(i: &Item, folder: &mut T) -> Item { - let id = folder.new_id(i.id); // Needs to be first, for ast_map. - let node = folder.fold_item_underscore(&i.node); +pub fn noop_fold_item_simple(Item {id, ident, attrs, node, vis, span}: Item, + folder: &mut T) -> Item { + let id = folder.new_id(id); // Needs to be first, for ast_map. + let node = folder.fold_item_underscore(node); let ident = match node { // The node may have changed, recompute the "pretty" impl name. - ItemImpl(_, ref maybe_trait, ty, _) => { - ast_util::impl_pretty_name(maybe_trait, &*ty) + ItemImpl(_, ref maybe_trait, ref ty, _) => { + ast_util::impl_pretty_name(maybe_trait, &**ty) } - _ => i.ident + _ => ident }; Item { id: id, ident: folder.fold_ident(ident), - attrs: i.attrs.iter().map(|e| folder.fold_attribute(*e)).collect(), + attrs: attrs.move_map(|e| folder.fold_attribute(e)), node: node, - vis: i.vis, - span: folder.new_span(i.span) + vis: vis, + span: folder.new_span(span) } } -pub fn noop_fold_foreign_item(ni: &ForeignItem, - folder: &mut T) -> Gc { - let id = folder.new_id(ni.id); // Needs to be first, for ast_map. - box(GC) ForeignItem { - id: id, - ident: folder.fold_ident(ni.ident), - attrs: ni.attrs.iter().map(|x| folder.fold_attribute(*x)).collect(), - node: match ni.node { - ForeignItemFn(ref fdec, ref generics) => { - ForeignItemFn(P(FnDecl { - inputs: fdec.inputs.iter().map(|a| folder.fold_arg(a)).collect(), - output: folder.fold_ty(fdec.output), - cf: fdec.cf, - variadic: fdec.variadic +pub fn noop_fold_foreign_item(ni: P, folder: &mut T) -> P { + ni.map(|ForeignItem {id, ident, attrs, node, span, vis}| ForeignItem { + id: folder.new_id(id), // Needs to be first, for ast_map. + ident: folder.fold_ident(ident), + attrs: attrs.move_map(|x| folder.fold_attribute(x)), + node: match node { + ForeignItemFn(fdec, generics) => { + ForeignItemFn(fdec.map(|FnDecl {inputs, output, cf, variadic}| FnDecl { + inputs: inputs.move_map(|a| folder.fold_arg(a)), + output: folder.fold_ty(output), + cf: cf, + variadic: variadic }), folder.fold_generics(generics)) } ForeignItemStatic(t, m) => { ForeignItemStatic(folder.fold_ty(t), m) } }, - span: folder.new_span(ni.span), - vis: ni.vis, - } + vis: vis, + span: folder.new_span(span) + }) } // Default fold over a method. // Invariant: produces exactly one method. -pub fn noop_fold_method(m: &Method, folder: &mut T) -> SmallVector> { - let id = folder.new_id(m.id); // Needs to be first, for ast_map. - SmallVector::one(box(GC) Method { - attrs: m.attrs.iter().map(|a| folder.fold_attribute(*a)).collect(), - id: id, - span: folder.new_span(m.span), - node: match m.node { +pub fn noop_fold_method(m: P, folder: &mut T) -> SmallVector> { + SmallVector::one(m.map(|Method {id, attrs, node, span}| Method { + id: folder.new_id(id), // Needs to be first, for ast_map. + attrs: attrs.move_map(|a| folder.fold_attribute(a)), + node: match node { MethDecl(ident, - ref generics, + generics, abi, - ref explicit_self, + explicit_self, fn_style, decl, body, @@ -1044,215 +989,226 @@ pub fn noop_fold_method(m: &Method, folder: &mut T) -> SmallVector MethMac(folder.fold_mac(mac)), - } + MethMac(mac) => MethMac(folder.fold_mac(mac)), + }, + span: folder.new_span(span) + })) +} + +pub fn noop_fold_pat(p: P, folder: &mut T) -> P { + p.map(|Pat {id, node, span}| Pat { + id: folder.new_id(id), + node: match node { + PatWild(k) => PatWild(k), + PatIdent(binding_mode, pth1, sub) => { + PatIdent(binding_mode, + Spanned{span: folder.new_span(pth1.span), + node: folder.fold_ident(pth1.node)}, + sub.map(|x| folder.fold_pat(x))) + } + PatLit(e) => PatLit(folder.fold_expr(e)), + PatEnum(pth, pats) => { + PatEnum(folder.fold_path(pth), + pats.map(|pats| pats.move_map(|x| folder.fold_pat(x)))) + } + PatStruct(pth, fields, etc) => { + let pth = folder.fold_path(pth); + let fs = fields.move_map(|f| { + ast::FieldPat { + ident: f.ident, + pat: folder.fold_pat(f.pat) + } + }); + PatStruct(pth, fs, etc) + } + PatTup(elts) => PatTup(elts.move_map(|x| folder.fold_pat(x))), + PatBox(inner) => PatBox(folder.fold_pat(inner)), + PatRegion(inner) => PatRegion(folder.fold_pat(inner)), + PatRange(e1, e2) => { + PatRange(folder.fold_expr(e1), folder.fold_expr(e2)) + }, + PatVec(before, slice, after) => { + PatVec(before.move_map(|x| folder.fold_pat(x)), + slice.map(|x| folder.fold_pat(x)), + after.move_map(|x| folder.fold_pat(x))) + } + PatMac(mac) => PatMac(folder.fold_mac(mac)) + }, + span: folder.new_span(span) }) } -pub fn noop_fold_pat(p: Gc, folder: &mut T) -> Gc { - let id = folder.new_id(p.id); - let node = match p.node { - PatWild(k) => PatWild(k), - PatIdent(binding_mode, ref pth1, ref sub) => { - PatIdent(binding_mode, - Spanned{span: folder.new_span(pth1.span), - node: folder.fold_ident(pth1.node)}, - sub.map(|x| folder.fold_pat(x))) - } - PatLit(e) => PatLit(folder.fold_expr(e)), - PatEnum(ref pth, ref pats) => { - PatEnum(folder.fold_path(pth), - pats.as_ref().map(|pats| pats.iter().map(|x| folder.fold_pat(*x)).collect())) - } - PatStruct(ref pth, ref fields, etc) => { - let pth_ = folder.fold_path(pth); - let fs = fields.iter().map(|f| { - ast::FieldPat { - ident: f.ident, - pat: folder.fold_pat(f.pat) - } - }).collect(); - PatStruct(pth_, fs, etc) - } - PatTup(ref elts) => PatTup(elts.iter().map(|x| folder.fold_pat(*x)).collect()), - PatBox(inner) => PatBox(folder.fold_pat(inner)), - PatRegion(inner) => PatRegion(folder.fold_pat(inner)), - PatRange(e1, e2) => { - PatRange(folder.fold_expr(e1), folder.fold_expr(e2)) - }, - PatVec(ref before, ref slice, ref after) => { - PatVec(before.iter().map(|x| folder.fold_pat(*x)).collect(), - slice.map(|x| folder.fold_pat(x)), - after.iter().map(|x| folder.fold_pat(*x)).collect()) - } - PatMac(ref mac) => PatMac(folder.fold_mac(mac)), - }; - - box(GC) Pat { - id: id, - span: folder.new_span(p.span), - node: node, - } -} - -pub fn noop_fold_expr(e: Gc, folder: &mut T) -> Gc { - let id = folder.new_id(e.id); - let node = match e.node { - ExprBox(p, e) => { - ExprBox(folder.fold_expr(p), folder.fold_expr(e)) - } - ExprVec(ref exprs) => { - ExprVec(exprs.iter().map(|&x| folder.fold_expr(x)).collect()) - } - ExprRepeat(expr, count) => { - ExprRepeat(folder.fold_expr(expr), folder.fold_expr(count)) - } - ExprTup(ref elts) => ExprTup(elts.iter().map(|x| folder.fold_expr(*x)).collect()), - ExprCall(f, ref args) => { - ExprCall(folder.fold_expr(f), - args.iter().map(|&x| folder.fold_expr(x)).collect()) - } - ExprMethodCall(i, ref tps, ref args) => { - ExprMethodCall( - respan(i.span, folder.fold_ident(i.node)), - tps.iter().map(|&x| folder.fold_ty(x)).collect(), - args.iter().map(|&x| folder.fold_expr(x)).collect()) - } - ExprBinary(binop, lhs, rhs) => { - ExprBinary(binop, - folder.fold_expr(lhs), - folder.fold_expr(rhs)) - } - ExprUnary(binop, ohs) => { - ExprUnary(binop, folder.fold_expr(ohs)) - } - ExprLit(_) => e.node.clone(), - ExprCast(expr, ty) => { - ExprCast(folder.fold_expr(expr), folder.fold_ty(ty)) - } - ExprAddrOf(m, ohs) => ExprAddrOf(m, folder.fold_expr(ohs)), - ExprIf(cond, tr, fl) => { - ExprIf(folder.fold_expr(cond), - folder.fold_block(tr), - fl.map(|x| folder.fold_expr(x))) - } - ExprWhile(cond, body, opt_ident) => { - ExprWhile(folder.fold_expr(cond), - folder.fold_block(body), - opt_ident.map(|i| folder.fold_ident(i))) - } - ExprForLoop(pat, iter, body, ref opt_ident) => { - ExprForLoop(folder.fold_pat(pat), - folder.fold_expr(iter), - folder.fold_block(body), +pub fn noop_fold_expr(Expr {id, node, span}: Expr, folder: &mut T) -> Expr { + Expr { + id: folder.new_id(id), + node: match node { + ExprBox(p, e) => { + ExprBox(folder.fold_expr(p), folder.fold_expr(e)) + } + ExprVec(exprs) => { + ExprVec(exprs.move_map(|x| folder.fold_expr(x))) + } + ExprRepeat(expr, count) => { + ExprRepeat(folder.fold_expr(expr), folder.fold_expr(count)) + } + ExprTup(elts) => ExprTup(elts.move_map(|x| folder.fold_expr(x))), + ExprCall(f, args) => { + ExprCall(folder.fold_expr(f), + args.move_map(|x| folder.fold_expr(x))) + } + ExprMethodCall(i, tps, args) => { + ExprMethodCall( + respan(i.span, folder.fold_ident(i.node)), + tps.move_map(|x| folder.fold_ty(x)), + args.move_map(|x| folder.fold_expr(x))) + } + ExprBinary(binop, lhs, rhs) => { + ExprBinary(binop, + folder.fold_expr(lhs), + folder.fold_expr(rhs)) + } + ExprUnary(binop, ohs) => { + ExprUnary(binop, folder.fold_expr(ohs)) + } + ExprLit(l) => ExprLit(l), + ExprCast(expr, ty) => { + ExprCast(folder.fold_expr(expr), folder.fold_ty(ty)) + } + ExprAddrOf(m, ohs) => ExprAddrOf(m, folder.fold_expr(ohs)), + ExprIf(cond, tr, fl) => { + ExprIf(folder.fold_expr(cond), + folder.fold_block(tr), + fl.map(|x| folder.fold_expr(x))) + } + ExprWhile(cond, body, opt_ident) => { + ExprWhile(folder.fold_expr(cond), + folder.fold_block(body), + opt_ident.map(|i| folder.fold_ident(i))) + } + ExprForLoop(pat, iter, body, opt_ident) => { + ExprForLoop(folder.fold_pat(pat), + folder.fold_expr(iter), + folder.fold_block(body), + opt_ident.map(|i| folder.fold_ident(i))) + } + ExprLoop(body, opt_ident) => { + ExprLoop(folder.fold_block(body), opt_ident.map(|i| folder.fold_ident(i))) - } - ExprLoop(body, opt_ident) => { - ExprLoop(folder.fold_block(body), - opt_ident.map(|i| folder.fold_ident(i))) - } - ExprMatch(expr, ref arms) => { - ExprMatch(folder.fold_expr(expr), - arms.iter().map(|x| folder.fold_arm(x)).collect()) - } - ExprFnBlock(capture_clause, ref decl, ref body) => { - ExprFnBlock(capture_clause, - folder.fold_fn_decl(&**decl), - folder.fold_block(body.clone())) - } - ExprProc(ref decl, ref body) => { - ExprProc(folder.fold_fn_decl(&**decl), - folder.fold_block(body.clone())) - } - ExprUnboxedFn(capture_clause, kind, ref decl, ref body) => { - ExprUnboxedFn(capture_clause, - kind, - folder.fold_fn_decl(&**decl), - folder.fold_block(*body)) - } - ExprBlock(ref blk) => ExprBlock(folder.fold_block(*blk)), - ExprAssign(el, er) => { - ExprAssign(folder.fold_expr(el), folder.fold_expr(er)) - } - ExprAssignOp(op, el, er) => { - ExprAssignOp(op, - folder.fold_expr(el), - folder.fold_expr(er)) - } - ExprField(el, id, ref tys) => { - ExprField(folder.fold_expr(el), - respan(id.span, folder.fold_ident(id.node)), - tys.iter().map(|&x| folder.fold_ty(x)).collect()) - } - ExprTupField(el, id, ref tys) => { - ExprTupField(folder.fold_expr(el), - respan(id.span, folder.fold_uint(id.node)), - tys.iter().map(|&x| folder.fold_ty(x)).collect()) - } - ExprIndex(el, er) => { - ExprIndex(folder.fold_expr(el), folder.fold_expr(er)) - } - ExprPath(ref pth) => ExprPath(folder.fold_path(pth)), - ExprBreak(opt_ident) => ExprBreak(opt_ident.map(|x| folder.fold_ident(x))), - ExprAgain(opt_ident) => ExprAgain(opt_ident.map(|x| folder.fold_ident(x))), - ExprRet(ref e) => { - ExprRet(e.map(|x| folder.fold_expr(x))) - } - ExprInlineAsm(ref a) => { + } + ExprMatch(expr, arms) => { + ExprMatch(folder.fold_expr(expr), + arms.move_map(|x| folder.fold_arm(x))) + } + ExprFnBlock(capture_clause, decl, body) => { + ExprFnBlock(capture_clause, + folder.fold_fn_decl(decl), + folder.fold_block(body)) + } + ExprProc(decl, body) => { + ExprProc(folder.fold_fn_decl(decl), + folder.fold_block(body)) + } + ExprUnboxedFn(capture_clause, kind, decl, body) => { + ExprUnboxedFn(capture_clause, + kind, + folder.fold_fn_decl(decl), + folder.fold_block(body)) + } + ExprBlock(blk) => ExprBlock(folder.fold_block(blk)), + ExprAssign(el, er) => { + ExprAssign(folder.fold_expr(el), folder.fold_expr(er)) + } + ExprAssignOp(op, el, er) => { + ExprAssignOp(op, + folder.fold_expr(el), + folder.fold_expr(er)) + } + ExprField(el, ident, tys) => { + ExprField(folder.fold_expr(el), + respan(ident.span, folder.fold_ident(ident.node)), + tys.move_map(|x| folder.fold_ty(x))) + } + ExprTupField(el, ident, tys) => { + ExprTupField(folder.fold_expr(el), + respan(ident.span, folder.fold_uint(ident.node)), + tys.move_map(|x| folder.fold_ty(x))) + } + ExprIndex(el, er) => { + ExprIndex(folder.fold_expr(el), folder.fold_expr(er)) + } + ExprPath(pth) => ExprPath(folder.fold_path(pth)), + ExprBreak(opt_ident) => ExprBreak(opt_ident.map(|x| folder.fold_ident(x))), + ExprAgain(opt_ident) => ExprAgain(opt_ident.map(|x| folder.fold_ident(x))), + ExprRet(e) => ExprRet(e.map(|x| folder.fold_expr(x))), ExprInlineAsm(InlineAsm { - inputs: a.inputs.iter().map(|&(ref c, input)| { - ((*c).clone(), folder.fold_expr(input)) - }).collect(), - outputs: a.outputs.iter().map(|&(ref c, out, is_rw)| { - ((*c).clone(), folder.fold_expr(out), is_rw) - }).collect(), - .. (*a).clone() - }) - } - ExprMac(ref mac) => ExprMac(folder.fold_mac(mac)), - ExprStruct(ref path, ref fields, maybe_expr) => { - ExprStruct(folder.fold_path(path), - fields.iter().map(|x| folder.fold_field(*x)).collect(), - maybe_expr.map(|x| folder.fold_expr(x))) + inputs, + outputs, + asm, + asm_str_style, + clobbers, + volatile, + alignstack, + dialect + }) => ExprInlineAsm(InlineAsm { + inputs: inputs.move_map(|(c, input)| { + (c, folder.fold_expr(input)) + }), + outputs: outputs.move_map(|(c, out, is_rw)| { + (c, folder.fold_expr(out), is_rw) + }), + asm: asm, + asm_str_style: asm_str_style, + clobbers: clobbers, + volatile: volatile, + alignstack: alignstack, + dialect: dialect + }), + ExprMac(mac) => ExprMac(folder.fold_mac(mac)), + ExprStruct(path, fields, maybe_expr) => { + ExprStruct(folder.fold_path(path), + fields.move_map(|x| folder.fold_field(x)), + maybe_expr.map(|x| folder.fold_expr(x))) + }, + ExprParen(ex) => ExprParen(folder.fold_expr(ex)) }, - ExprParen(ex) => ExprParen(folder.fold_expr(ex)) - }; - - box(GC) Expr { - id: id, - node: node, - span: folder.new_span(e.span), + span: folder.new_span(span) } } -pub fn noop_fold_stmt(s: &Stmt, - folder: &mut T) -> SmallVector> { - let nodes = match s.node { +pub fn noop_fold_stmt(Spanned {node, span}: Stmt, folder: &mut T) + -> SmallVector> { + let span = folder.new_span(span); + match node { StmtDecl(d, id) => { let id = folder.new_id(id); - folder.fold_decl(d).move_iter() - .map(|d| StmtDecl(d, id)) - .collect() + folder.fold_decl(d).move_iter().map(|d| P(Spanned { + node: StmtDecl(d, id), + span: span + })).collect() } StmtExpr(e, id) => { let id = folder.new_id(id); - SmallVector::one(StmtExpr(folder.fold_expr(e), id)) + SmallVector::one(P(Spanned { + node: StmtExpr(folder.fold_expr(e), id), + span: span + })) } StmtSemi(e, id) => { let id = folder.new_id(id); - SmallVector::one(StmtSemi(folder.fold_expr(e), id)) + SmallVector::one(P(Spanned { + node: StmtSemi(folder.fold_expr(e), id), + span: span + })) } - StmtMac(ref mac, semi) => SmallVector::one(StmtMac(folder.fold_mac(mac), semi)) - }; - - nodes.move_iter().map(|node| box(GC) Spanned { - node: node, - span: folder.new_span(s.span), - }).collect() + StmtMac(mac, semi) => SmallVector::one(P(Spanned { + node: StmtMac(folder.fold_mac(mac), semi), + span: span + })) + } } #[cfg(test)] diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs index 517c5e5bf47..47aef987a63 100644 --- a/src/libsyntax/util/small_vector.rs +++ b/src/libsyntax/util/small_vector.rs @@ -12,6 +12,8 @@ use std::mem; use std::slice; use std::vec; +use fold::MoveMap; + /// A vector type optimized for cases where the size is almost always 0 or 1 pub struct SmallVector { repr: SmallVectorRepr, @@ -20,7 +22,7 @@ pub struct SmallVector { enum SmallVectorRepr { Zero, One(T), - Many(Vec ), + Many(Vec), } impl Collection for SmallVector { @@ -160,6 +162,17 @@ impl Iterator for MoveItems { } } +impl MoveMap for SmallVector { + fn move_map(self, f: |T| -> T) -> SmallVector { + let repr = match self.repr { + Zero => Zero, + One(v) => One(f(v)), + Many(vs) => Many(vs.move_map(f)) + }; + SmallVector { repr: repr } + } +} + #[cfg(test)] mod test { use super::*;