Description
Background
For converting between different primitive integer types we have impls of the From
trait (and so of TryFrom<Error=!>
through the generic impl<T, U> TryFrom<T> for U where U: From<T>
) for conversions that always succeed (for example u8
to u32
), and TryFrom<Error=TryFromIntError>
for other conversions (for example u32
to u8
, which return Err(_)
on values that would overflow).
When usize
or isize
is involved however, some conversions can be fallible or infallible depending on the target platform’s pointer width. (For example u64
to usize
on 64-bit v.s. 32-bit platforms.)
There is desire to make such impls infallible with From
whenever possible. Since APIs would be different on the target platform, their usage should be gated on a portability lint that is not implemented yet. (The lint would additionally need to be able to "see" that a non-portable impl is used indirectly through a generic impl like impl<T, U> TryFrom<T> for U where U: From<T>
or impl<T, U> Into<U> for T where U: From<T>
.)
A downside of this is that even code that would be portable because it doesn’t care about the error type (because it only tests for the presence of an error, or works in both case though e.g. the From
conversion inside the ?
operator) would still need top opt into "non-portability" in order to silence the lint.
In order to be able to stabilize the TryFrom
trait without waiting for the portability lint to be implemented, #49305 removed the affected impls. They are those marked NP
in the table in #49305 (comment):
TryFrom<usize>
foru16
,u32
,u64
,u128
,i32
,i64
,i128
TryFrom<isize>
fori16
,i32
,i64
,i128
TryFrom<_> for usize
:u32
,u64
,u128
TryFrom<_> for isize
:u16
,u32
,u64
,u128
,i32
,i64
,i128
Alternatives
We want to have these impls eventually, but need to chose between:
- Different APIs based on the target platform, with a portability lint
- Give up on static-infallibility-on-some-platforms and make these impls apparently-fallible with
TryFrom<Error=TryFromIntError>
on all platforms.