about summary refs log tree commit diff
path: root/src/comp/middle
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2012-01-08 13:32:40 -0800
committerNiko Matsakis <niko@alum.mit.edu>2012-01-08 14:57:03 -0800
commit7a336f1e7c7c34bb81f80150fb3b04ec0aae14fd (patch)
tree33b955867de736e51ea4aa6e1c38a3a32e0e587c /src/comp/middle
parent106385cb9140626166a99d11451e5b4912c602c7 (diff)
modify last use to take into account cap clause, add new test
Diffstat (limited to 'src/comp/middle')
-rw-r--r--src/comp/middle/last_use.rs33
-rw-r--r--src/comp/middle/trans_closure.rs20
2 files changed, 44 insertions, 9 deletions
diff --git a/src/comp/middle/last_use.rs b/src/comp/middle/last_use.rs
index f783943c0dc..075c40ccfa5 100644
--- a/src/comp/middle/last_use.rs
+++ b/src/comp/middle/last_use.rs
@@ -136,6 +136,16 @@ fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) {
         v.visit_expr(dest, cx, v);
         clear_if_path(cx, dest, v, true);
       }
+      expr_fn(_, _, _, cap_clause) {
+        // n.b.: safe to ignore copies, as if they are unused
+        // then they are ignored, otherwise they will show up
+        // as freevars in the body.
+
+        vec::iter(cap_clause.moves) {|ci|
+            clear_def_if_path(cx, cx.def_map.get(ci.id), true);
+        }
+        visit::visit_expr(ex, cx, v);
+      }
       expr_call(f, args, _) {
         v.visit_expr(f, cx, v);
         let i = 0u, fns = [];
@@ -263,18 +273,25 @@ fn clear_in_current(cx: ctx, my_def: node_id, to: bool) {
     }
 }
 
+fn clear_def_if_path(cx: ctx, d: def, to: bool)
+    -> option<node_id> {
+    alt d {
+      def_local(def_id, let_copy.) | def_arg(def_id, by_copy.) |
+      def_arg(def_id, by_move.) {
+        clear_in_current(cx, def_id.node, to);
+        some(def_id.node)
+      }
+      _ {
+        none
+      }
+    }
+}
+
 fn clear_if_path(cx: ctx, ex: @expr, v: visit::vt<ctx>, to: bool)
     -> option::t<node_id> {
     alt ex.node {
       expr_path(_) {
-        alt cx.def_map.get(ex.id) {
-          def_local(def_id, let_copy.) | def_arg(def_id, by_copy.) |
-          def_arg(def_id, by_move.) {
-            clear_in_current(cx, def_id.node, to);
-            ret option::some(def_id.node);
-          }
-          _ {}
-        }
+        ret clear_def_if_path(cx, cx.def_map.get(ex.id), to);
       }
       _ { v.visit_expr(ex, cx, v); }
     }
diff --git a/src/comp/middle/trans_closure.rs b/src/comp/middle/trans_closure.rs
index 2eb881b09e9..dd343e14b4f 100644
--- a/src/comp/middle/trans_closure.rs
+++ b/src/comp/middle/trans_closure.rs
@@ -9,6 +9,7 @@ import middle::freevars::{get_freevars, freevar_info};
 import option::{some, none};
 import back::abi;
 import syntax::codemap::span;
+import syntax::print::pprust::expr_to_str;
 import back::link::{
     mangle_internal_name_by_path,
     mangle_internal_name_by_path_and_seq};
@@ -121,6 +122,18 @@ tag environment_value {
     env_ref(ValueRef, ty::t, lval_kind);
 }
 
+fn ev_to_str(ccx: @crate_ctxt, ev: environment_value) -> str {
+    alt ev {
+      env_expr(ex) { expr_to_str(ex) }
+      env_copy(v, t, lk) { #fmt("copy(%s,%s)", val_str(ccx.tn, v),
+                                ty_to_str(ccx.tcx, t)) }
+      env_move(v, t, lk) { #fmt("move(%s,%s)", val_str(ccx.tn, v),
+                                ty_to_str(ccx.tcx, t)) }
+      env_ref(v, t, lk) { #fmt("ref(%s,%s)", val_str(ccx.tn, v),
+                                ty_to_str(ccx.tcx, t)) }
+    }
+}
+
 fn mk_tydesc_ty(tcx: ty::ctxt, ck: ty::closure_kind) -> ty::t {
     ret alt ck {
       ty::closure_block. | ty::closure_shared. { ty::mk_type(tcx) }
@@ -284,7 +297,7 @@ fn store_environment(
         };
     }
 
-    //let ccx = bcx_ccx(bcx);
+    let ccx = bcx_ccx(bcx);
     let tcx = bcx_tcx(bcx);
 
     // compute the shape of the closure
@@ -351,6 +364,11 @@ fn store_environment(
     let {bcx: bcx, val:bindings_slot} =
         GEP_tup_like_1(bcx, cboxptr_ty, llbox, [0, abi::cbox_elt_bindings]);
     vec::iteri(bound_values) { |i, bv|
+        if (!ccx.sess.get_opts().no_asm_comments) {
+            add_comment(bcx, #fmt("Copy %s into closure",
+                                  ev_to_str(ccx, bv)));
+        }
+
         let bound_data = GEPi(bcx, bindings_slot, [0, i as int]);
         alt bv {
           env_expr(e) {