-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Explicit signedness casts for integers #359
Comments
Bikeshed: These should definitely follow |
The downside is that it makes method chaining a bit uglier with |
What is the intended behavior of |
|
Yes. It's exactly the same operation as |
Re: bikeshedding on It'd be bad if the answer to the question of "how do I reinterpret 64 bits as a numeric type X?" depended on X. It has a good chance of spawning a mnemonic: "from for floats, reInt for ints" or something similar. |
We discussed this in the libs-api meeting today. We're happy to add these methods. Feel free to open a tracking issue and open a PR to rust-lang/rust to add it as an unstable feature. |
Trait methods take precedence over inherent methods nowadays, correct? Trying to determine if there is any future breakage for |
Only while the inherent method is unstable, otherwise it takes precedence. |
Good enough for |
I'm worried about the fact that the names |
Not really. The main problem with
|
Does this need an RFC first, or can I just link to this issue? |
Linking to this issue is sufficient. |
Proposal
Problem statement
Casting using the
as
operator has some issues, in that it does not necessarily reflect the intent of the cast. Was the cast meant to be lossy or not? Was it meant to preserve the size? Constness? Signedness?Some of the motivations for pointer constness casts raised at https://internals.rust-lang.org/t/casting-constness-can-be-risky-heres-a-simple-fix/15933 would apply here too. When refactoring, the sizes of types may change, and silently introduce bugs due to casts not being updated.
Clippy has the
cast_possible_wrap
andcast_sign_loss
lints, which tag sign-changing casts, but since there is no alternative to usingas
, it cannot propose a fix.Motivating examples or use cases
Rust has been slowly introducing alternatives to direct casts, to more clearly signal intent, catch errors, and allow casting only one aspect of a type instead of everything in one go.
From
is used when the cast is lossless,TryFrom
for checked casts,ptr::cast_const
andptr::cast_mut
change the mutability and nothing else,ptr::cast
changes pointed type and nothing else.Solution sketch
Following the example of
ptr::cast_const
andptr::cast_mut
, I propose adding two new methods to integer types, for all X includingsize
:uX::cast_signed() -> iX
iX::cast_unsigned() -> uX
These do the same as a regular
as
cast, but crucially they only cast to another integer of the same size and opposite signedness. They don't ever change the size, soi32
→u64
andu64
→i32
are not implemented.Alternatives
Other names for the two proposed methods would be possible, such as:
reinterpret_*
, following the example of C++.transmute_*
, since this is really a kind of transmute.cast_sign
for both methods. This has the downside of not conveying which direction you're casting in, which the pointer constness methods do indicate.iX::from_bits
andiX::to_bits
, following the example of floats. The methods would only be present on signed integers in this case.It would also be possible to implement this as a trait, like the
explicit_cast
crate does, but since it's a closed class of types, that seems overkill. There have also been proposals to include this under a more general "wrapping cast" or "lossy cast" function/trait of some sort, but I feel that ai32
→u32
cast isn't in the same class of casts asi32
->i16
, since the former is fully reversible and the latter is actually lossy.Links and related work
as
for lossy numeric castsexplicit_cast
crate: https://docs.rs/explicit_cast/latest/explicit_cast/trait.SignCast.htmlThe text was updated successfully, but these errors were encountered: