diff options
| author | Marijn Haverbeke <marijnh@gmail.com> | 2012-01-02 10:20:58 +0100 |
|---|---|---|
| committer | Marijn Haverbeke <marijnh@gmail.com> | 2012-01-02 10:20:58 +0100 |
| commit | bd6646e698c38564b8b324ec8cf30305db6a409a (patch) | |
| tree | 6fb4068a45ed012ae42f8dc75d8d95e7115136f5 | |
| parent | 1c125d8829f38eadd62f4feef9b4f6b55b6aed7d (diff) | |
| download | rust-bd6646e698c38564b8b324ec8cf30305db6a409a.tar.gz rust-bd6646e698c38564b8b324ec8cf30305db6a409a.zip | |
Make last-use pass properly handle closed-over variables
Closes #1399
| -rw-r--r-- | src/comp/middle/last_use.rs | 21 | ||||
| -rw-r--r-- | src/test/run-pass/last-use-is-capture.rs | 8 |
2 files changed, 26 insertions, 3 deletions
diff --git a/src/comp/middle/last_use.rs b/src/comp/middle/last_use.rs index 113e9a9c299..4d1c26ddbbc 100644 --- a/src/comp/middle/last_use.rs +++ b/src/comp/middle/last_use.rs @@ -63,6 +63,13 @@ fn find_last_uses(c: @crate, def_map: resolve::def_map, ret mini_table; } +fn is_block(cx: ctx, id: node_id) -> bool { + alt ty::struct(cx.tcx, ty::node_id_to_monotype(cx.tcx, id)) { + ty::ty_fn({proto: proto_block., _}) { true } + _ { false } + } +} + fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) { alt ex.node { expr_ret(oexpr) { @@ -135,9 +142,8 @@ fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) { let arg_ts = ty::ty_fn_args(cx.tcx, ty::expr_ty(cx.tcx, f)); for arg in args { alt arg.node { - //NDM--register captured as uses - expr_fn(_, _, _, captured) { fns += [arg]; } - expr_fn_block(_, _) { fns += [arg]; } + expr_fn(proto_block., _, _, _) { fns += [arg]; } + expr_fn_block(_, _) when is_block(cx, arg.id) { fns += [arg]; } _ { alt arg_ts[i].mode { by_mut_ref. { clear_if_path(cx, arg, v, false); } @@ -163,6 +169,15 @@ fn visit_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, visit::visit_fn(fk, decl, body, sp, id, cx, v); }); } else { + alt cx.tcx.freevars.find(id) { + some(vars) { + for v in *vars { + clear_in_current(cx, ast_util::def_id_of_def(v.def).node, + false); + } + } + _ {} + } let old = nil; cx.blocks <-> old; visit::visit_fn(fk, decl, body, sp, id, cx, v); diff --git a/src/test/run-pass/last-use-is-capture.rs b/src/test/run-pass/last-use-is-capture.rs new file mode 100644 index 00000000000..1399839a1ed --- /dev/null +++ b/src/test/run-pass/last-use-is-capture.rs @@ -0,0 +1,8 @@ +// Make sure #1399 stays fixed + +fn main() { + fn invoke(f: lambda()) { f(); } + let k = ~22; + let _u = {a: k}; + invoke {||log(error, k);} +} |
