0

I am trying to use a closure as function parameter:

fn foo(f: Box<Fn() -> bool>) -> bool { f() } fn main() { let bar = 42; foo(Box::new(|| bar != 42)); } 

but I get this lifetime error:

src/main.rs:7:24: 7:36 error: cannot infer an appropriate lifetime due to conflicting requirements src/main.rs:7 let n = foo(Box::new(|| bar != 42)); ^~~~~~~~~~~~ src/main.rs:7:15: 7:23 note: first, the lifetime cannot outlive the expression at 7:14... src/main.rs:7 let n = foo(Box::new(|| bar != 42)); ^~~~~~~~ src/main.rs:7:15: 7:23 note: ...so that the type `[closure src/main.rs:7:24: 7:36]` will meet its required lifetime bounds src/main.rs:7 let n = foo(Box::new(|| bar != 42)); ^~~~~~~~ src/main.rs:7:15: 7:37 note: but, the lifetime must be valid for the call at 7:14... src/main.rs:7 let n = foo(Box::new(|| bar != 42)); ^~~~~~~~~~~~~~~~~~~~~~ src/main.rs:7:24: 7:36 note: ...so that argument is valid for the call src/main.rs:7 let n = foo(Box::new(|| bar != 42)); ^~~~~~~~~~~~ error: aborting due to previous error 

I don't understand why the lifetime is not properly infered. What can I do to fix that ?

$ rustc --version rustc 1.0.0-nightly (6c065fc8c 2015-02-17) (built 2015-02-18) 

1 Answer 1

3

if you want to use a boxed closure you need to use move || {}.

fn foo(f: Box<Fn() -> bool>) -> bool { f() } fn main() { let bar = 42; let blub = foo(Box::new(move || bar != 42)); } 

On the other hand, you cannot use an unboxed closure directly, as it may contain any number of captured elements, and is therefor unsized. By using generics you can easily circumvent this limitation:

fn foo<T>(f: T) -> bool where T : Fn() -> bool { f() } fn main() { let bar = 42; let blub = foo(|| bar != 42); } 
Sign up to request clarification or add additional context in comments.

3 Comments

Would you mind explaining the meaning of the error in more detail? I'm seeing a similar error (except without using any closures/lambdas), and it's not making a whole lot of sense to me. What makes it so that the lifetime cannot outlive an expression?
usually that is because the object you are referencing would go out of scope before your reference does, which would allow use-after-free which is undefined behavior
It's the "first, the lifetime cannot outlive" part that I find more perplexing.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.