Is there a difference between the impl Trait
syntax and trait bound syntax? According to the Rust Book, one might guess that there is no difference.
The
impl Trait
syntax works for straightforward cases but is actually syntax sugar for a longer form, which is called a trait bound.
However, there are cases where this seems to be an incorrect assumption - namely, when the trait bound is on a return type. For instance, consider the following code.
pub fn main() {
println!("{:x}", f());
}
pub fn f() -> impl std::fmt::LowerHex {
48879
}
This function compiles and runs without issue. However, when one uses trait bound syntax rather than impl Trait
syntax, then issues arise.
pub fn main() {
println!("{:x}", f());
}
pub fn f<T: std::fmt::LowerHex>() -> T {
48879
}
Below is the output from the compiler, given the above code.
error[E0282]: type annotations needed
--> src/main.rs:2:22
|
2 | println!("{:x}", f());
| ^ cannot infer type for type parameter `T` declared on the function `f`
error[E0308]: mismatched types
--> src/main.rs:12:5
|
11 | pub fn f<T: std::fmt::LowerHex>() -> T {
| - this type parameter - expected `T` because of return type
12 | 48879
| ^^^^^ expected type parameter `T`, found integer
|
= note: expected type parameter `T`
found type `{integer}`
= help: type parameters must be constrained to match other types
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
The first error can be fixed by adding a type argument, i.e. f::<i64>()
, though I don't understand why it is even needed. And the second is quite confusing and I cannot find a solution except for using impl Trait
syntax.
At any rate, any help at all would be greatly appreciated. And if you'd like to play with code, you can go here.
Thanks in advance!