Adding a trait bound to a non-generic type can only be done from the where clause:
fn add_five<T>(t: T) -> i32
where
i32: From<T> // now compiles!
{
5_i32 + <i32 as From<T>>::from(t)
}
The reason <T, i32: From<T>>
fails is because the compiler parses all of the names used within <>
as identifiers for generic type parameters.
The error message is confusing because the compiler doesn't clarify when i32
refers to the concrete 32-bit signed integer type vs the function-local identifier for a generic type parameter by the same name (which also now shadows the concrete integer type).
Here's the error message but with added clarifications:
error[E0277]: cannot add `i32` (generic type) to `i32` (concrete integer type)
--> src/main.rs:24:11
|
| 5_i32 + <i32 (generic type) as From<T>>::from(t)
| ^ no implementation for `i32 (concrete integer type) + i32 (generic type)`
|
= help: the trait `Add<i32 (generic type)>` is not implemented for `i32` (concrete integer type)
Or to substitute the confusingly ambiguous i32
for the more conventional U
as the generic type:
error[E0277]: cannot add `U` to `i32`
--> src/main.rs:24:11
|
| 5_i32 + <U as From<T>>::from(t)
| ^ no implementation for `i32 + U`
|
= help: the trait `Add<U>` is not implemented for `i32`
The fix is to simply move the bound into the where clause, as stated above, to avoid accidentally declaring i32
as a generic type.