-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Closed
Labels
A-lifetimesArea: Lifetimes / regionsArea: Lifetimes / regions
Description
This works:
#![feature(unboxed_closures)]
fn f1(i: i32) -> i32 { i * 2 }
fn main() {
let mut arr: Vec<&Fn(i32) -> i32> = Vec::new();
let p1 = &f1;
arr.push(p1);
arr[0].call((1, ));
}
This doesn't, which is surprising:
#![feature(unboxed_closures)]
fn f1(i: i32) -> i32 { i * 2 }
fn main() {
let mut arr: Vec<&Fn(i32) -> i32> = Vec::new();
arr.push(&f1);
arr[0].call((1, ));
}
test.rs:7:15: 7:17 error: borrowed value does not live long enough
test.rs:7 arr.push(&f1);
^~
test.rs:5:11: 9:2 note: reference must be valid for the block at 5:10...
test.rs:5 fn main() {
test.rs:6 let mut arr: Vec<&Fn(i32) -> i32> = Vec::new();
test.rs:7 arr.push(&f1);
test.rs:8 arr[0].call((1, ));
test.rs:9 }
test.rs:7:5: 7:19 note: ...but borrowed value is only valid for the statement at 7:4
test.rs:7 arr.push(&f1);
^~~~~~~~~~~~~~
test.rs:7:5: 7:19 help: consider using a `let` binding to increase its lifetime
test.rs:7 arr.push(&f1);
^~~~~~~~~~~~~~
The bigger problem is that this does not work as well:
#![feature(unboxed_closures)]
fn main() {
let mut arr: Vec<&Fn(i32) -> i32> = Vec::new();
arr.push(&|x| x * 4);
arr[0].call((1, ));
}
test.rs:5:15: 5:24 error: borrowed value does not live long enough
test.rs:5 arr.push(&|x| x * 4);
^~~~~~~~~
test.rs:3:11: 7:2 note: reference must be valid for the block at 3:10...
test.rs:3 fn main() {
test.rs:4 let mut arr: Vec<&Fn(i32) -> i32> = Vec::new();
test.rs:5 arr.push(&|x| x * 4);
test.rs:6 arr[0].call((1, ));
test.rs:7 }
test.rs:5:5: 5:26 note: ...but borrowed value is only valid for the statement at 5:4
test.rs:5 arr.push(&|x| x * 4);
^~~~~~~~~~~~~~~~~~~~~
test.rs:5:5: 5:26 help: consider using a `let` binding to increase its lifetime
test.rs:5 arr.push(&|x| x * 4);
^~~~~~~~~~~~~~~~~~~~~
And there is no workaround - I can't bind the closure to a separate variable because a lot of type inference issues arise, most notably is that closure is interpreted as an old closure (and I don't know how to force it to be interpreted as a new one).
Discovered in this SO question.
Metadata
Metadata
Assignees
Labels
A-lifetimesArea: Lifetimes / regionsArea: Lifetimes / regions