提交 982e1166 编写于 作者: N Niko Matsakis

Issue #2633: remove last_use entries that are subject to a loan

上级 3e2006a5
......@@ -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 @@
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 @@ fn check_move_out_from_cmt(cmt: cmt) {
}
}
// 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 @@
// 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;
......
fn a_val(&&x: ~int, +y: ~int) -> int {
*x + *y
}
fn main() {
let z = ~22;
a_val(z, z);
}
// 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});
}
\ No newline at end of file
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册