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.