I have this simple generic function:
fn add_five<T: Into<i32>>(t: T) -> i32 {
5_i32 + t.into()
}
Which I would like to express using the From
trait instead of the Into
trait, however my attempted refactor:
fn add_five<T, i32: From<T>>(t: T) -> i32 {
5_i32 + <i32 as From<T>>::from(t)
}
Throws this compile error:
error[E0277]: cannot add `i32` to `i32`
--> src/main.rs:24:11
|
| 5_i32 + <i32 as From<T>>::from(t)
| ^ no implementation for `i32 + i32`
|
= help: the trait `Add<i32>` is not implemented for `i32`
Which is very confusing, because there is indeed an impl Add<i32> for i32
in the standard library, so what's the real problem?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With