modify last use to take into account cap clause, add new test
This commit is contained in:
parent
106385cb91
commit
7a336f1e7c
@ -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); }
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
24
src/test/run-pass/task-spawn-move-and-copy.rs
Normal file
24
src/test/run-pass/task-spawn-move-and-copy.rs
Normal file
@ -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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user