about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSteve Klabnik <steve@steveklabnik.com>2015-09-25 13:33:31 -0600
committerSteve Klabnik <steve@steveklabnik.com>2015-09-25 13:33:31 -0600
commitaed73e0122e538375e6ef827e90c6d1a191c5fff (patch)
tree0d9a4417d8909ceb7d587a06d10cba18ec45c461
parentde2792faa08943699377f782e86098dda599829a (diff)
parent09d4deef5b3f84548c0b9f6e1f70b0f5818eba2d (diff)
downloadrust-aed73e0122e538375e6ef827e90c6d1a191c5fff.tar.gz
rust-aed73e0122e538375e6ef827e90c6d1a191c5fff.zip
Rollup merge of #28588 - critiqjo:trpl-closure, r=steveklabnik
r? @steveklabnik
-rw-r--r--src/doc/trpl/closures.md33
1 files changed, 17 insertions, 16 deletions
diff --git a/src/doc/trpl/closures.md b/src/doc/trpl/closures.md
index 161c4ce90b2..983af4a0efe 100644
--- a/src/doc/trpl/closures.md
+++ b/src/doc/trpl/closures.md
@@ -411,8 +411,9 @@ fn factory() -> &(Fn(i32) -> i32) {
 ```
 
 Right. Because we have a reference, we need to give it a lifetime. But
-our `factory()` function takes no arguments, so elision doesn’t kick in
-here. What lifetime can we choose? `'static`:
+our `factory()` function takes no arguments, so
+[elision](lifetimes.html#lifetime-elision) doesn’t kick in here. Then what
+choices do we have? Try `'static`:
 
 ```rust,ignore
 fn factory() -> &'static (Fn(i32) -> i32) {
@@ -432,7 +433,7 @@ But we get another error:
 ```text
 error: mismatched types:
  expected `&'static core::ops::Fn(i32) -> i32`,
-    found `[closure <anon>:7:9: 7:20]`
+    found `[closure@<anon>:7:9: 7:20]`
 (expected &-ptr,
     found closure) [E0308]
          |x| x + num
@@ -441,21 +442,17 @@ error: mismatched types:
 ```
 
 This error is letting us know that we don’t have a `&'static Fn(i32) -> i32`,
-we have a `[closure <anon>:7:9: 7:20]`. Wait, what?
+we have a `[closure@<anon>:7:9: 7:20]`. Wait, what?
 
 Because each closure generates its own environment `struct` and implementation
 of `Fn` and friends, these types are anonymous. They exist just solely for
-this closure. So Rust shows them as `closure <anon>`, rather than some
+this closure. So Rust shows them as `closure@<anon>`, rather than some
 autogenerated name.
 
-But why doesn’t our closure implement `&'static Fn`? Well, as we discussed before,
-closures borrow their environment. And in this case, our environment is based
-on a stack-allocated `5`, the `num` variable binding. So the borrow has a lifetime
-of the stack frame. So if we returned this closure, the function call would be
-over, the stack frame would go away, and our closure is capturing an environment
-of garbage memory!
-
-So what to do? This _almost_ works:
+The error also points out that the return type is expected to be a reference,
+but what we are trying to return is not. Further, we cannot directly assign a
+`'static` lifetime to an object. So we'll take a different approach and return
+a "trait object" by `Box`ing up the `Fn`. This _almost_ works:
 
 ```rust,ignore
 fn factory() -> Box<Fn(i32) -> i32> {
@@ -471,7 +468,7 @@ assert_eq!(6, answer);
 # }
 ```
 
-We use a trait object, by `Box`ing up the `Fn`. There’s just one last problem:
+There’s just one last problem:
 
 ```text
 error: closure may outlive the current function, but it borrows `num`,
@@ -480,8 +477,12 @@ Box::new(|x| x + num)
          ^~~~~~~~~~~
 ```
 
-We still have a reference to the parent stack frame. With one last fix, we can
-make this work:
+Well, as we discussed before, closures borrow their environment. And in this
+case, our environment is based on a stack-allocated `5`, the `num` variable
+binding. So the borrow has a lifetime of the stack frame. So if we returned
+this closure, the function call would be over, the stack frame would go away,
+and our closure is capturing an environment of garbage memory! With one last
+fix, we can make this work:
 
 ```rust
 fn factory() -> Box<Fn(i32) -> i32> {