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 moveactually 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.
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.