@@ -411,8 +411,9 @@ fn factory() -> &(Fn(i32) -> i32) {
411411```
412412
413413Right. Because we have a reference, we need to give it a lifetime. But
414- our ` factory() ` function takes no arguments, so elision doesn’t kick in
415- here. What lifetime can we choose? ` 'static ` :
414+ our ` factory() ` function takes no arguments, so
415+ [ elision] ( lifetimes.html#lifetime-elision ) doesn’t kick in here. Then what
416+ choices do we have? Try ` 'static ` :
416417
417418``` rust,ignore
418419fn factory() -> &'static (Fn(i32) -> i32) {
@@ -432,7 +433,7 @@ But we get another error:
432433``` text
433434error: mismatched types:
434435 expected `&'static core::ops::Fn(i32) -> i32`,
435- found `[closure <anon>:7:9: 7:20]`
436+ found `[closure@ <anon>:7:9: 7:20]`
436437(expected &-ptr,
437438 found closure) [E0308]
438439 |x| x + num
@@ -441,21 +442,17 @@ error: mismatched types:
441442```
442443
443444This error is letting us know that we don’t have a ` &'static Fn(i32) -> i32 ` ,
444- we have a ` [closure <anon>:7:9: 7:20] ` . Wait, what?
445+ we have a ` [closure@ <anon>:7:9: 7:20] ` . Wait, what?
445446
446447Because each closure generates its own environment ` struct ` and implementation
447448of ` Fn ` and friends, these types are anonymous. They exist just solely for
448- this closure. So Rust shows them as ` closure <anon> ` , rather than some
449+ this closure. So Rust shows them as ` closure@ <anon> ` , rather than some
449450autogenerated name.
450451
451- But why doesn’t our closure implement ` &'static Fn ` ? Well, as we discussed before,
452- closures borrow their environment. And in this case, our environment is based
453- on a stack-allocated ` 5 ` , the ` num ` variable binding. So the borrow has a lifetime
454- of the stack frame. So if we returned this closure, the function call would be
455- over, the stack frame would go away, and our closure is capturing an environment
456- of garbage memory!
457-
458- So what to do? This _ almost_ works:
452+ The error also points out that the return type is expected to be a reference,
453+ but what we are trying to return is not. Further, we cannot directly assign a
454+ ` 'static ` lifetime to an object. So we'll take a different approach and return
455+ a "trait object" by ` Box ` ing up the ` Fn ` . This _ almost_ works:
459456
460457``` rust,ignore
461458fn factory() -> Box<Fn(i32) -> i32> {
@@ -471,7 +468,7 @@ assert_eq!(6, answer);
471468# }
472469```
473470
474- We use a trait object, by ` Box ` ing up the ` Fn ` . There’s just one last problem:
471+ There’s just one last problem:
475472
476473``` text
477474error: closure may outlive the current function, but it borrows `num`,
@@ -480,8 +477,12 @@ Box::new(|x| x + num)
480477 ^~~~~~~~~~~
481478```
482479
483- We still have a reference to the parent stack frame. With one last fix, we can
484- make this work:
480+ Well, as we discussed before, closures borrow their environment. And in this
481+ case, our environment is based on a stack-allocated ` 5 ` , the ` num ` variable
482+ binding. So the borrow has a lifetime of the stack frame. So if we returned
483+ this closure, the function call would be over, the stack frame would go away,
484+ and our closure is capturing an environment of garbage memory! With one last
485+ fix, we can make this work:
485486
486487``` rust
487488fn factory () -> Box <Fn (i32 ) -> i32 > {
0 commit comments