From 3607c7a982c55a165adda8056cc228acf918bc37 Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Wed, 30 Jul 2014 13:36:21 -0700 Subject: [PATCH] Implement RFC #43 Remove the ability of the borrow checker to determine that repeated dereferences of a Box refer to the same memory object. This will usually require one of two workarounds: 1) The interior of a Box 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] --- src/librustc/middle/borrowck/check_loans.rs | 7 +++++-- src/test/compile-fail/borrowck-borrow-from-owned-ptr.rs | 9 +++++---- src/test/run-pass/match-implicit-copy-unique.rs | 5 +++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index fd867393469..7dec42538cf 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -261,6 +261,7 @@ impl<'a> CheckLoanCtxt<'a> { // let x = &mut a.b.c; // Restricts a, a.b, and a.b.c // let y = a; // Conflicts with restriction + let loan_path = owned_ptr_base_path(loan_path); let cont = self.each_in_scope_loan(scope_id, |loan| { let mut ret = true; for restr_path in loan.restricted_paths.iter() { @@ -395,8 +396,9 @@ impl<'a> CheckLoanCtxt<'a> { return true; } + let loan2_base_path = owned_ptr_base_path_rc(&loan2.loan_path); for restr_path in loan1.restricted_paths.iter() { - if *restr_path != loan2.loan_path { continue; } + if *restr_path != loan2_base_path { continue; } let old_pronoun = if new_loan.loan_path == old_loan.loan_path { "it".to_string() @@ -648,7 +650,8 @@ impl<'a> CheckLoanCtxt<'a> { debug!("check_if_path_is_moved(id={:?}, use_kind={:?}, lp={})", id, use_kind, lp.repr(self.bccx.tcx)); - self.move_data.each_move_of(id, lp, |move, moved_lp| { + let base_lp = owned_ptr_base_path_rc(lp); + self.move_data.each_move_of(id, &base_lp, |move, moved_lp| { self.bccx.report_use_of_moved_value( span, use_kind, diff --git a/src/test/compile-fail/borrowck-borrow-from-owned-ptr.rs b/src/test/compile-fail/borrowck-borrow-from-owned-ptr.rs index c7695e0ff5f..208f58f6b54 100644 --- a/src/test/compile-fail/borrowck-borrow-from-owned-ptr.rs +++ b/src/test/compile-fail/borrowck-borrow-from-owned-ptr.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -52,7 +52,7 @@ fn borrow_same_field_twice_imm_imm() { fn borrow_both_fields_mut() { let mut foo = make_foo(); let bar1 = &mut foo.bar1; - let _bar2 = &mut foo.bar2; + let _bar2 = &mut foo.bar2; //~ ERROR cannot borrow *bar1; } @@ -60,6 +60,7 @@ fn borrow_both_mut_pattern() { let mut foo = make_foo(); match *foo { Foo { bar1: ref mut _bar1, bar2: ref mut _bar2 } => {} + //~^ ERROR cannot borrow } } @@ -120,7 +121,7 @@ fn borrow_imm_and_base_imm() { fn borrow_mut_and_imm() { let mut foo = make_foo(); let bar1 = &mut foo.bar1; - let _foo1 = &foo.bar2; + let _foo1 = &foo.bar2; //~ ERROR cannot borrow *bar1; } @@ -133,7 +134,7 @@ fn borrow_mut_from_imm() { fn borrow_long_path_both_mut() { let mut foo = make_foo(); let bar1 = &mut foo.bar1.int1; - let foo1 = &mut foo.bar2.int2; + let foo1 = &mut foo.bar2.int2; //~ ERROR cannot borrow *bar1; *foo1; } diff --git a/src/test/run-pass/match-implicit-copy-unique.rs b/src/test/run-pass/match-implicit-copy-unique.rs index 679fb472503..0e7c959d58c 100644 --- a/src/test/run-pass/match-implicit-copy-unique.rs +++ b/src/test/run-pass/match-implicit-copy-unique.rs @@ -13,8 +13,9 @@ struct Pair { a: Box, b: Box } pub fn main() { let mut x = box Pair {a: box 10, b: box 20}; - match x { - box Pair {a: ref mut a, b: ref mut _b} => { + let x_internal = &mut *x; + match *x_internal { + Pair {a: ref mut a, b: ref mut _b} => { assert!(**a == 10); *a = box 30; assert!(**a == 30); } }