correct preservation of explicit borrows like "let x = &*y;"

This commit is contained in:
Niko Matsakis 2012-05-16 06:57:52 -07:00
parent 5c8069d817
commit 63210ecddb
3 changed files with 69 additions and 3 deletions

View file

@ -1481,7 +1481,7 @@ impl preserve_methods for preserve_ctxt {
// Unsafe pointers are the user's problem
ok(())
}
cat_deref(_, derefs, gc_ptr) {
cat_deref(base, derefs, gc_ptr) {
// GC'd pointers of type @MT: always stable because we can inc
// the ref count or keep a GC root as necessary. We need to
// insert this id into the root_map, however.
@ -1489,9 +1489,9 @@ impl preserve_methods for preserve_ctxt {
some(scope_id) {
#debug["Inserting root map entry for %s: \
node %d:%u -> scope %d",
self.bccx.cmt_to_repr(cmt), cmt.id,
self.bccx.cmt_to_repr(cmt), base.id,
derefs, scope_id];
let rk = {id: cmt.id, derefs: derefs};
let rk = {id: base.id, derefs: derefs};
self.bccx.root_map.insert(rk, scope_id);
ok(())
}

View file

@ -0,0 +1,35 @@
/*
Tests that borrowing always produces a pointer confined to the
innermost scope. In this case, the variable `a` gets inferred
to the lifetime of the `if` statement because it is assigned
a borrow of `y` which takes place within the `if`.
Note: If this constraint were lifted (as I contemplated at one point),
it complicates the preservation mechanics in trans, though not
irreperably. I'm partially including this test so that if these
semantics do change we'll remember to test this scenario.
*/
fn testfn(cond: bool) {
let mut x = @3;
let mut y = @4;
let mut a = &*x;
//!^ ERROR reference is not valid outside of its lifetime
let mut exp = 3;
if cond {
a = &*y;
exp = 4;
}
x = @5;
y = @6;
assert *a == exp;
}
fn main() {
}

View file

@ -0,0 +1,31 @@
// compile-flags:--borrowck=err
// exec-env:RUST_POISON_ON_FREE=1
fn testfn(cond: bool) {
let mut x = @3;
let mut y = @4;
// borrow x and y
let mut r_x = &*x;
let mut r_y = &*y;
let mut r = r_x, exp = 3;
if cond {
r = r_y;
exp = 4;
}
#debug["*r = %d, exp = %d", *r, exp];
assert *r == exp;
x = @5;
y = @6;
#debug["*r = %d, exp = %d", *r, exp];
assert *r == exp;
}
fn main() {
testfn(true);
testfn(false);
}