about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/doc/book/closures.md47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/doc/book/closures.md b/src/doc/book/closures.md
index d81619b647f..e690f4edd47 100644
--- a/src/doc/book/closures.md
+++ b/src/doc/book/closures.md
@@ -319,6 +319,53 @@ assert_eq!(3, answer);
 Now we take a trait object, a `&Fn`. And we have to make a reference
 to our closure when we pass it to `call_with_one`, so we use `&||`.
 
+A quick note about closures that use explicit lifetimes. Sometimes you might have a closure
+that takes a reference like so:
+
+```
+fn call_with_ref<F>(some_closure:F) -> i32
+    where F: Fn(&i32) -> i32 {
+
+    let mut value = 0;
+    some_closure(&value)
+}
+```
+
+Normally you can specify the lifetime of the parameter to our closure. We
+could annotate it on the function declaration:
+
+```ignore
+fn call_with_ref<'a, F>(some_closure:F) -> i32 
+    where F: Fn(&'a 32) -> i32 {
+```
+
+However this presents a problem with in our case. When you specify the explict
+lifetime on a function it binds that lifetime to the *entire* scope of the function
+instead of just the invocation scope of our closure. This means that the borrow checker
+will see a mutable reference in the same lifetime as our immutable reference and fail
+to compile.
+
+In order to say that we only need the lifetime to be valid for the invocation scope
+of the closure we can use Higher-Ranked Trait Bounds with the `for<...>` syntax:
+
+```ignore
+fn call_with_ref<F>(some_closure:F) -> i32
+    where F: for<'a> Fn(&'a 32) -> i32 {
+```
+
+This lets the Rust compiler find the minimum lifetime to invoke our closure and 
+satisfy the borrow checker's rules. Our function then compiles and excutes as we
+expect.
+
+```
+fn call_with_ref<F>(some_closure:F) -> i32
+    where F: for<'a> Fn(&'a i32) -> i32 {
+
+    let mut value = 0;
+    some_closure(&value)
+}
+```
+
 # Function pointers and closures
 
 A function pointer is kind of like a closure that has no environment. As such,