Rollup merge of #26191 - jimblandy:master, r=steveklabnik

In the discussion of returning closures, it seems like the example code got simplified, but only the later copies got fixed. The final working code has `factory` returning `|x| x + num`, but the earlier code has `|x| vec.push(x)`.

The first form seemed to have more distracting characteristics, and the code wasn't right anyway, so I changed them to all use the second form, and updated the error messages.

r? @steveklabnik
This commit is contained in:
Manish Goregaokar 2015-06-11 12:50:53 +05:30
commit 95407cc627

View File

@ -324,37 +324,34 @@ first, it may seem strange, but well figure it out. Heres how youd prob
try to return a closure from a function:
```rust,ignore
fn factory() -> (Fn(i32) -> Vec<i32>) {
let vec = vec![1, 2, 3];
fn factory() -> (Fn(i32) -> i32) {
let num = 5;
|n| vec.push(n)
|x| x + num
}
let f = factory();
let answer = f(4);
assert_eq!(vec![1, 2, 3, 4], answer);
let answer = f(1);
assert_eq!(6, answer);
```
This gives us these long, related errors:
```text
error: the trait `core::marker::Sized` is not implemented for the type
`core::ops::Fn(i32) -> collections::vec::Vec<i32>` [E0277]
f = factory();
^
note: `core::ops::Fn(i32) -> collections::vec::Vec<i32>` does not have a
constant size known at compile-time
f = factory();
^
error: the trait `core::marker::Sized` is not implemented for the type
`core::ops::Fn(i32) -> collections::vec::Vec<i32>` [E0277]
factory() -> (Fn(i32) -> Vec<i32>) {
^~~~~~~~~~~~~~~~~~~~~
note: `core::ops::Fn(i32) -> collections::vec::Vec<i32>` does not have a constant size known at compile-time
factory() -> (Fn(i32) -> Vec<i32>) {
^~~~~~~~~~~~~~~~~~~~~
`core::ops::Fn(i32) -> i32` [E0277]
fn factory() -> (Fn(i32) -> i32) {
^~~~~~~~~~~~~~~~
note: `core::ops::Fn(i32) -> i32` does not have a constant size known at compile-time
fn factory() -> (Fn(i32) -> i32) {
^~~~~~~~~~~~~~~~
error: the trait `core::marker::Sized` is not implemented for the type `core::ops::Fn(i32) -> i32` [E0277]
let f = factory();
^
note: `core::ops::Fn(i32) -> i32` does not have a constant size known at compile-time
let f = factory();
^
```
In order to return something from a function, Rust needs to know what
@ -364,16 +361,16 @@ way to give something a size is to take a reference to it, as references
have a known size. So wed write this:
```rust,ignore
fn factory() -> &(Fn(i32) -> Vec<i32>) {
let vec = vec![1, 2, 3];
fn factory() -> &(Fn(i32) -> i32) {
let num = 5;
|n| vec.push(n)
|x| x + num
}
let f = factory();
let answer = f(4);
assert_eq!(vec![1, 2, 3, 4], answer);
let answer = f(1);
assert_eq!(6, answer);
```
But we get another error:
@ -448,7 +445,8 @@ assert_eq!(6, answer);
We use a trait object, by `Box`ing up the `Fn`. Theres just one last problem:
```text
error: `num` does not live long enough
error: closure may outlive the current function, but it borrows `num`,
which is owned by the current function [E0373]
Box::new(|x| x + num)
^~~~~~~~~~~
```