rust-clippy
rust-clippy copied to clipboard
Catch xor vs power confusion
2x is often written in ASCII as 2^x, but in Rust this happens to xor the value instead of raising it to the power.
let bad = 2^31;
let good = 1<<31;
Apparently, people make that mistake, and so far it goes undetected:
https://twitter.com/johnregehr/status/1139302389612077056
I'm curious: Is there a programming language where x^y means "raise x to the power of y"?
Since writing 2^31 is totally valid rust code and whether it is correct or not strongly depends on the context, I would classify this as a restriction lint.
I think writing this with constants in base ten is highly suspicious and could be a regular or pedantic lint. Especially for 2^x
^ is exponentiation in AWK, BASIC, J, MATLAB, Mathematica, R, Excel, TeX, Haskell, and some others, but I don't think that matters. It's more commonly an ASCII-compatible/keyboard-accessible way to write down exponentiation in docs, readmes, and comments. I presume copying of formulas from other documents is most likely to be the source of this error.
The fact that x^y is technically perfectly valid in Rust is part of the problem, because it'll compile, and just give a result different from what the programmer meant, so this lint is all about second-guessing the programmer.
I think raising 2 and 10 to a power is a much more common operation than xoring constant 2 or 10 with something.
x^y may be anything, but 2^x and 10^x are very suspicious (x^2 maybe, x^10 not).
xoring is all about bits, so the lint shouldn't apply to non-decimal notations (e.g. 0xA^x or x^0b10)
Found this issue after being linked to this GCC thread on the same topic https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90885 - possibly useful for additional context / comments 🙂
My initial reaction was "ha, that definitely sounds like an easy human error to make, and sounds exactly like one of those errors where rustc and/or clippy would go the extra mile in being magically helpful as they always are".
Alas,

I agree that this is probably a high-value lint to add, considering how easy it probably is to make this mistake (ref. ascii documentation etc), and the likelihood of intended behavior of xor vs exponentiation when dealing with decimal values, especially constants.
EDIT: I'll give a try at implementing this 🙂
Commented in closed PR (as it was inactive). Would anybody mind me picking this up and pushing it across the finish line since it's been a while?
Three inactive PR, cool!
Really impressed this isn't solved yet, I got a lucky one! @rustbot claim
Edit: 3 pull requests before mine. Relevant XKCD
I'm curious: Is there a programming language where x^y means "raise x to the power of y"?
In Haskell:
Prelude> 2 ^ 5
32
Prelude> 2 ^^ 5
32.0
In Python ** is used. D language uses ^^.