diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2014-08-12 14:25:41 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2014-08-12 14:30:05 -0700 |
| commit | f1799fdfcae806988bd7104870da56c7596af8ac (patch) | |
| tree | 07030434f531353eee21c29df90609a97220f1e3 | |
| parent | e2273d945640442224a09e532865e4a58257a851 (diff) | |
| download | rust-f1799fdfcae806988bd7104870da56c7596af8ac.tar.gz rust-f1799fdfcae806988bd7104870da56c7596af8ac.zip | |
librustc: Record unique immutable borrows in the restrictions table.
This fixes borrow checking for closures. Code like this will break:
struct Foo {
x: int,
}
pub fn main() {
let mut this = &mut Foo {
x: 1,
};
let r = || {
let p = &this.x;
&mut this.x;
};
r()
}
Change this code to not take multiple mutable references to the same value. For
example:
struct Foo {
x: int,
}
pub fn main() {
let mut this = &mut Foo {
x: 1,
};
let r = || {
&mut this.x;
};
r()
}
Closes #16361.
[breaking-change]
| -rw-r--r-- | src/librustc/middle/borrowck/gather_loans/mod.rs | 2 | ||||
| -rw-r--r-- | src/librustc/middle/borrowck/gather_loans/restrictions.rs | 8 | ||||
| -rw-r--r-- | src/test/compile-fail/borrowck-closures-unique-imm.rs | 25 |
3 files changed, 31 insertions, 4 deletions
diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs index 454c3dcd5d3..18323c26dd9 100644 --- a/src/librustc/middle/borrowck/gather_loans/mod.rs +++ b/src/librustc/middle/borrowck/gather_loans/mod.rs @@ -261,6 +261,8 @@ impl<'a> GatherLoanCtxt<'a> { self.bccx, borrow_span, cause, cmt.clone(), loan_region); + debug!("guarantee_valid(): restrictions={:?}", restr); + // Create the loan record (if needed). let loan = match restr { restrictions::Safe => { diff --git a/src/librustc/middle/borrowck/gather_loans/restrictions.rs b/src/librustc/middle/borrowck/gather_loans/restrictions.rs index da739faabad..7d50d07a11e 100644 --- a/src/librustc/middle/borrowck/gather_loans/restrictions.rs +++ b/src/librustc/middle/borrowck/gather_loans/restrictions.rs @@ -122,9 +122,7 @@ impl<'a> RestrictionsContext<'a> { } mc::cat_deref(cmt_base, _, mc::BorrowedPtr(ty::ImmBorrow, lt)) | - mc::cat_deref(cmt_base, _, mc::BorrowedPtr(ty::UniqueImmBorrow, lt)) | - mc::cat_deref(cmt_base, _, mc::Implicit(ty::ImmBorrow, lt)) | - mc::cat_deref(cmt_base, _, mc::Implicit(ty::UniqueImmBorrow, lt)) => { + mc::cat_deref(cmt_base, _, mc::Implicit(ty::ImmBorrow, lt)) => { // R-Deref-Imm-Borrowed if !self.bccx.is_subregion_of(self.loan_region, lt) { self.bccx.report( @@ -142,7 +140,9 @@ impl<'a> RestrictionsContext<'a> { mc::cat_deref(cmt_base, _, pk) => { match pk { mc::BorrowedPtr(ty::MutBorrow, lt) | - mc::Implicit(ty::MutBorrow, lt) => { + mc::BorrowedPtr(ty::UniqueImmBorrow, lt) | + mc::Implicit(ty::MutBorrow, lt) | + mc::Implicit(ty::UniqueImmBorrow, lt) => { // R-Deref-Mut-Borrowed if !self.bccx.is_subregion_of(self.loan_region, lt) { self.bccx.report( diff --git a/src/test/compile-fail/borrowck-closures-unique-imm.rs b/src/test/compile-fail/borrowck-closures-unique-imm.rs new file mode 100644 index 00000000000..dfe5de09c50 --- /dev/null +++ b/src/test/compile-fail/borrowck-closures-unique-imm.rs @@ -0,0 +1,25 @@ +// 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. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Foo { + x: int, +} + +pub fn main() { + let mut this = &mut Foo { + x: 1, + }; + let r = || { + let p = &this.x; + &mut this.x; //~ ERROR cannot borrow + }; + r() +} + |
