There isn’t a way to cast integer types into another which may fail. From::from only works if the conversion always succeeds. I suggest we add a coerce(A) -> B function which panics if the conversion fails. There should also be a try_coerce(A) -> Option<B> which simply returns None if the conversion fail. Currently these typically done using the as keyword which does no overflow checking and should rarely be used.
There should also be functions defined on the integers types which converts them to the opposite signness with the same size using a bitcast. This is also current done with as and will result in subtle error if the size of one of them changes.
Third, a bitcast function should be added which does the same thing as as. A lint should be added for as on integer types asking the user to use one of the newly introduced functions.
This is exactly what RFC 1218 proposes. coerce is called cast, try_coerce is checked_cast, bitcast is wrapping_cast.
It’s in the queue since the last summer though, the libs team seems to avoid new numerics in the stdlib at all cost.
I forked it (accept my pull requests) and made a coerce function. I would like the value_into() error to return the original if the conversion failed so I don’t need the Clone bound for error messages.
pub fn coerce<A: ValueInto<B> + Display + Clone, B>(from: A) -> B {
match from.clone().value_into() {
Ok(v) => v,
Err(_) => {
unsafe {
panic!("Cannot coerce value {} of type {} into type {}", from, type_name::<A>(), type_name::<B>())
}
}
}
}
I changed all the error types a while ago to carry the original value so you could get the value back without needing Clone or Copy. I suppose the problem here is that there’s no generic way to extract that value.
Shouldn’t be too disruptive to add a trait for doing so… you’d still need to bound the conversion’s error type by that trait, but it should do the trick.