Designating longer lifetime of function parameter returned via closure

⚓ Rust    📅 2026-04-04    👤 surdeus    👁️ 6      

surdeus

Hello everyone,

I've been working through chapter 13.3 of the book about improving minigrep with closures and iterators. While playing around I've found an issue that the compiler correctly rejected to compile, but I'm a bit confused how the compiler knew and how this could be somehow annotated in the function declaration.

fn foo(data: &str) -> impl FnOnce() -> () {
    move || { println!("{data}") }
}

fn main() {
    let c = foo(&String::from("test"));
    c();
}

This doesn't compile, since the borrowed reference to the String created from "test" is lost after calling foo. And if you pass in "test" directly as a literal it does compile, as it has a static lifetime. So far so good. But just from the foo function declaration it has zero information that the passed parameter needs to have a longer lifetime. So my guess is the compiler does deeper analysis in those cases than just to look at the function declaration? It actually analyses the function definition/implementation as well?

The second question I have in this case: How do you mark the parameter data in foo to have a longer lifetime? If you'd provide such a public interface, it would probably be quite confusing for a caller to to be confronted with this situation. Thus it would be nice to designate the longer lifetime of data somehow in the function declaration. Is there a possibility for that?

Thank you for the help in advance.

3 posts - 3 participants

Read full topic

🏷️ Rust_feed