diff options
| author | bors <bors@rust-lang.org> | 2014-08-13 04:11:22 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-08-13 04:11:22 +0000 |
| commit | 6291781592ff079fc1e84f4b8be5684d2a52b8bd (patch) | |
| tree | 4aaf32a3a7f2782a8d95513d3fcea0368518ab4e | |
| parent | ee87234eed95d6077247bee5416339ce2652b599 (diff) | |
| parent | f1799fdfcae806988bd7104870da56c7596af8ac (diff) | |
| download | rust-6291781592ff079fc1e84f4b8be5684d2a52b8bd.tar.gz rust-6291781592ff079fc1e84f4b8be5684d2a52b8bd.zip | |
auto merge of #16460 : pcwalton/rust/borrowck-closure-issue, r=nikomatsakis
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]
r? @nikomatsakis
| -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() +} + |
