Move and impl Fn()

hello, could you tell me why this example is considered valid in the Rust

fn create_fn() -> impl Fn() {
    let text = "Fn".to_owned();

    move || println!("This is a: {}", text)}
}


fn main() {
    let fn_plain = create_fn();

    fn_plain();
}

as said here

when move is used, the closures is represented by the FnOnce trait.

but impl Fn() is valid, why?


guess: in a closure with move all traits Fn, FnMut and FnOnce are implemented, and the impl Fn() check differs from how the <F: Fn()> parameters are checked?

Really good question. The docs page is just wrong about this. What move actually does is: make sure that every captured variable is moved (or copied it that’s possible) into the closure. This is commonly relevant when a closure is to be returned from a function, since capturing by-reference would then produce lifetime errors. In particular however, the keyword move has no effect whatsoever on what Fn* traits the closure implements.

2 Likes

For additional information, see the page on closures in the reference.

This section of that page has a note that directly answers your question:

Note: move closures may still implement Fn or FnMut , even though they capture variables by move. This is because the traits implemented by a closure type are determined by what the closure does with captured values, not how it captures them.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.