Question
Why is a temporary closure inferred to not implement Fn when it should?
I found some weird behavior: the rust compiler erroneously infers Fn* trait implementation of closure when used as a temp instance.
Here's a simple example:
fn takes_fn_map<I, F, A, B>(_: std::iter::Map<I, F>)
where
F: Fn(A) -> B,
{
}
fn main() {
let map_temp_f = vec![0].into_iter().map(|x| x + 1);
let var_f = |x| x + 1;
let map_var_f = vec![0].into_iter().map(var_f);
fn fn_f(x: i32) -> i32 {
x + 1
}
let map_fn_f = vec![0].into_iter().map(fn_f);
takes_fn_map(map_temp_f); // ! Error
takes_fn_map(map_var_f); // Ok
takes_fn_map(map_fn_f); // Ok
}
error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnMut`
--> src/main.rs:8:46
|
8 | let map_temp_f = vec![0].into_iter().map(|x| x + 1);
| ^^^ this closure implements `FnMut`, not `Fn`
...
18 | takes_fn_map(map_temp_f); // ! Error
| ------------ ---------- the requirement to implement `Fn` derives from here
| |
| required by a bound introduced by this call
|
note: required by a bound in `takes_fn_map`
--> src/main.rs:3:8
|
1 | fn takes_fn_map<I, F, A, B>(_: std::iter::Map<I, F>)
| ------------ required by a bound in this function
2 | where
3 | F: Fn(A) -> B
| ^^^^^^^^^^ required by this bound in `takes_fn_map`
For more information about this error, try `rustc --explain E0525`.
It seems to be related to this issue, but there's no actual answer.
Is this a compiler error or expected behavior?