Taking a shared reference of an array suppresses the unconditional_panic lint
I tried this code:
fn main() {
let xs: [i32; 5] = [1, 2, 3, 4, 5];
let _ = &xs; // this line suppresses the `unconditional_panic` lint
let _ = xs[7];
}
I expected to see this happen:
error: this operation will panic at runtime
--> src/main.rs:4:13
|
4 | let _ = xs[7];
| ^^^^^ index out of bounds: the length is 5 but the index is 7
|
= note: `#[deny(unconditional_panic)]` on by default
Instead, this happened:
thread 'main' panicked at 'index out of bounds: the len is 5 but the index is 7', src/main.rs:4:13
Apparently, taking a shared reference of xs will suppress the unconditional_panic lint. This seems like a false negative. While false negatives can't be avoided entirely, this case seems to be avoidable as taking a shared reference shouldn't change the type of xs (which is [i32; 5]) or modify any data in this example.
Note that
fn main() {
let xs: [i32; 5] = [1, 2, 3, 4, 5];
//let _ = &xs;
let _ = xs[7];
}
will trigger the lint properly.
Meta
rustc --version --verbose:
rustc 1.63.0-nightly (43347397f 2022-06-23)
binary: rustc
commit-hash: 43347397f7c5ca9a670a3bb3890c7187e24a52ab
commit-date: 2022-06-23
host: x86_64-unknown-freebsd
release: 1.63.0-nightly
LLVM version: 14.0.5
See also this thread on URLO.
@rustbot claim
Note this is a problem because the book has an example which is supposed to fail to compile but this bug makes it fail at runtime instead
In case no one has dug into it yet, the error is suppressed in 1.61 but not in 1.60 and before:
$ cargo +1.61 build
Compiling mycrate v0.1.0 (/rust-tests)
Finished dev [unoptimized + debuginfo] target(s) in 0.74s
$ cargo +1.60 build
Compiling mycrate v0.1.0 (/rust-tests)
error: this operation will panic at runtime
--> src/main.rs:129:13
|
129 | let _ = xs[7];
| ^^^^^ index out of bounds: the length is 5 but the index is 7
|
= note: `#[deny(unconditional_panic)]` on by default
error: could not compile `mycrate` due to previous error
warning: build failed, waiting for other jobs to finish...
error: build failed
@rustbot label +regression-from-stable-to-stable
This is caused by #94934. It only ever worked because the lint ran after optimizations.
I made a fix here. It specializes the length of arrays as constant, even if the array isn't. I'm going to open a PR when I have time, probably tomorrow.
In the long term, I'd like to implement some more extensive tracking of "what parts of a value are constant". For example, the compiler currently assumes that anything that had its reference taken can change, but actually, this can only happen inside UnsafeCell (as I understand it).
Labels from the closed duplicate #101470, @rustbot label A-diagnostics, A-lint, A-mir-opt, T-compiler.
Fixed on stable @rustbot label E-needs-test
I claim the add test part
This lint only appears on full builds (not check), but this will be fixed once #108730 lands.
Reopening because I feel this is not yet solved, see Zulip notes on #114840.
As per the prev. comment, #108730 should nail down this issue?
MRE:
fn main() {
let slice = &[0, 1];
let _ = slice[2];
}
Also, duplicate of #38035
Another variant of this same issue: #109260