Issue #2633: remove last_use entries that are subject to a loan
This commit is contained in:
parent
3e2006a570
commit
982e1166b2
@ -203,7 +203,8 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
|
||||
bind middle::tstate::ck::check_crate(ty_cx, crate));
|
||||
let (root_map, mutbl_map) = time(
|
||||
time_passes, "borrow checking",
|
||||
bind middle::borrowck::check_crate(ty_cx, method_map, crate));
|
||||
bind middle::borrowck::check_crate(ty_cx, method_map,
|
||||
last_use_map, crate));
|
||||
time(time_passes, "kind checking",
|
||||
bind kind::check_crate(ty_cx, method_map, last_use_map, crate));
|
||||
time(time_passes, "lint checking",
|
||||
|
@ -170,9 +170,11 @@ export check_crate, root_map, mutbl_map;
|
||||
|
||||
fn check_crate(tcx: ty::ctxt,
|
||||
method_map: typeck::method_map,
|
||||
last_use_map: liveness::last_use_map,
|
||||
crate: @ast::crate) -> (root_map, mutbl_map) {
|
||||
let bccx = @{tcx: tcx,
|
||||
method_map: method_map,
|
||||
last_use_map: last_use_map,
|
||||
root_map: root_map(),
|
||||
mutbl_map: int_hash()};
|
||||
|
||||
@ -186,6 +188,7 @@ fn check_crate(tcx: ty::ctxt,
|
||||
|
||||
type borrowck_ctxt = @{tcx: ty::ctxt,
|
||||
method_map: typeck::method_map,
|
||||
last_use_map: liveness::last_use_map,
|
||||
root_map: root_map,
|
||||
mutbl_map: mutbl_map};
|
||||
|
||||
|
@ -448,6 +448,23 @@ impl methods for check_loan_ctxt {
|
||||
}
|
||||
}
|
||||
|
||||
// Very subtle (#2633): liveness can mark options as last_use even
|
||||
// when there is an outstanding loan. In that case, it is not
|
||||
// safe to consider the use a last_use.
|
||||
fn check_last_use(expr: @ast::expr) {
|
||||
let cmt = self.bccx.cat_expr(expr);
|
||||
let lp = alt cmt.lp {
|
||||
none { ret; }
|
||||
some(lp) { lp }
|
||||
};
|
||||
for self.walk_loans_of(cmt.id, lp) { |_loan|
|
||||
#debug["Removing last use entry %? due to outstanding loan",
|
||||
expr.id];
|
||||
self.bccx.last_use_map.remove(expr.id);
|
||||
ret;
|
||||
}
|
||||
}
|
||||
|
||||
fn check_call(expr: @ast::expr,
|
||||
callee: option<@ast::expr>,
|
||||
callee_id: ast::node_id,
|
||||
@ -531,6 +548,10 @@ fn check_loans_in_expr(expr: @ast::expr,
|
||||
self.check_for_conflicting_loans(expr.id);
|
||||
|
||||
alt expr.node {
|
||||
ast::expr_path(*) if self.bccx.last_use_map.contains_key(expr.id) {
|
||||
self.check_last_use(expr);
|
||||
}
|
||||
|
||||
ast::expr_swap(l, r) {
|
||||
self.check_assignment(at_swap, l);
|
||||
self.check_assignment(at_swap, r);
|
||||
|
@ -63,6 +63,9 @@ export last_use_map;
|
||||
// the local/argument/etc that the path refers to. However, it also
|
||||
// possible for the expr to be a closure, in which case the list is a
|
||||
// list of closed over variables that can be moved into the closure.
|
||||
//
|
||||
// Very subtle (#2633): borrowck will remove entries from this table
|
||||
// if it detects an outstanding loan (that is, the addr is taken).
|
||||
type last_use_map = hashmap<node_id, @dvec<node_id>>;
|
||||
|
||||
enum variable = uint;
|
||||
|
8
src/test/run-pass/issue-2633-2.rs
Normal file
8
src/test/run-pass/issue-2633-2.rs
Normal file
@ -0,0 +1,8 @@
|
||||
fn a_val(&&x: ~int, +y: ~int) -> int {
|
||||
*x + *y
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let z = ~22;
|
||||
a_val(z, z);
|
||||
}
|
@ -1,5 +1,3 @@
|
||||
// Currently segfaults
|
||||
// xfail-test
|
||||
class cat {
|
||||
let mut meow: fn@();
|
||||
new() { self.meow = fn@() { #error("meow"); };}
|
||||
@ -15,4 +13,4 @@ fn nyan(kitty: cat, _kitty_info: kitty_info) {
|
||||
fn main() {
|
||||
let mut kitty = cat();
|
||||
nyan(kitty, {kitty: kitty});
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user