rust/src/comp/syntax/fold.rs
Tim Chevalier f841e89443 Support unchecked blocks
This patch supports the syntax

    unchecked {
      ...
    }

    to disable purity checking within a block. Presumably it will only be
    used within a declared "pure fn". However, there is no checking that it
    doesn't occur elsewhere, and it would be harmless for it to do so.

    I went with Lindsey's suggestion for the syntax, but it's subject to
    change.

    This allows you to write code that uses predicates that call arbitrary
    Rust functions, but you must declare your intentions by wrapping it in
    an unchecked { ... } block. The test case run-pass/unchecked-predicates.rs
    demonstrates how to do that.
2011-08-25 18:28:23 -07:00

715 lines
26 KiB
Rust

import syntax::codemap::span;
import ast::*;
import std::vec;
import std::option;
export ast_fold_precursor;
export ast_fold;
export default_ast_fold;
export make_fold;
export dummy_out;
export noop_fold_crate;
export noop_fold_item;
export noop_fold_expr;
export noop_fold_mod;
type ast_fold = @mutable a_f;
// We may eventually want to be able to fold over type parameters, too
type ast_fold_precursor =
//unlike the others, item_ is non-trivial
{fold_crate: fn(&crate_, ast_fold) -> crate_,
fold_crate_directive:
fn(&crate_directive_, ast_fold) -> crate_directive_,
fold_view_item: fn(&view_item_, ast_fold) -> view_item_,
fold_native_item: fn(&@native_item, ast_fold) -> @native_item,
fold_item: fn(&@item, ast_fold) -> @item,
fold_item_underscore: fn(&item_, ast_fold) -> item_,
fold_method: fn(&method_, ast_fold) -> method_,
fold_block: fn(&blk_, ast_fold) -> blk_,
fold_stmt: fn(&stmt_, ast_fold) -> stmt_,
fold_arm: fn(&arm, ast_fold) -> arm,
fold_pat: fn(&pat_, ast_fold) -> pat_,
fold_decl: fn(&decl_, ast_fold) -> decl_,
fold_expr: fn(&expr_, ast_fold) -> expr_,
fold_ty: fn(&ty_, ast_fold) -> ty_,
fold_constr: fn(&ast::constr_, ast_fold) -> constr_,
fold_fn: fn(&_fn, ast_fold) -> _fn,
fold_mod: fn(&_mod, ast_fold) -> _mod,
fold_native_mod: fn(&native_mod, ast_fold) -> native_mod,
fold_variant: fn(&variant_, ast_fold) -> variant_,
fold_ident: fn(&ident, ast_fold) -> ident,
fold_path: fn(&path_, ast_fold) -> path_,
fold_local: fn(&local_, ast_fold) -> local_,
map_exprs: fn(fn(&@expr) -> @expr, [@expr]) -> [@expr],
new_id: fn(node_id) -> node_id,
new_span: fn(&span) -> span};
type a_f =
{fold_crate: fn(&crate) -> crate,
fold_crate_directive: fn(&@crate_directive) -> @crate_directive,
fold_view_item: fn(&@view_item) -> @view_item,
fold_native_item: fn(&@native_item) -> @native_item,
fold_item: fn(&@item) -> @item,
fold_item_underscore: fn(&item_) -> item_,
fold_method: fn(&@method) -> @method,
fold_block: fn(&blk) -> blk,
fold_stmt: fn(&@stmt) -> @stmt,
fold_arm: fn(&arm) -> arm,
fold_pat: fn(&@pat) -> @pat,
fold_decl: fn(&@decl) -> @decl,
fold_expr: fn(&@expr) -> @expr,
fold_ty: fn(&@ty) -> @ty,
fold_constr: fn(&@constr) -> @constr,
fold_fn: fn(&_fn) -> _fn,
fold_mod: fn(&_mod) -> _mod,
fold_native_mod: fn(&native_mod) -> native_mod,
fold_variant: fn(&variant) -> variant,
fold_ident: fn(&ident) -> ident,
fold_path: fn(&path) -> path,
fold_local: fn(&@local) -> @local,
map_exprs: fn(fn(&@expr) -> @expr, [@expr]) -> [@expr],
new_id: fn(node_id) -> node_id,
new_span: fn(&span) -> span};
//fn nf_dummy<T>(&T node) -> T { fail; }
fn nf_crate_dummy(_c: &crate) -> crate { fail; }
fn nf_crate_directive_dummy(_c: &@crate_directive) -> @crate_directive {
fail;
}
fn nf_view_item_dummy(_v: &@view_item) -> @view_item { fail; }
fn nf_native_item_dummy(_n: &@native_item) -> @native_item { fail; }
fn nf_item_dummy(_i: &@item) -> @item { fail; }
fn nf_item_underscore_dummy(_i: &item_) -> item_ { fail; }
fn nf_method_dummy(_m: &@method) -> @method { fail; }
fn nf_blk_dummy(_b: &blk) -> blk { fail; }
fn nf_stmt_dummy(_s: &@stmt) -> @stmt { fail; }
fn nf_arm_dummy(_a: &arm) -> arm { fail; }
fn nf_pat_dummy(_p: &@pat) -> @pat { fail; }
fn nf_decl_dummy(_d: &@decl) -> @decl { fail; }
fn nf_expr_dummy(_e: &@expr) -> @expr { fail; }
fn nf_ty_dummy(_t: &@ty) -> @ty { fail; }
fn nf_constr_dummy(_c: &@constr) -> @constr { fail; }
fn nf_fn_dummy(_f: &_fn) -> _fn { fail; }
fn nf_mod_dummy(_m: &_mod) -> _mod { fail; }
fn nf_native_mod_dummy(_n: &native_mod) -> native_mod { fail; }
fn nf_variant_dummy(_v: &variant) -> variant { fail; }
fn nf_ident_dummy(_i: &ident) -> ident { fail; }
fn nf_path_dummy(_p: &path) -> path { fail; }
fn nf_obj_field_dummy(_o: &obj_field) -> obj_field { fail; }
fn nf_local_dummy(_o: &@local) -> @local { fail; }
/* some little folds that probably aren't useful to have in ast_fold itself*/
//used in noop_fold_item and noop_fold_crate and noop_fold_crate_directive
fn fold_meta_item_(mi: &@meta_item, fld: ast_fold) -> @meta_item {
ret @{node:
alt mi.node {
meta_word(id) { meta_word(fld.fold_ident(id)) }
meta_list(id, mis) {
let fold_meta_item = bind fold_meta_item_(_, fld);
meta_list(id, vec::map(fold_meta_item, mis))
}
meta_name_value(id, s) {
meta_name_value(fld.fold_ident(id), s)
}
},
span: mi.span};
}
//used in noop_fold_item and noop_fold_crate
fn fold_attribute_(at: &attribute, fmi: fn(&@meta_item) -> @meta_item) ->
attribute {
ret {node: {style: at.node.style, value: *fmi(@at.node.value)},
span: at.span};
}
//used in noop_fold_native_item and noop_fold_fn
fn fold_arg_(a: &arg, fld: ast_fold) -> arg {
ret {mode: a.mode,
ty: fld.fold_ty(a.ty),
ident: fld.fold_ident(a.ident),
id: a.id};
}
//used in noop_fold_expr, and possibly elsewhere in the future
fn fold_mac_(m: &mac, fld: ast_fold) -> mac {
ret {node:
alt m.node {
mac_invoc(pth, arg, body) {
mac_invoc(fld.fold_path(pth), fld.fold_expr(arg), body)
}
mac_embed_type(ty) { mac_embed_type(fld.fold_ty(ty)) }
mac_embed_block(blk) { mac_embed_block(fld.fold_block(blk)) }
mac_ellipsis. { mac_ellipsis }
},
span: m.span};
}
fn noop_fold_crate(c: &crate_, fld: ast_fold) -> crate_ {
let fold_meta_item = bind fold_meta_item_(_, fld);
let fold_attribute = bind fold_attribute_(_, fold_meta_item);
ret {directives: vec::map(fld.fold_crate_directive, c.directives),
module: fld.fold_mod(c.module),
attrs: vec::map(fold_attribute, c.attrs),
config: vec::map(fold_meta_item, c.config)};
}
fn noop_fold_crate_directive(cd: &crate_directive_, fld: ast_fold) ->
crate_directive_ {
ret alt cd {
cdir_src_mod(id, fname, attrs) {
cdir_src_mod(fld.fold_ident(id), fname, attrs)
}
cdir_dir_mod(id, fname, cds, attrs) {
cdir_dir_mod(fld.fold_ident(id), fname,
vec::map(fld.fold_crate_directive, cds), attrs)
}
cdir_view_item(vi) { cdir_view_item(fld.fold_view_item(vi)) }
cdir_syntax(_) { cd }
cdir_auth(_, _) { cd }
}
}
fn noop_fold_view_item(vi: &view_item_, _fld: ast_fold) -> view_item_ {
ret vi;
}
fn noop_fold_native_item(ni: &@native_item, fld: ast_fold) -> @native_item {
let fold_arg = bind fold_arg_(_, fld);
let fold_meta_item = bind fold_meta_item_(_, fld);
let fold_attribute = bind fold_attribute_(_, fold_meta_item);
ret @{ident: fld.fold_ident(ni.ident),
attrs: vec::map(fold_attribute, ni.attrs),
node:
alt ni.node {
native_item_ty. { native_item_ty }
native_item_fn(st, fdec, typms) {
native_item_fn(st,
{inputs: vec::map(fold_arg, fdec.inputs),
output: fld.fold_ty(fdec.output),
purity: fdec.purity,
il: fdec.il,
cf: fdec.cf,
constraints:
vec::map(fld.fold_constr,
fdec.constraints)}, typms)
}
},
id: ni.id,
span: ni.span};
}
fn noop_fold_item(i: &@item, fld: ast_fold) -> @item {
let fold_meta_item = bind fold_meta_item_(_, fld);
let fold_attribute = bind fold_attribute_(_, fold_meta_item);
ret @{ident: fld.fold_ident(i.ident),
attrs: vec::map(fold_attribute, i.attrs),
id: i.id,
node: fld.fold_item_underscore(i.node),
span: i.span};
}
fn noop_fold_item_underscore(i: &item_, fld: ast_fold) -> item_ {
fn fold_obj_field_(of: &obj_field, fld: ast_fold) -> obj_field {
ret {mut: of.mut,
ty: fld.fold_ty(of.ty),
ident: fld.fold_ident(of.ident),
id: of.id};
}
let fold_obj_field = bind fold_obj_field_(_, fld);
ret alt i {
item_const(t, e) { item_const(fld.fold_ty(t), fld.fold_expr(e)) }
item_fn(f, typms) { item_fn(fld.fold_fn(f), typms) }
item_mod(m) { item_mod(fld.fold_mod(m)) }
item_native_mod(nm) { item_native_mod(fld.fold_native_mod(nm)) }
item_ty(t, typms) { item_ty(fld.fold_ty(t), typms) }
item_tag(variants, typms) {
item_tag(vec::map(fld.fold_variant, variants), typms)
}
item_obj(o, typms, d) {
item_obj({fields: vec::map(fold_obj_field, o.fields),
methods: vec::map(fld.fold_method, o.methods)}, typms,
d)
}
item_res(dtor, did, typms, cid) {
item_res(fld.fold_fn(dtor), did, typms, cid)
}
};
}
fn noop_fold_method(m: &method_, fld: ast_fold) -> method_ {
ret {ident: fld.fold_ident(m.ident), meth: fld.fold_fn(m.meth), id: m.id};
}
fn noop_fold_block(b: &blk_, fld: ast_fold) -> blk_ {
ret {stmts: vec::map(fld.fold_stmt, b.stmts),
expr: option::map(fld.fold_expr, b.expr),
id: b.id,
rules: b.rules};
}
fn noop_fold_stmt(s: &stmt_, fld: ast_fold) -> stmt_ {
ret alt s {
stmt_decl(d, nid) { stmt_decl(fld.fold_decl(d), nid) }
stmt_expr(e, nid) { stmt_expr(fld.fold_expr(e), nid) }
stmt_crate_directive(cd) {
stmt_crate_directive(fld.fold_crate_directive(cd))
}
};
}
fn noop_fold_arm(a: &arm, fld: ast_fold) -> arm {
ret {pats: vec::map(fld.fold_pat, a.pats),
guard: option::map(fld.fold_expr, a.guard),
body: fld.fold_block(a.body)};
}
fn noop_fold_pat(p: &pat_, fld: ast_fold) -> pat_ {
ret alt p {
pat_wild. { p }
pat_bind(ident) { pat_bind(fld.fold_ident(ident)) }
pat_lit(_) { p }
pat_tag(pth, pats) {
pat_tag(fld.fold_path(pth), vec::map(fld.fold_pat, pats))
}
pat_rec(fields, etc) {
let fs = [];
for f: ast::field_pat in fields {
fs += [{ident: f.ident, pat: fld.fold_pat(f.pat)}];
}
pat_rec(fs, etc)
}
pat_tup(elts) { pat_tup(vec::map(fld.fold_pat, elts)) }
pat_box(inner) { pat_box(fld.fold_pat(inner)) }
};
}
fn noop_fold_decl(d: &decl_, fld: ast_fold) -> decl_ {
ret alt d {
decl_local(ls) { decl_local(vec::map(fld.fold_local, ls)) }
decl_item(it) { decl_item(fld.fold_item(it)) }
}
}
fn noop_fold_expr(e: &expr_, fld: ast_fold) -> expr_ {
fn fold_field_(field: &field, fld: ast_fold) -> field {
ret {node:
{mut: field.node.mut,
ident: fld.fold_ident(field.node.ident),
expr: fld.fold_expr(field.node.expr)},
span: field.span};
}
let fold_field = bind fold_field_(_, fld);
fn fold_anon_obj_(ao: &anon_obj, fld: ast_fold) -> anon_obj {
fn fold_anon_obj_field_(aof: &anon_obj_field, fld: ast_fold) ->
anon_obj_field {
ret {mut: aof.mut,
ty: fld.fold_ty(aof.ty),
expr: fld.fold_expr(aof.expr),
ident: fld.fold_ident(aof.ident),
id: aof.id};
}
let fold_anon_obj_field = bind fold_anon_obj_field_(_, fld);
ret {fields:
alt ao.fields {
option::none. { ao.fields }
option::some(v) {
option::some(vec::map(fold_anon_obj_field, v))
}
},
methods: vec::map(fld.fold_method, ao.methods),
inner_obj: option::map(fld.fold_expr, ao.inner_obj)}
}
let fold_anon_obj = bind fold_anon_obj_(_, fld);
let fold_mac = bind fold_mac_(_, fld);
ret alt e {
expr_vec(exprs, mut) {
expr_vec(fld.map_exprs(fld.fold_expr, exprs), mut)
}
expr_rec(fields, maybe_expr) {
expr_rec(vec::map(fold_field, fields),
option::map(fld.fold_expr, maybe_expr))
}
expr_tup(elts) { expr_tup(vec::map(fld.fold_expr, elts)) }
expr_call(f, args) {
expr_call(fld.fold_expr(f), fld.map_exprs(fld.fold_expr, args))
}
expr_self_method(id) { expr_self_method(fld.fold_ident(id)) }
expr_bind(f, args) {
let opt_map_se = bind option::map(fld.fold_expr, _);
expr_bind(fld.fold_expr(f), vec::map(opt_map_se, args))
}
expr_binary(binop, lhs, rhs) {
expr_binary(binop, fld.fold_expr(lhs), fld.fold_expr(rhs))
}
expr_unary(binop, ohs) { expr_unary(binop, fld.fold_expr(ohs)) }
expr_lit(_) { e }
expr_cast(expr, ty) { expr_cast(fld.fold_expr(expr), ty) }
expr_if(cond, tr, fl) {
expr_if(fld.fold_expr(cond), fld.fold_block(tr),
option::map(fld.fold_expr, fl))
}
expr_ternary(cond, tr, fl) {
expr_ternary(fld.fold_expr(cond), fld.fold_expr(tr),
fld.fold_expr(fl))
}
expr_while(cond, body) {
expr_while(fld.fold_expr(cond), fld.fold_block(body))
}
expr_for(decl, expr, blk) {
expr_for(fld.fold_local(decl), fld.fold_expr(expr),
fld.fold_block(blk))
}
expr_for_each(decl, expr, blk) {
expr_for_each(fld.fold_local(decl), fld.fold_expr(expr),
fld.fold_block(blk))
}
expr_do_while(blk, expr) {
expr_do_while(fld.fold_block(blk), fld.fold_expr(expr))
}
expr_alt(expr, arms) {
expr_alt(fld.fold_expr(expr), vec::map(fld.fold_arm, arms))
}
expr_fn(f) { expr_fn(fld.fold_fn(f)) }
expr_block(blk) { expr_block(fld.fold_block(blk)) }
expr_move(el, er) {
expr_move(fld.fold_expr(el), fld.fold_expr(er))
}
expr_copy(e) { expr_copy(fld.fold_expr(e)) }
expr_assign(el, er) {
expr_assign(fld.fold_expr(el), fld.fold_expr(er))
}
expr_swap(el, er) {
expr_swap(fld.fold_expr(el), fld.fold_expr(er))
}
expr_assign_op(op, el, er) {
expr_assign_op(op, fld.fold_expr(el), fld.fold_expr(er))
}
expr_field(el, id) {
expr_field(fld.fold_expr(el), fld.fold_ident(id))
}
expr_index(el, er) {
expr_index(fld.fold_expr(el), fld.fold_expr(er))
}
expr_path(pth) { expr_path(fld.fold_path(pth)) }
expr_fail(e) { expr_fail(option::map(fld.fold_expr, e)) }
expr_break. { e }
expr_cont. { e }
expr_ret(e) { expr_ret(option::map(fld.fold_expr, e)) }
expr_put(e) { expr_put(option::map(fld.fold_expr, e)) }
expr_be(e) { expr_be(fld.fold_expr(e)) }
expr_log(lv, e) { expr_log(lv, fld.fold_expr(e)) }
expr_assert(e) { expr_assert(fld.fold_expr(e)) }
expr_check(m, e) { expr_check(m, fld.fold_expr(e)) }
expr_if_check(cond, tr, fl) {
expr_if_check(fld.fold_expr(cond), fld.fold_block(tr),
option::map(fld.fold_expr, fl))
}
expr_anon_obj(ao) { expr_anon_obj(fold_anon_obj(ao)) }
expr_mac(mac) { expr_mac(fold_mac(mac)) }
expr_uniq(e) { expr_uniq(fld.fold_expr(e)) }
}
}
fn noop_fold_ty(t: &ty_, _fld: ast_fold) -> ty_ {
//drop in ty::fold_ty here if necessary
ret t;
}
fn noop_fold_constr(c: &constr_, fld: ast_fold) -> constr_ {
{path: fld.fold_path(c.path), args: c.args, id: c.id}
}
// functions just don't get spans, for some reason
fn noop_fold_fn(f: &_fn, fld: ast_fold) -> _fn {
let fold_arg = bind fold_arg_(_, fld);
ret {decl:
{inputs: vec::map(fold_arg, f.decl.inputs),
output: fld.fold_ty(f.decl.output),
purity: f.decl.purity,
il: f.decl.il,
cf: f.decl.cf,
constraints: vec::map(fld.fold_constr, f.decl.constraints)},
proto: f.proto,
body: fld.fold_block(f.body)};
}
// ...nor do modules
fn noop_fold_mod(m: &_mod, fld: ast_fold) -> _mod {
ret {view_items: vec::map(fld.fold_view_item, m.view_items),
items: vec::map(fld.fold_item, m.items)};
}
fn noop_fold_native_mod(nm: &native_mod, fld: ast_fold) -> native_mod {
ret {native_name: nm.native_name,
abi: nm.abi,
view_items: vec::map(fld.fold_view_item, nm.view_items),
items: vec::map(fld.fold_native_item, nm.items)}
}
fn noop_fold_variant(v: &variant_, fld: ast_fold) -> variant_ {
fn fold_variant_arg_(va: &variant_arg, fld: ast_fold) -> variant_arg {
ret {ty: fld.fold_ty(va.ty), id: va.id};
}
let fold_variant_arg = bind fold_variant_arg_(_, fld);
ret {name: v.name, args: vec::map(fold_variant_arg, v.args), id: v.id};
}
fn noop_fold_ident(i: &ident, _fld: ast_fold) -> ident { ret i; }
fn noop_fold_path(p: &path_, fld: ast_fold) -> path_ {
ret {global: p.global,
idents: vec::map(fld.fold_ident, p.idents),
types: vec::map(fld.fold_ty, p.types)};
}
fn noop_fold_local(l: &local_, fld: ast_fold) -> local_ {
ret {ty: fld.fold_ty(l.ty),
pat: fld.fold_pat(l.pat),
init:
alt l.init {
option::none::<initializer>. { l.init }
option::some::<initializer>(init) {
option::some::<initializer>({op: init.op,
expr: fld.fold_expr(init.expr)})
}
},
id: l.id};
}
/* temporarily eta-expand because of a compiler bug with using `fn<T>` as a
value */
fn noop_map_exprs(f: fn(&@expr) -> @expr, es: [@expr]) -> [@expr] {
ret vec::map(f, es);
}
fn noop_id(i: node_id) -> node_id { ret i; }
fn noop_span(sp: &span) -> span { ret sp; }
fn default_ast_fold() -> @ast_fold_precursor {
ret @{fold_crate: noop_fold_crate,
fold_crate_directive: noop_fold_crate_directive,
fold_view_item: noop_fold_view_item,
fold_native_item: noop_fold_native_item,
fold_item: noop_fold_item,
fold_item_underscore: noop_fold_item_underscore,
fold_method: noop_fold_method,
fold_block: noop_fold_block,
fold_stmt: noop_fold_stmt,
fold_arm: noop_fold_arm,
fold_pat: noop_fold_pat,
fold_decl: noop_fold_decl,
fold_expr: noop_fold_expr,
fold_ty: noop_fold_ty,
fold_constr: noop_fold_constr,
fold_fn: noop_fold_fn,
fold_mod: noop_fold_mod,
fold_native_mod: noop_fold_native_mod,
fold_variant: noop_fold_variant,
fold_ident: noop_fold_ident,
fold_path: noop_fold_path,
fold_local: noop_fold_local,
map_exprs: noop_map_exprs,
new_id: noop_id,
new_span: noop_span};
}
fn dummy_out(a: ast_fold) {
*a =
{fold_crate: nf_crate_dummy,
fold_crate_directive: nf_crate_directive_dummy,
fold_view_item: nf_view_item_dummy,
fold_native_item: nf_native_item_dummy,
fold_item: nf_item_dummy,
fold_item_underscore: nf_item_underscore_dummy,
fold_method: nf_method_dummy,
fold_block: nf_blk_dummy,
fold_stmt: nf_stmt_dummy,
fold_arm: nf_arm_dummy,
fold_pat: nf_pat_dummy,
fold_decl: nf_decl_dummy,
fold_expr: nf_expr_dummy,
fold_ty: nf_ty_dummy,
fold_constr: nf_constr_dummy,
fold_fn: nf_fn_dummy,
fold_mod: nf_mod_dummy,
fold_native_mod: nf_native_mod_dummy,
fold_variant: nf_variant_dummy,
fold_ident: nf_ident_dummy,
fold_path: nf_path_dummy,
fold_local: nf_local_dummy,
map_exprs: noop_map_exprs,
new_id: noop_id,
new_span: noop_span};
}
fn make_fold(afp: &ast_fold_precursor) -> ast_fold {
let result: ast_fold =
@mutable {fold_crate: nf_crate_dummy,
fold_crate_directive: nf_crate_directive_dummy,
fold_view_item: nf_view_item_dummy,
fold_native_item: nf_native_item_dummy,
fold_item: nf_item_dummy,
fold_item_underscore: nf_item_underscore_dummy,
fold_method: nf_method_dummy,
fold_block: nf_blk_dummy,
fold_stmt: nf_stmt_dummy,
fold_arm: nf_arm_dummy,
fold_pat: nf_pat_dummy,
fold_decl: nf_decl_dummy,
fold_expr: nf_expr_dummy,
fold_ty: nf_ty_dummy,
fold_constr: nf_constr_dummy,
fold_fn: nf_fn_dummy,
fold_mod: nf_mod_dummy,
fold_native_mod: nf_native_mod_dummy,
fold_variant: nf_variant_dummy,
fold_ident: nf_ident_dummy,
fold_path: nf_path_dummy,
fold_local: nf_local_dummy,
map_exprs: noop_map_exprs,
new_id: noop_id,
new_span: noop_span};
/* naturally, a macro to write these would be nice */
fn f_crate(afp: &ast_fold_precursor, f: ast_fold, c: &crate) -> crate {
ret {node: afp.fold_crate(c.node, f), span: afp.new_span(c.span)};
}
fn f_crate_directive(afp: &ast_fold_precursor, f: ast_fold,
c: &@crate_directive) -> @crate_directive {
ret @{node: afp.fold_crate_directive(c.node, f),
span: afp.new_span(c.span)};
}
fn f_view_item(afp: &ast_fold_precursor, f: ast_fold, x: &@view_item) ->
@view_item {
ret @{node: afp.fold_view_item(x.node, f),
span: afp.new_span(x.span)};
}
fn f_native_item(afp: &ast_fold_precursor, f: ast_fold, x: &@native_item)
-> @native_item {
ret afp.fold_native_item(x, f);
}
fn f_item(afp: &ast_fold_precursor, f: ast_fold, i: &@item) -> @item {
ret afp.fold_item(i, f);
}
fn f_item_underscore(afp: &ast_fold_precursor, f: ast_fold, i: &item_) ->
item_ {
ret afp.fold_item_underscore(i, f);
}
fn f_method(afp: &ast_fold_precursor, f: ast_fold, x: &@method) ->
@method {
ret @{node: afp.fold_method(x.node, f), span: afp.new_span(x.span)};
}
fn f_block(afp: &ast_fold_precursor, f: ast_fold, x: &blk) -> blk {
ret {node: afp.fold_block(x.node, f), span: afp.new_span(x.span)};
}
fn f_stmt(afp: &ast_fold_precursor, f: ast_fold, x: &@stmt) -> @stmt {
ret @{node: afp.fold_stmt(x.node, f), span: afp.new_span(x.span)};
}
fn f_arm(afp: &ast_fold_precursor, f: ast_fold, x: &arm) -> arm {
ret afp.fold_arm(x, f);
}
fn f_pat(afp: &ast_fold_precursor, f: ast_fold, x: &@pat) -> @pat {
ret @{id: afp.new_id(x.id),
node: afp.fold_pat(x.node, f),
span: afp.new_span(x.span)};
}
fn f_decl(afp: &ast_fold_precursor, f: ast_fold, x: &@decl) -> @decl {
ret @{node: afp.fold_decl(x.node, f), span: afp.new_span(x.span)};
}
fn f_expr(afp: &ast_fold_precursor, f: ast_fold, x: &@expr) -> @expr {
ret @{id: afp.new_id(x.id),
node: afp.fold_expr(x.node, f),
span: afp.new_span(x.span)};
}
fn f_ty(afp: &ast_fold_precursor, f: ast_fold, x: &@ty) -> @ty {
ret @{node: afp.fold_ty(x.node, f), span: afp.new_span(x.span)};
}
fn f_constr(afp: &ast_fold_precursor, f: ast_fold, x: &@ast::constr) ->
@ast::constr {
ret @{node: afp.fold_constr(x.node, f), span: afp.new_span(x.span)};
}
fn f_fn(afp: &ast_fold_precursor, f: ast_fold, x: &_fn) -> _fn {
ret afp.fold_fn(x, f);
}
fn f_mod(afp: &ast_fold_precursor, f: ast_fold, x: &_mod) -> _mod {
ret afp.fold_mod(x, f);
}
fn f_native_mod(afp: &ast_fold_precursor, f: ast_fold, x: &native_mod) ->
native_mod {
ret afp.fold_native_mod(x, f);
}
fn f_variant(afp: &ast_fold_precursor, f: ast_fold, x: &variant) ->
variant {
ret {node: afp.fold_variant(x.node, f), span: afp.new_span(x.span)};
}
fn f_ident(afp: &ast_fold_precursor, f: ast_fold, x: &ident) -> ident {
ret afp.fold_ident(x, f);
}
fn f_path(afp: &ast_fold_precursor, f: ast_fold, x: &path) -> path {
ret {node: afp.fold_path(x.node, f), span: afp.new_span(x.span)};
}
fn f_local(afp: &ast_fold_precursor, f: ast_fold, x: &@local) -> @local {
ret @{node: afp.fold_local(x.node, f), span: afp.new_span(x.span)};
}
*result =
{fold_crate: bind f_crate(afp, result, _),
fold_crate_directive: bind f_crate_directive(afp, result, _),
fold_view_item: bind f_view_item(afp, result, _),
fold_native_item: bind f_native_item(afp, result, _),
fold_item: bind f_item(afp, result, _),
fold_item_underscore: bind f_item_underscore(afp, result, _),
fold_method: bind f_method(afp, result, _),
fold_block: bind f_block(afp, result, _),
fold_stmt: bind f_stmt(afp, result, _),
fold_arm: bind f_arm(afp, result, _),
fold_pat: bind f_pat(afp, result, _),
fold_decl: bind f_decl(afp, result, _),
fold_expr: bind f_expr(afp, result, _),
fold_ty: bind f_ty(afp, result, _),
fold_constr: bind f_constr(afp, result, _),
fold_fn: bind f_fn(afp, result, _),
fold_mod: bind f_mod(afp, result, _),
fold_native_mod: bind f_native_mod(afp, result, _),
fold_variant: bind f_variant(afp, result, _),
fold_ident: bind f_ident(afp, result, _),
fold_path: bind f_path(afp, result, _),
fold_local: bind f_local(afp, result, _),
map_exprs: afp.map_exprs,
new_id: afp.new_id,
new_span: afp.new_span};
ret result;
}
//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//