]> git.lizzy.rs Git - rust.git/blobdiff - src/doc/trpl/closures.md
Auto merge of #28651 - dotdash:exhaustive_match, r=eddyb
[rust.git] / src / doc / trpl / closures.md
index 161c4ce90b2408614e80601fb45de3be3f7569dd..983af4a0efe7fb9613a9def0feafc4b1b9f95a58 100644 (file)
@@ -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> {