about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2011-08-03 10:19:36 +0200
committerMarijn Haverbeke <marijnh@gmail.com>2011-08-03 10:26:41 +0200
commitd08c0f0ec12d5fb238a3a9992e2da4fadcf9d1d4 (patch)
tree521b2010c06562e08e8a0a61565a533b1c14a3e2
parent948f8090ae66ea9207473bf97d5c0dfaee4244ed (diff)
downloadrust-d08c0f0ec12d5fb238a3a9992e2da4fadcf9d1d4.tar.gz
rust-d08c0f0ec12d5fb238a3a9992e2da4fadcf9d1d4.zip
Make ast::pat_bindings an iterator
And use it to get rid of some repetetive code
-rw-r--r--src/comp/middle/alias.rs27
-rw-r--r--src/comp/middle/freevars.rs7
-rw-r--r--src/comp/middle/resolve.rs13
-rw-r--r--src/comp/middle/tstate/annotate.rs4
-rw-r--r--src/comp/middle/tstate/auxiliary.rs2
-rw-r--r--src/comp/middle/tstate/collect_locals.rs2
-rw-r--r--src/comp/middle/tstate/pre_post_conditions.rs29
-rw-r--r--src/comp/middle/tstate/states.rs2
-rw-r--r--src/comp/syntax/ast.rs36
9 files changed, 48 insertions, 74 deletions
diff --git a/src/comp/middle/alias.rs b/src/comp/middle/alias.rs
index 75b3dbf658c..5d158afa6f1 100644
--- a/src/comp/middle/alias.rs
+++ b/src/comp/middle/alias.rs
@@ -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,
diff --git a/src/comp/middle/freevars.rs b/src/comp/middle/freevars.rs
index 1fbe16547e2..8cd898b5813 100644
--- a/src/comp/middle/freevars.rs
+++ b/src/comp/middle/freevars.rs
@@ -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);
diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs
index e341855978d..5aa955e7c44 100644
--- a/src/comp/middle/resolve.rs
+++ b/src/comp/middle/resolve.rs
@@ -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);
     }
 }
 
diff --git a/src/comp/middle/tstate/annotate.rs b/src/comp/middle/tstate/annotate.rs
index f0bebcfc0c5..705a2dc534c 100644
--- a/src/comp/middle/tstate/annotate.rs
+++ b/src/comp/middle/tstate/annotate.rs
@@ -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,
diff --git a/src/comp/middle/tstate/auxiliary.rs b/src/comp/middle/tstate/auxiliary.rs
index e1a01731ea1..2b08dde75c6 100644
--- a/src/comp/middle/tstate/auxiliary.rs
+++ b/src/comp/middle/tstate/auxiliary.rs
@@ -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}];
     }
diff --git a/src/comp/middle/tstate/collect_locals.rs b/src/comp/middle/tstate/collect_locals.rs
index 3f85007d0cb..c420bc0151c 100644
--- a/src/comp/middle/tstate/collect_locals.rs
+++ b/src/comp/middle/tstate/collect_locals.rs
@@ -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))];
diff --git a/src/comp/middle/tstate/pre_post_conditions.rs b/src/comp/middle/tstate/pre_post_conditions.rs
index 54e53af0ff3..473e1cfbf2b 100644
--- a/src/comp/middle/tstate/pre_post_conditions.rs
+++ b/src/comp/middle/tstate/pre_post_conditions.rs
@@ -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);
diff --git a/src/comp/middle/tstate/states.rs b/src/comp/middle/tstate/states.rs
index 66c2b4324ab..a78522fcf3d 100644
--- a/src/comp/middle/tstate/states.rs
+++ b/src/comp/middle/tstate/states.rs
@@ -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);
     }
diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs
index 5dfe6ba7463..ff8e6c0893c 100644
--- a/src/comp/syntax/ast.rs
+++ b/src/comp/syntax/ast.rs
@@ -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;
 }