I would like to understand why I must annotate a type for x
here, and why this happens only in a very specific scenario. The type annotation isn't needed if I …
- use
Fn(i32)
instead of the aliasMyFn
, - use an operator instead of making a method call, or
- use a
Box<dyn …>
.
Why?
trait MyFn: Fn(i32) {}
impl<T: ?Sized> MyFn for T where T: Fn(i32) {}
fn takes_closure<F: MyFn>(_closure: F) {}
fn takes_boxed_closure(_closure: Box<dyn MyFn>) {}
fn takes_closure2<F: Fn(i32)>(_closure: F) {}
fn main() {
takes_closure(|x| drop(x.abs())); // why is type annotation needed here?
takes_boxed_closure(Box::new(|x| drop(x.abs()))); // but not here?
takes_closure2(|x| drop(x.abs())); // and this works too, but why?
takes_closure(|x| drop(x + x)); // also this works!?
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0282]: type annotations needed
--> src/main.rs:10:20
|
10 | takes_closure(|x| drop(x.abs())); // why is type annotation needed here?
| ^
|
= note: type must be known at this point
help: consider giving this closure parameter an explicit type
|
10 | takes_closure(|x: _| drop(x.abs())); // why is type annotation needed here?
| +++
For more information about this error, try `rustc --explain E0282`.
error: could not compile `playground` due to previous error
I tried to use #![feature(trait_alias)]
, and it exhibits the same problem:
-trait MyFn: Fn(i32) {}
-impl<T: ?Sized> MyFn for T where T: Fn(i32) {}
+#![feature(trait_alias)]
+
+trait MyFn = Fn(i32);
Maybe this is a bug then?