提交 7a336f1e 编写于 作者: N Niko Matsakis

modify last use to take into account cap clause, add new test

上级 106385cb
......@@ -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 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 @@
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) {
......
// error-pattern: warning: Captured variable 'y' not used in closure
fn main() {
let x = ~1;
let y = ptr::addr_of(*x) as uint;
......
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;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册