Skip to content

Commit e1919ea

Browse files
committed
Rollup merge of rust-lang#33294 - timothy-mcroy:E0501, r=GuillaumeGomez
Add detailed error explanation for E0501 r? @GuillaumeGomez Bring on the nits!
2 parents fc5d99b + 3f49920 commit e1919ea

File tree

1 file changed

+76
-1
lines changed

1 file changed

+76
-1
lines changed

src/librustc_borrowck/diagnostics.rs

+76-1
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,82 @@ let c = &i; // still ok!
314314
```
315315
"##,
316316

317+
E0501: r##"
318+
This error indicates that a mutable variable is being used while it is still
319+
captured by a closure. Because the closure has borrowed the variable, it is not
320+
available for use until the closure goes out of scope.
321+
322+
Note that a capture will either move or borrow a variable, but in this
323+
situation, the closure is borrowing the variable. Take a look at
324+
http://rustbyexample.com/fn/closures/capture.html for more information about
325+
capturing.
326+
327+
Example of erroneous code:
328+
329+
```compile_fail
330+
fn inside_closure(x: &mut i32) {
331+
// Actions which require unique access
332+
}
333+
334+
fn outside_closure(x: &mut i32) {
335+
// Actions which require unique access
336+
}
337+
338+
fn foo(a: &mut i32) {
339+
let bar = || {
340+
inside_closure(a)
341+
};
342+
outside_closure(a); // error: cannot borrow `*a` as mutable because previous
343+
// closure requires unique access.
344+
}
345+
```
346+
347+
To fix this error, you can place the closure in its own scope:
348+
349+
```
350+
fn inside_closure(x: &mut i32) {}
351+
fn outside_closure(x: &mut i32) {}
352+
353+
fn foo(a: &mut i32) {
354+
{
355+
let bar = || {
356+
inside_closure(a)
357+
};
358+
} // borrow on `a` ends.
359+
outside_closure(a); // ok!
360+
}
361+
```
362+
363+
Or you can pass the variable as a parameter to the closure:
364+
365+
```
366+
fn inside_closure(x: &mut i32) {}
367+
fn outside_closure(x: &mut i32) {}
368+
369+
fn foo(a: &mut i32) {
370+
let bar = |s: &mut i32| {
371+
inside_closure(s)
372+
};
373+
outside_closure(a);
374+
bar(a);
375+
}
376+
```
377+
378+
It may be possible to define the closure later:
379+
380+
```
381+
fn inside_closure(x: &mut i32) {}
382+
fn outside_closure(x: &mut i32) {}
383+
384+
fn foo(a: &mut i32) {
385+
outside_closure(a);
386+
let bar = || {
387+
inside_closure(a)
388+
};
389+
}
390+
```
391+
"##,
392+
317393
E0507: r##"
318394
You tried to move out of a value which was borrowed. Erroneous code example:
319395
@@ -436,7 +512,6 @@ register_diagnostics! {
436512
E0388, // {} in a static location
437513
E0389, // {} in a `&` reference
438514
E0500, // closure requires unique access to `..` but .. is already borrowed
439-
E0501, // cannot borrow `..`.. as .. because previous closure requires unique access
440515
E0502, // cannot borrow `..`.. as .. because .. is also borrowed as ...
441516
E0503, // cannot use `..` because it was mutably borrowed
442517
E0504, // cannot move `..` into closure because it is borrowed

0 commit comments

Comments
 (0)