d7de4e9aff
Implement the stronger guarantees for mutable borrows from #12624. This removes the ability to read from a mutably borrowed path for the duration of the borrow, and enforces a unique access path for any mutable borrow, for both reads and writes. This makes mutable borrows work better with concurrent accesses from multiple threads, and it opens the door for allowing moves out of mutably borrowed values, as long as a new value is written before the mutable borrow ends. This also aligns Rust more closely with academic languages based on substructural types and separation logic. The most common situation triggering an error after this change is a call to a function mutably borrowing self with self.field as one of the arguments. The workaround is to bind self.field to a temporary, but the need for these temporaries will hopefully go away after #6268 is fixed. Another situation that triggers an error is using the head expression of a match in an arm that binds a variable with a mutable reference. The use of the head expression needs to be replaced with an expression that reconstructs it from match-bound variables. This fixes #12624. [breaking-change]
23 lines
885 B
Rust
23 lines
885 B
Rust
// Copyright 2012 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.
|
|
|
|
// The type of `y` ends up getting inferred to the type of the block.
|
|
fn broken() {
|
|
let mut x = 3;
|
|
let mut _y = vec!(&mut x);
|
|
while x < 10 { //~ ERROR cannot use `x` because it was mutably borrowed
|
|
let mut z = x; //~ ERROR cannot use `x` because it was mutably borrowed
|
|
_y.push(&mut z); //~ ERROR `z` does not live long enough
|
|
x += 1; //~ ERROR cannot assign
|
|
}
|
|
}
|
|
|
|
fn main() { }
|