Skip to content
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

Shift operators: signed RHS, Wrapping impl #27601

Closed
TimNN opened this issue Aug 8, 2015 · 2 comments
Closed

Shift operators: signed RHS, Wrapping impl #27601

TimNN opened this issue Aug 8, 2015 · 2 comments

Comments

@TimNN
Copy link
Contributor

TimNN commented Aug 8, 2015

1. Shift operators are defined for signed RHS types
The following fails to compile: 1u32 << -1i32; this compiles: let i = -1i32; 1u32 << i but panics due to overflow in debug mode and evaluates to 0 or 2147483648 in release mode, depending on whether the u32 value is even or odd (which leads me to believe that internally the signed value is just cast to an unsigned one).

My preferred solution would be to remove the Sh* impls for signed RHS types, but I understand that this might not be possible due to backwards compatibility reasons. If this is the case I would vote for fixing the signed impls by conditionally calling the opposite or some other way because the current behaviour is pretty bad in my opinion.

2. The shift impl of Wrapping is not wrapping
The Sh* operators for Wrapping are currently only defined for usize as the RHS (because of #23545) with the plan to support all integer types as the RHS once that issue is fixed. This is not a problem, however the current implementation is because it is implemented using the << and >> operators on the primitive value, which does obviously not perform a wrapping shift.

The solution would obviously be to use the wrapping_sh* method on the primitive types, however they are only defined for a RHS = u32, which would require some nontrivial logic to convert usize (on 64bit platforms) to that u32.

Furthermore, I found that there is currently no way to solve the problem (in stable rust) which originally caused me to discover these issues: Given 1u8 << 8 I want to get 0 as a result without panicking and ideally without reimplementing std::num::wrapping::OverflowingOps which is currently unstable (and even if used would still require a condition on my part).

I would love to hear some opinions on these issues and would be open to implement a solution, if found / required.

@steveklabnik
Copy link
Member

/cc @rust-lang/libs

@steveklabnik
Copy link
Member

Triage: no comments in 18 months. @TimNN , these kinds of discussions are usually better on http://internals.rust-lang.org/. Mind opening up something there if any of this is still relevant or if you still care about this? Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants