Make ast::pat_bindings an iterator

And use it to get rid of some repetetive code
This commit is contained in:
Marijn Haverbeke 2011-08-03 10:19:36 +02:00
parent 948f8090ae
commit d08c0f0ec1
9 changed files with 48 additions and 74 deletions

View file

@ -310,22 +310,7 @@ fn check_alt(cx: &ctx, input: &@ast::expr, arms: &ast::arm[], sc: &scope,
}
fn arm_defnums(arm: &ast::arm) -> node_id[] {
let dnums = ~[];
fn walk_pat(found: &mutable node_id[], p: &@ast::pat) {
alt p.node {
ast::pat_bind(_) { found += ~[p.id]; }
ast::pat_tag(_, children) {
for child: @ast::pat in children { walk_pat(found, child); }
}
ast::pat_rec(fields, _) {
for f: ast::field_pat in fields { walk_pat(found, f.pat); }
}
ast::pat_box(inner) { walk_pat(found, inner); }
_ { }
}
}
walk_pat(dnums, arm.pats.(0));
ret dnums;
ret ast::pat_binding_ids(arm.pats.(0));
}
fn check_for_each(cx: &ctx, local: &@ast::local, call: &@ast::expr,
@ -334,10 +319,7 @@ fn check_for_each(cx: &ctx, local: &@ast::local, call: &@ast::expr,
alt call.node {
ast::expr_call(f, args) {
let data = check_call(cx, f, args, sc);
let bindings = ~[];
for p: @ast::pat in ast::pat_bindings(local.node.pat) {
bindings += ~[p.id];
}
let bindings = ast::pat_binding_ids(local.node.pat);
let new_sc = @{root_vars: data.root_vars,
block_defnum: bindings.(ivec::len(bindings) - 1u),
bindings: bindings,
@ -370,10 +352,7 @@ fn check_for(cx: &ctx, local: &@ast::local, seq: &@ast::expr, blk: &ast::blk,
util::ppaux::ty_to_str(cx.tcx, seq_t));
}
}
let bindings = ~[];
for p: @ast::pat in ast::pat_bindings(local.node.pat) {
bindings += ~[p.id];
}
let bindings = ast::pat_binding_ids(local.node.pat);
let new_sc = @{root_vars: root_def,
block_defnum: bindings.(ivec::len(bindings) - 1u),
bindings: bindings,

View file

@ -69,7 +69,7 @@ fn collect_freevars(def_map: &resolve::def_map, sess: &session::session,
}
}
fn walk_local(e: env, local: &@ast::local) {
for b: @ast::pat in ast::pat_bindings(local.node.pat) {
for each b: @ast::pat in ast::pat_bindings(local.node.pat) {
set_add(e.decls, b.id);
}
}
@ -133,10 +133,7 @@ fn annotate_freevars(sess: &session::session, def_map: &resolve::def_map,
fn start_walk(b: &ast::blk, v: &visit::vt[()]) {
v.visit_block(b, (), v);
}
let bound = ~[];
for b: @ast::pat in ast::pat_bindings(local.node.pat){
bound += ~[b.id];
}
let bound = ast::pat_binding_ids(local.node.pat);
let vars =
collect_freevars(e.def_map, e.sess, bind start_walk(body, _),
bound);

View file

@ -1241,16 +1241,9 @@ fn check_item(e: &@env, i: &@ast::item, x: &(), v: &vt[()]) {
}
fn check_pat(ch: checker, p: &@ast::pat) {
alt p.node {
ast::pat_bind(name) { add_name(ch, p.span, name); }
ast::pat_tag(_, children) {
for child: @ast::pat in children { check_pat(ch, child); }
}
ast::pat_rec(fields, _) {
for f: ast::field_pat in fields { check_pat(ch, f.pat); }
}
ast::pat_box(inner) { check_pat(ch, inner); }
_ { }
for each p in ast::pat_bindings(p) {
let ident = alt p.node { pat_bind(n) { n } };
add_name(ch, p.span, ident);
}
}

View file

@ -44,9 +44,7 @@ fn collect_ids_stmt(s: &@stmt, rs: @mutable node_id[]) {
}
fn collect_ids_local(l: &@local, rs: @mutable node_id[]) {
for p: @pat in pat_bindings(l.node.pat) {
*rs += ~[p.id];
}
*rs += pat_binding_ids(l.node.pat);
}
fn node_ids_in_fn(f: &_fn, tps: &ty_param[], sp: &span, i: &fn_ident,

View file

@ -1081,7 +1081,7 @@ type binding = {lhs: inst[], rhs: option::t[initializer]};
fn local_to_bindings(loc : &@local) -> binding {
let lhs = ~[];
for p: @pat in pat_bindings(loc.node.pat) {
for each p: @pat in pat_bindings(loc.node.pat) {
let ident = alt p.node { pat_bind(name) { name } };
lhs += ~[{ident: ident, node: p.id}];
}

View file

@ -14,7 +14,7 @@ import syntax::ast::respan;
type ctxt = {cs: @mutable sp_constr[], tcx: ty::ctxt};
fn collect_local(loc: &@local, cx: &ctxt, v: &visit::vt[ctxt]) {
for p: @pat in pat_bindings(loc.node.pat) {
for each p: @pat in pat_bindings(loc.node.pat) {
let ident = alt p.node { pat_bind(id) { id } };
log "collect_local: pushing " + ident;
*cx.cs += ~[respan(loc.span, ninit(p.id, ident))];

View file

@ -136,7 +136,7 @@ fn find_pre_post_loop(fcx: &fn_ctxt, l: &@local, index: &@expr, body: &blk,
id: node_id) {
find_pre_post_expr(fcx, index);
find_pre_post_block(fcx, body);
for p: @pat in pat_bindings(l.node.pat) {
for each p: @pat in pat_bindings(l.node.pat) {
let ident = alt p.node { pat_bind(id) { id } };
let v_init = ninit(p.id, ident);
relax_precond_block(fcx, bit_num(fcx, v_init) as node_id, body);
@ -578,37 +578,38 @@ fn find_pre_post_stmt(fcx: &fn_ctxt, s: &stmt) {
alt adecl.node {
decl_local(alocals) {
for alocal: @local in alocals {
let bindings = pat_bindings(alocal.node.pat);
alt alocal.node.init {
some(an_init) {
/* LHS always becomes initialized,
whether or not this is a move */
find_pre_post_expr(fcx, an_init.expr);
for p: @pat in bindings {
for each p: @pat in pat_bindings(alocal.node.pat) {
copy_pre_post(fcx.ccx, p.id, an_init.expr);
}
/* Inherit ann from initializer, and add var being
initialized to the postcondition */
copy_pre_post(fcx.ccx, id, an_init.expr);
let p = none;
alt an_init.expr.node {
expr_path(p) {
for pat: @pat in bindings {
let ident = alt pat.node { pat_bind(n) { n } };
expr_path(_p) { p = some(_p); }
_ { }
}
for each pat: @pat in pat_bindings(alocal.node.pat) {
let ident = alt pat.node { pat_bind(n) { n } };
alt p {
some(p) {
copy_in_postcond(fcx, id,
{ident: ident, node: pat.id},
{ident:
path_to_ident(fcx.ccx.tcx, p),
node: an_init.expr.id},
op_to_oper_ty(an_init.op));
}
none. {}
}
}
_ { }
}
for p: @pat in bindings {
let ident = alt p.node { pat_bind(name) { name } };
gen(fcx, id, ninit(p.id, ident));
gen(fcx, id, ninit(pat.id, ident));
}
if an_init.op == init_move && is_path(an_init.expr) {
@ -616,7 +617,7 @@ fn find_pre_post_stmt(fcx: &fn_ctxt, s: &stmt) {
}
}
none. {
for p: @pat in bindings {
for each p: @pat in pat_bindings(alocal.node.pat) {
clear_pp(node_id_to_ts_ann(fcx.ccx, p.id).conditions);
}
clear_pp(node_id_to_ts_ann(fcx.ccx, id).conditions);

View file

@ -195,7 +195,7 @@ fn find_pre_post_state_loop(fcx: &fn_ctxt, pres: prestate, l: &@local,
// Make sure the index vars are considered initialized
// in the body
let index_post = tritv_clone(expr_poststate(fcx.ccx, index));
for p: @pat in pat_bindings(l.node.pat) {
for each p: @pat in pat_bindings(l.node.pat) {
let ident = alt p.node { pat_bind(name) { name } };
set_in_poststate_ident(fcx, p.id, ident, index_post);
}

View file

@ -154,23 +154,29 @@ fn pat_id_map(pat: &@pat) -> pat_id_map {
ret map;
}
// FIXME This wanted to be an iter, but bug #791 got in the way.
fn pat_bindings(pat: &@pat) -> (@pat)[] {
let found = ~[];
fn recur(found: &mutable (@pat)[], pat: &@pat) {
alt pat.node {
pat_bind(_) { found += ~[pat]; }
pat_tag(_, sub) {
for p in sub { recur(found, p); }
}
pat_rec(fields, _) {
for f: field_pat in fields { recur(found, f.pat); }
}
pat_box(sub) { recur(found, sub); }
pat_wild. | pat_lit(_) {}
iter pat_bindings(pat: &@pat) -> @pat {
alt pat.node {
pat_bind(_) { put pat; }
pat_tag(_, sub) {
for p in sub {
for each b in pat_bindings(p) { put b; }
}
}
pat_rec(fields, _) {
for f in fields {
for each b in pat_bindings(f.pat) { put b; }
}
}
pat_box(sub) {
for each b in pat_bindings(sub) { put b; }
}
pat_wild. | pat_lit(_) {}
}
recur(found, pat);
}
fn pat_binding_ids(pat: &@pat) -> node_id[] {
let found = ~[];
for each b in pat_bindings(pat) { found += ~[b.id]; }
ret found;
}