I'm writing a function that accepts different trait implementors. One of them is a closure. Some closures need an argument type annotation and some don't, depending on their bodies.
Example (playground):
fn main() {
bar(|x| x);
bar(|x: bool| !x); // Why is the annotation needed?
}
trait Foo<T> {
type Output;
}
impl<F: Fn(T) -> O, T, O> Foo<T> for F {
type Output = O;
}
fn bar(_: impl Foo<bool, Output = bool>) {}
Why do some closures infer the argument type and others need annotation?
Is it possible to redesign trait or function to never require annotation?
My (invalid) reasoning is that inference is the same for both closures:
bar
needsFoo<bool, Output = bool>
- Only
Fn(bool) -> bool
implementsFoo<bool, Output = bool>
- The closure must be
|bool| -> bool
The fact that negation (Not
trait) detaches the input type from the output type should not matter, but it seems to somehow be a crucial element.
!x
withx | true
removes need for annotation andBitOr
is not implemented forT
either.|x| !&x
works, but|x| !*&x
doesn't.