Skip to content

Commit 982e116

Browse files
committed
Issue #2633: remove last_use entries that are subject to a loan
1 parent 3e2006a commit 982e116

File tree

6 files changed

+38
-4
lines changed

6 files changed

+38
-4
lines changed

src/rustc/driver/driver.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,8 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
203203
bind middle::tstate::ck::check_crate(ty_cx, crate));
204204
let (root_map, mutbl_map) = time(
205205
time_passes, "borrow checking",
206-
bind middle::borrowck::check_crate(ty_cx, method_map, crate));
206+
bind middle::borrowck::check_crate(ty_cx, method_map,
207+
last_use_map, crate));
207208
time(time_passes, "kind checking",
208209
bind kind::check_crate(ty_cx, method_map, last_use_map, crate));
209210
time(time_passes, "lint checking",

src/rustc/middle/borrowck.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,11 @@ export check_crate, root_map, mutbl_map;
170170

171171
fn check_crate(tcx: ty::ctxt,
172172
method_map: typeck::method_map,
173+
last_use_map: liveness::last_use_map,
173174
crate: @ast::crate) -> (root_map, mutbl_map) {
174175
let bccx = @{tcx: tcx,
175176
method_map: method_map,
177+
last_use_map: last_use_map,
176178
root_map: root_map(),
177179
mutbl_map: int_hash()};
178180

@@ -186,6 +188,7 @@ fn check_crate(tcx: ty::ctxt,
186188

187189
type borrowck_ctxt = @{tcx: ty::ctxt,
188190
method_map: typeck::method_map,
191+
last_use_map: liveness::last_use_map,
189192
root_map: root_map,
190193
mutbl_map: mutbl_map};
191194

src/rustc/middle/borrowck/check_loans.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,23 @@ impl methods for check_loan_ctxt {
448448
}
449449
}
450450

451+
// Very subtle (#2633): liveness can mark options as last_use even
452+
// when there is an outstanding loan. In that case, it is not
453+
// safe to consider the use a last_use.
454+
fn check_last_use(expr: @ast::expr) {
455+
let cmt = self.bccx.cat_expr(expr);
456+
let lp = alt cmt.lp {
457+
none { ret; }
458+
some(lp) { lp }
459+
};
460+
for self.walk_loans_of(cmt.id, lp) { |_loan|
461+
#debug["Removing last use entry %? due to outstanding loan",
462+
expr.id];
463+
self.bccx.last_use_map.remove(expr.id);
464+
ret;
465+
}
466+
}
467+
451468
fn check_call(expr: @ast::expr,
452469
callee: option<@ast::expr>,
453470
callee_id: ast::node_id,
@@ -531,6 +548,10 @@ fn check_loans_in_expr(expr: @ast::expr,
531548
self.check_for_conflicting_loans(expr.id);
532549

533550
alt expr.node {
551+
ast::expr_path(*) if self.bccx.last_use_map.contains_key(expr.id) {
552+
self.check_last_use(expr);
553+
}
554+
534555
ast::expr_swap(l, r) {
535556
self.check_assignment(at_swap, l);
536557
self.check_assignment(at_swap, r);

src/rustc/middle/liveness.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ export last_use_map;
6363
// the local/argument/etc that the path refers to. However, it also
6464
// possible for the expr to be a closure, in which case the list is a
6565
// list of closed over variables that can be moved into the closure.
66+
//
67+
// Very subtle (#2633): borrowck will remove entries from this table
68+
// if it detects an outstanding loan (that is, the addr is taken).
6669
type last_use_map = hashmap<node_id, @dvec<node_id>>;
6770

6871
enum variable = uint;

src/test/run-pass/issue-2633-2.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fn a_val(&&x: ~int, +y: ~int) -> int {
2+
*x + *y
3+
}
4+
5+
fn main() {
6+
let z = ~22;
7+
a_val(z, z);
8+
}

src/test/run-pass/issue-2633.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// Currently segfaults
2-
// xfail-test
31
class cat {
42
let mut meow: fn@();
53
new() { self.meow = fn@() { #error("meow"); };}
@@ -15,4 +13,4 @@ fn nyan(kitty: cat, _kitty_info: kitty_info) {
1513
fn main() {
1614
let mut kitty = cat();
1715
nyan(kitty, {kitty: kitty});
18-
}
16+
}

0 commit comments

Comments
 (0)