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 = [];
}
}
+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); }
}
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) }
};
}
- //let ccx = bcx_ccx(bcx);
+ let ccx = bcx_ccx(bcx);
let tcx = bcx_tcx(bcx);
// compute the shape of the closure
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) {
-// error-pattern: warning: Captured variable 'y' not used in closure
fn main() {
let x = ~1;
let y = ptr::addr_of(*x) as uint;
--- /dev/null
+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;
+}