Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error explanation e0524 #64428

Merged
merged 2 commits into from
Sep 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 63 additions & 1 deletion src/librustc_mir/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1993,6 +1993,69 @@ fn get_owned_iterator() -> IntoIter<i32> {
```
"##,

E0524: r##"
A variable which requires unique access is being used in more than one closure
at the same time.

Erroneous code example:

```compile_fail,E0524
fn set(x: &mut isize) {
*x += 4;
}

fn dragoooon(x: &mut isize) {
let mut c1 = || set(x);
let mut c2 = || set(x); // error!

c2();
c1();
}
```

To solve this issue, multiple solutions are available. First, is it required
for this variable to be used in more than one closure at a time? If it is the
case, use reference counted types such as `Rc` (or `Arc` if it runs
concurrently):

```
use std::rc::Rc;
use std::cell::RefCell;

fn set(x: &mut isize) {
*x += 4;
}

fn dragoooon(x: &mut isize) {
let x = Rc::new(RefCell::new(x));
let y = Rc::clone(&x);
let mut c1 = || { let mut x2 = x.borrow_mut(); set(&mut x2); };
let mut c2 = || { let mut x2 = y.borrow_mut(); set(&mut x2); }; // ok!

c2();
c1();
}
```

If not, just run closures one at a time:

```
fn set(x: &mut isize) {
*x += 4;
}

fn dragoooon(x: &mut isize) {
{ // This block isn't necessary since non-lexical lifetimes, it's just to
// make it more clear.
let mut c1 = || set(&mut *x);
c1();
} // `c1` has been dropped here so we're free to use `x` again!
let mut c2 = || set(&mut *x);
c2();
}
```
"##,

E0595: r##"
#### Note: this error code is no longer emitted by the compiler.

Expand Down Expand Up @@ -2393,7 +2456,6 @@ There are some known bugs that trigger this message.
// E0385, // {} in an aliasable location
E0493, // destructors cannot be evaluated at compile-time
E0521, // borrowed data escapes outside of closure
E0524, // two closures require unique access to `..` at the same time
E0526, // shuffle indices are not constant
E0594, // cannot assign to {}
// E0598, // lifetime of {} is too short to guarantee its contents can be...
Expand Down
4 changes: 0 additions & 4 deletions src/test/ui/borrowck/borrowck-closures-mut-of-imm.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
// Tests that two closures cannot simultaneously have mutable
// and immutable access to the variable. Issue #6801.

fn get(x: &isize) -> isize {
*x
}

fn set(x: &mut isize) {
*x = 4;
}
Expand Down
9 changes: 5 additions & 4 deletions src/test/ui/borrowck/borrowck-closures-mut-of-imm.stderr
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-closures-mut-of-imm.rs:13:25
--> $DIR/borrowck-closures-mut-of-imm.rs:9:25
|
LL | let mut c1 = || set(&mut *x);
| ^^^^^^^ cannot borrow as mutable

error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-closures-mut-of-imm.rs:15:25
--> $DIR/borrowck-closures-mut-of-imm.rs:11:25
|
LL | let mut c2 = || set(&mut *x);
| ^^^^^^^ cannot borrow as mutable

error[E0524]: two closures require unique access to `x` at the same time
--> $DIR/borrowck-closures-mut-of-imm.rs:15:18
--> $DIR/borrowck-closures-mut-of-imm.rs:11:18
|
LL | let mut c1 = || set(&mut *x);
| -- - first borrow occurs due to use of `x` in closure
Expand All @@ -28,4 +28,5 @@ LL | c2(); c1();

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0596`.
Some errors have detailed explanations: E0524, E0596.
For more information about an error, try `rustc --explain E0524`.
1 change: 1 addition & 0 deletions src/test/ui/borrowck/borrowck-closures-mut-of-mut.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ LL | c2(); c1();

error: aborting due to previous error

For more information about this error, try `rustc --explain E0524`.
3 changes: 2 additions & 1 deletion src/test/ui/borrowck/borrowck-closures-unique.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,5 @@ LL | let c1 = |y: &'static mut isize| x = y;

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0500`.
Some errors have detailed explanations: E0500, E0524.
For more information about an error, try `rustc --explain E0500`.
2 changes: 1 addition & 1 deletion src/test/ui/nll/closures-in-loops.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ LL | v.push(|| *x = String::new());

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0382, E0499.
Some errors have detailed explanations: E0382, E0499, E0524.
For more information about an error, try `rustc --explain E0382`.