about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2016-05-03 19:09:07 +0530
committerManish Goregaokar <manishsmail@gmail.com>2016-05-03 19:54:50 +0530
commit5bac8cb16d7c2ce68a826e5b4238e545cd68d3d5 (patch)
treef9fd6e479f3f710075da6304fb3884d3bb485ddc /src
parentaf05b568c036bf19d0f66ceb5285236a7f17b054 (diff)
parent3f49920495c1db358e5964acf8182b96405ce435 (diff)
downloadrust-5bac8cb16d7c2ce68a826e5b4238e545cd68d3d5.tar.gz
rust-5bac8cb16d7c2ce68a826e5b4238e545cd68d3d5.zip
Rollup merge of #33294 - timothy-mcroy:E0501, r=GuillaumeGomez
Add detailed error explanation for E0501

r? @GuillaumeGomez

Bring on the nits!
Diffstat (limited to 'src')
-rw-r--r--src/librustc_borrowck/diagnostics.rs77
1 files changed, 76 insertions, 1 deletions
diff --git a/src/librustc_borrowck/diagnostics.rs b/src/librustc_borrowck/diagnostics.rs
index c7ad0b6a6c6..e838921a831 100644
--- a/src/librustc_borrowck/diagnostics.rs
+++ b/src/librustc_borrowck/diagnostics.rs
@@ -314,6 +314,82 @@ let c = &i; // still ok!
 ```
 "##,
 
+E0501: r##"
+This error indicates that a mutable variable is being used while it is still
+captured by a closure. Because the closure has borrowed the variable, it is not
+available for use until the closure goes out of scope.
+
+Note that a capture will either move or borrow a variable, but in this
+situation, the closure is borrowing the variable. Take a look at
+http://rustbyexample.com/fn/closures/capture.html for more information about
+capturing.
+
+Example of erroneous code:
+
+```compile_fail
+fn inside_closure(x: &mut i32) {
+    // Actions which require unique access
+}
+
+fn outside_closure(x: &mut i32) {
+    // Actions which require unique access
+}
+
+fn foo(a: &mut i32) {
+    let bar = || {
+        inside_closure(a)
+    };
+    outside_closure(a); // error: cannot borrow `*a` as mutable because previous
+                        //        closure requires unique access.
+}
+```
+
+To fix this error, you can place the closure in its own scope:
+
+```
+fn inside_closure(x: &mut i32) {}
+fn outside_closure(x: &mut i32) {}
+
+fn foo(a: &mut i32) {
+    {
+        let bar = || {
+            inside_closure(a)
+        };
+    } // borrow on `a` ends.
+    outside_closure(a); // ok!
+}
+```
+
+Or you can pass the variable as a parameter to the closure:
+
+```
+fn inside_closure(x: &mut i32) {}
+fn outside_closure(x: &mut i32) {}
+
+fn foo(a: &mut i32) {
+    let bar = |s: &mut i32| {
+        inside_closure(s)
+    };
+    outside_closure(a);
+    bar(a);
+}
+```
+
+It may be possible to define the closure later:
+
+```
+fn inside_closure(x: &mut i32) {}
+fn outside_closure(x: &mut i32) {}
+
+fn foo(a: &mut i32) {
+    outside_closure(a);
+    let bar = || {
+        inside_closure(a)
+    };
+}
+```
+"##,
+
 E0507: r##"
 You tried to move out of a value which was borrowed. Erroneous code example:
 
@@ -436,7 +512,6 @@ register_diagnostics! {
     E0388, // {} in a static location
     E0389, // {} in a `&` reference
     E0500, // closure requires unique access to `..` but .. is already borrowed
-    E0501, // cannot borrow `..`.. as .. because previous closure requires unique access
     E0502, // cannot borrow `..`.. as .. because .. is also borrowed as ...
     E0503, // cannot use `..` because it was mutably borrowed
     E0504, // cannot move `..` into closure because it is borrowed