Skip to content

Commit 3607c7a

Browse files
author
Cameron Zwarich
committed
Implement RFC #43
Remove the ability of the borrow checker to determine that repeated dereferences of a Box<T> refer to the same memory object. This will usually require one of two workarounds: 1) The interior of a Box<T> will sometimes need to be moved / borrowed into a temporary before moving / borrowing individual derived paths. 2) A `ref x` pattern will have to be replaced with a `box ref x` pattern. Fixes #16094. [breaking-change]
1 parent 8c4dbf3 commit 3607c7a

File tree

3 files changed

+13
-8
lines changed

3 files changed

+13
-8
lines changed

src/librustc/middle/borrowck/check_loans.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ impl<'a> CheckLoanCtxt<'a> {
261261
// let x = &mut a.b.c; // Restricts a, a.b, and a.b.c
262262
// let y = a; // Conflicts with restriction
263263

264+
let loan_path = owned_ptr_base_path(loan_path);
264265
let cont = self.each_in_scope_loan(scope_id, |loan| {
265266
let mut ret = true;
266267
for restr_path in loan.restricted_paths.iter() {
@@ -395,8 +396,9 @@ impl<'a> CheckLoanCtxt<'a> {
395396
return true;
396397
}
397398

399+
let loan2_base_path = owned_ptr_base_path_rc(&loan2.loan_path);
398400
for restr_path in loan1.restricted_paths.iter() {
399-
if *restr_path != loan2.loan_path { continue; }
401+
if *restr_path != loan2_base_path { continue; }
400402

401403
let old_pronoun = if new_loan.loan_path == old_loan.loan_path {
402404
"it".to_string()
@@ -648,7 +650,8 @@ impl<'a> CheckLoanCtxt<'a> {
648650

649651
debug!("check_if_path_is_moved(id={:?}, use_kind={:?}, lp={})",
650652
id, use_kind, lp.repr(self.bccx.tcx));
651-
self.move_data.each_move_of(id, lp, |move, moved_lp| {
653+
let base_lp = owned_ptr_base_path_rc(lp);
654+
self.move_data.each_move_of(id, &base_lp, |move, moved_lp| {
652655
self.bccx.report_use_of_moved_value(
653656
span,
654657
use_kind,

src/test/compile-fail/borrowck-borrow-from-owned-ptr.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -52,14 +52,15 @@ fn borrow_same_field_twice_imm_imm() {
5252
fn borrow_both_fields_mut() {
5353
let mut foo = make_foo();
5454
let bar1 = &mut foo.bar1;
55-
let _bar2 = &mut foo.bar2;
55+
let _bar2 = &mut foo.bar2; //~ ERROR cannot borrow
5656
*bar1;
5757
}
5858

5959
fn borrow_both_mut_pattern() {
6060
let mut foo = make_foo();
6161
match *foo {
6262
Foo { bar1: ref mut _bar1, bar2: ref mut _bar2 } => {}
63+
//~^ ERROR cannot borrow
6364
}
6465
}
6566

@@ -120,7 +121,7 @@ fn borrow_imm_and_base_imm() {
120121
fn borrow_mut_and_imm() {
121122
let mut foo = make_foo();
122123
let bar1 = &mut foo.bar1;
123-
let _foo1 = &foo.bar2;
124+
let _foo1 = &foo.bar2; //~ ERROR cannot borrow
124125
*bar1;
125126
}
126127

@@ -133,7 +134,7 @@ fn borrow_mut_from_imm() {
133134
fn borrow_long_path_both_mut() {
134135
let mut foo = make_foo();
135136
let bar1 = &mut foo.bar1.int1;
136-
let foo1 = &mut foo.bar2.int2;
137+
let foo1 = &mut foo.bar2.int2; //~ ERROR cannot borrow
137138
*bar1;
138139
*foo1;
139140
}

src/test/run-pass/match-implicit-copy-unique.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ struct Pair { a: Box<int>, b: Box<int> }
1313

1414
pub fn main() {
1515
let mut x = box Pair {a: box 10, b: box 20};
16-
match x {
17-
box Pair {a: ref mut a, b: ref mut _b} => {
16+
let x_internal = &mut *x;
17+
match *x_internal {
18+
Pair {a: ref mut a, b: ref mut _b} => {
1819
assert!(**a == 10); *a = box 30; assert!(**a == 30);
1920
}
2021
}

0 commit comments

Comments
 (0)