]> git.lizzy.rs Git - rust.git/commitdiff
modify last use to take into account cap clause, add new test
authorNiko Matsakis <niko@alum.mit.edu>
Sun, 8 Jan 2012 21:32:40 +0000 (13:32 -0800)
committerNiko Matsakis <niko@alum.mit.edu>
Sun, 8 Jan 2012 22:57:03 +0000 (14:57 -0800)
src/comp/middle/last_use.rs
src/comp/middle/trans_closure.rs
src/test/run-pass/cap-clause-move.rs
src/test/run-pass/task-spawn-move-and-copy.rs [new file with mode: 0644]

index f783943c0dcd5a6eb79488db79ef1f458ff2ec20..075c40ccfa5acda64788f57c498daf84a51d778e 100644 (file)
@@ -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); }
     }
index 2eb881b09e9480926d29c2c8e49bc56a99c258bb..dd343e14b4f712fb4b0b73f4df9d1301fa3da9ad 100644 (file)
@@ -9,6 +9,7 @@
 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};
     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 maybe_clone_tydesc(bcx: @block_ctxt,
         };
     }
 
-    //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 maybe_clone_tydesc(bcx: @block_ctxt,
     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) {
index 96b4b4d3aaa6365f2db76dba1f45d6c4f7f64ef4..a8cca1490faa21da2deb7ae8341b09d366923c3e 100644 (file)
@@ -1,4 +1,3 @@
-// error-pattern: warning: Captured variable 'y' not used in closure
 fn main() {
     let x = ~1;
     let y = ptr::addr_of(*x) as uint;
diff --git a/src/test/run-pass/task-spawn-move-and-copy.rs b/src/test/run-pass/task-spawn-move-and-copy.rs
new file mode 100644 (file)
index 0000000..00e86a4
--- /dev/null
@@ -0,0 +1,24 @@
+fn main() {
+    let p = comm::port::<uint>();
+    let ch = comm::chan(p);
+
+    let x = ~1;
+    let x_in_parent = ptr::addr_of(*x) as uint;
+
+    let y = ~2;
+    let y_in_parent = ptr::addr_of(*y) as uint;
+
+    task::spawn(sendfn[copy ch, y; move x]() {
+        let x_in_child = ptr::addr_of(*x) as uint;
+        comm::send(ch, x_in_child);
+
+        let y_in_child = ptr::addr_of(*y) as uint;
+        comm::send(ch, y_in_child);
+    });
+
+    let x_in_child = comm::recv(p);
+    assert x_in_parent == x_in_child;
+
+    let y_in_child = comm::recv(p);
+    assert y_in_parent != y_in_child;
+}