Open
Description
I tried this code:
macro_rules! set_bit {
($bb:expr, $sq:expr) => {
{
let mut bb = $bb as u64;
let sq = $sq as i32;
if sq >= 0 && sq < 64 {
bb |= (1u64 << $sq);
}
bb
}
};
}
I expected to see this happen: i expected the code to run if i simply passed sq=64 to the macro as an parameter, however it threw an:
error: this arithmetic operation will overflow
--> main.rs:10:23
|
10 | bb |= (1u64 << $sq);
| ^^^^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
...
63 | println!("{}", set_bit!(0, 64));
| --------------- in this macro invocation
|
= note: `#[deny(arithmetic_overflow)]` on by default
= note: this error originates in the macro `set_bit` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error; 4 warnings emitted
which is pretty strange since it will never be able to actually perform the bitwise if sq >= 64.
It's also to note if i change the bitwise operation to bb |= (1u64 << sq);
(removing the dollar sign) it won't throw this error.
I thinks this is due to an oversight where if the sq operator is copied to an different variable it won't release a if-statement is done to prevent a arithmetic_overflow.
Meta
rustc --version --verbose
:
rustc 1.66.1 (90743e729 2023-01-10) (built from a source tarball)
binary: rustc
commit-hash: 90743e7298aca107ddaa0c202a4d3604e29bfeb6
commit-date: 2023-01-10
host: x86_64-unknown-linux-gnu
release: 1.66.1
LLVM version: 15.0.7
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
saethlin commentedon Jul 21, 2023
Here's a significantly more silly minimized version:
The problem is that the lint here has trouble seeing that code is dead. Something about the way we lower
&&
confuses it.[-]Incorrect overflow error in macro[/-][+]const_prop_lint can't tell when code guarded with && is dead[/+]cjgillot commentedon Jul 22, 2023
#111752 may help with that. To check once it lands.
chenyukang commentedon Jul 23, 2023
Even this code also don't have a lint?
I expect something like
any code following this block is unreachable
.saethlin commentedon Jul 24, 2023
@chenyukang In current stable, that code correctly does not have a lint. In 1.69 and before, it actually did hit this lint. So things have gotten better recently, but it's still too easy to hit these scuffed cases.
chenyukang commentedon Jul 24, 2023
The result of 1.67.1 for code:
is:
Should we check the
if-else
branch with some kind of const-eval checking? I expect the result is something like this:We have
warn_if_unreachable
, but seems it only checking expressions followingreturn
orpanic!
.rust/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Line 49 in 8771282
saethlin commentedon Jul 24, 2023
The lint that we are discussing here lints by running the const eval interpreter.
We definitely should not warn or error on
if false {
, that's for example whatdebug_assert!
expands to when debug assertions are off. The concern in this issue is that we shouldn't report unconditional panics in unreachable code. Because the panic isn't a problem.RalfJung commentedon Mar 18, 2024
I think this is a duplicate of #109731?
veera-sivarajan commentedon Jul 18, 2024
Output on
rustc 1.79.0
for code:Output: