Shouldn't the implementations of TryFrom for integer types be infallible for unbounded conversions?

While writing a small embedded program I came across the fact that the implementation of TryFrom<u32> for usize in platforms where the pointer size is 32 bits has an Error type of TryFromIntError. In fact, all unbounded integer conversions in core are defined through the use of this macro, present in

// no possible bounds violation
macro_rules! try_from_unbounded {
    ($source:ty, $($target:ty),*) => {$(
        #[stable(feature = "try_from", since = "1.34.0")]
        #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")]
        impl const TryFrom<$source> for $target {
            type Error = TryFromIntError;

            /// Try to create the target number type from a source
            /// number type. This returns an error if the source value
            /// is outside of the range of the target type.
            fn try_from(value: $source) -> Result<Self, Self::Error> {
                Ok(value as Self)

Is there any reason for the error type here to be a "real" error type, rather than Infallible or !? I haven't been able to come up with anything on my own, so I'm wondering if anyone knows what the reason for it is.

I especially don't understand why that's the case as having it be infallible would also open up the possibility of, for instance, using Result::into_ok to check a for a lossless conversion at compile time, rather than at runtime. A feature which would come in handy for embedded applications, where the usefulness of a panic is limited.

It started out as you suggest, but that conditional-infallibility was seen as a portability footgun. See the tracking issue for the discussion:


Well, I guess that makes sense then. Thank you!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.