Fix bug in handling of block functions in last-use analysis
It would fail to start out with a fresh scope when going over a loop or block function for the second time, and thus not recognize last uses of locals defined inside the block. Closes #1818
This commit is contained in:
parent
520c3f5f79
commit
94d4dcdbf0
@ -137,7 +137,6 @@ fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) {
|
||||
// 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);
|
||||
}
|
||||
@ -203,13 +202,18 @@ fn visit_fn(fk: visit::fn_kind, decl: fn_decl, body: blk,
|
||||
fn visit_block(tp: block_type, cx: ctx, visit: fn()) {
|
||||
let local = @{type: tp, mutable second: false, mutable exits: []};
|
||||
cx.blocks = cons(local, @cx.blocks);
|
||||
let start_current = cx.current;
|
||||
visit();
|
||||
local.second = true;
|
||||
local.exits = [];
|
||||
cx.current = start_current;
|
||||
visit();
|
||||
let cx_blocks = cx.blocks;
|
||||
check is_not_empty(cx_blocks);
|
||||
cx.blocks = tail(cx_blocks);
|
||||
cx.current = join_branches(local.exits);
|
||||
let branches = if tp == func { local.exits + [cx.current] }
|
||||
else { local.exits };
|
||||
cx.current = join_branches(branches);
|
||||
}
|
||||
|
||||
fn add_block_exit(cx: ctx, tp: block_type) -> bool {
|
||||
|
16
src/test/run-pass/last-use-in-block.rs
Normal file
16
src/test/run-pass/last-use-in-block.rs
Normal file
@ -0,0 +1,16 @@
|
||||
// Issue #1818
|
||||
|
||||
fn loop<T>(s: str, f: fn(str) -> T) -> T {
|
||||
while false {
|
||||
let r = f(s);
|
||||
ret r;
|
||||
}
|
||||
fail;
|
||||
}
|
||||
|
||||
fn apply<T>(s: str, f: fn(str) -> T) -> T {
|
||||
fn g<T>(s: str, f: fn(str) -> T) -> T {f(s)}
|
||||
g(s) {|v| let r = f(v); r }
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user