Why can't return closure with 'static lifetime?

I'm reading the book, chapter about the closures:

fn factory() -> &'static (Fn(i32) -> i32) {
    let num = 5;

    |x| x + num
}
let f = factory();
let answer = f(1);

Book says: "Further, we cannot directly assign a 'static lifetime to an object.",
however didn't explain why.

What's the rationale behind that error?

Couldn't compiler deduce size of returned closures during compilation and place it somewhere in the code section in binary?

There are multiple problems but most likely you are after;

fn factory() -> Box<Fn(i32) -> i32> {
    let num = 5;
    Box::new(move |x| x + num)
}

In nightly you also have;

#![feature(conservative_impl_trait)]
fn factory() -> impl Fn(i32) -> i32 {
    let num = 5;
    move |x| x + num
}

Which does the size deduction and creates a anonymous type as the return value. Fn(...)->(...) by itself is a Trait not a datatype.

3 Likes

You're returning closure by value. If you simplify the type to an int, it's equivalent to doing this:

fn factory() -> &'static i32 {
let n = 5;
n
}

and you can't return a static reference for the same reason too:

fn factory() -> &'static i32 {
let n = 5;
&n // this is a pointer to stack of factory() call, which is gone when the call ends
}
1 Like

Will that feature go into stable?

https://github.com/rust-lang/rust/issues/34511

Yes

3 Likes