Change:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: Instead, this happened: Apparently, taking a shared reference of will suppress the 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 (which is ) or modify any data in this example. Note that will trigger the lint properly. : <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
See also .
claim
Note this is a problem because 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 but not in and before:
label +regression-from-stable-to-stable
WG-prioritization assigning priority (). label -I-prioritize +P-medium
This is caused by . It only ever worked because the lint ran after optimizations. I made a fix . 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 (as I understand it).
Labels from the closed duplicate , label A-diagnostics, A-lint, A-mir-opt, T-compiler.
Fixed on stable 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 lands.
Reopening because I feel this is not yet solved, see on . As per the , should nail down this issue?
MRE: Also, duplicate of
Another variant of this same issue:

Discussion:
} Len(place) => { <del> let len = match self.get_const(place)? { Value::Immediate(src) => src.len(&self.ecx).discard_err()?, Value::Aggregate { fields, .. } => fields.len() as u64, Value::Uninit => match place.ty(self.local_decls(), self.tcx).ty.kind() { ty::Array(_, n) => n.try_eval_target_usize(self.tcx, self.param_env)?, _ => return None, }, </del> <ins> let len = if let ty::Array(_, n) = place.ty(self.local_decls(), self.tcx).ty.kind() { n.try_eval_target_usize(self.tcx, self.param_env)? } else { match self.get_const(place)? { Value::Immediate(src) => src.len(&self.ecx).discard_err()?, Value::Aggregate { fields, .. } => fields.len() as u64, Value::Uninit => return None, } </ins> }; ImmTy::from_scalar(Scalar::from_target_usize(len, self), layout).into() }

util(); } <ins> #[allow(unconditional_panic)] </ins> fn util() { let _a: u8 = 4.try_into().unwrap(); let _a: u8 = 5.try_into().expect("");

|             ~~~~~~~~~~~~~~~ error: called `.get().unwrap()` on a slice <del> --> tests/ui-toml/unwrap_used/unwrap_used.rs:93:17 </del> <ins> --> tests/ui-toml/unwrap_used/unwrap_used.rs:94:17 </ins> | LL |         let _ = Box::new([0]).get(1).unwrap(); |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

mod issue9909 { #![allow(clippy::identity_op, clippy::unwrap_used, dead_code)] <ins> #[allow(unconditional_panic)] </ins> fn reduced() { let f = &[1, 2, 3];

= help: consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a slice <del> --> tests/ui/get_unwrap.rs:77:24 </del> <ins> --> tests/ui/get_unwrap.rs:78:24 </ins> | LL |         let _x: &i32 = f.get(1 + 2).unwrap(); |                        ^^^^^^^^^^^^^^^^^^^^^

|                        ~~~~~~~~~ error: called `.get().unwrap()` on a slice <del> --> tests/ui/get_unwrap.rs:80:18 </del> <ins> --> tests/ui/get_unwrap.rs:81:18 </ins> | LL |         let _x = f.get(1 + 2).unwrap().to_string(); |                  ^^^^^^^^^^^^^^^^^^^^^

|                  ~~~~~~~~ error: called `.get().unwrap()` on a slice <del> --> tests/ui/get_unwrap.rs:83:18 </del> <ins> --> tests/ui/get_unwrap.rs:84:18 </ins> | LL |         let _x = f.get(1 + 2).unwrap().abs(); |                  ^^^^^^^^^^^^^^^^^^^^^

|                  ~~~~~~~~ error: called `.get_mut().unwrap()` on a slice <del> --> tests/ui/get_unwrap.rs:100:33 </del> <ins> --> tests/ui/get_unwrap.rs:101:33 </ins> | LL |                         let b = rest.get_mut(linidx(j, k) - linidx(i, k) - 1).unwrap(); |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

<ins> //@ build-fail fn main() { // MIR encodes this as a reborrow from a promoted constant. // But the array lenth can still be gotten from the type. let slice = &[0, 1]; let _ = slice[2]; //~ ERROR: this operation will panic at runtime [unconditional_panic] } </ins>

<ins> error: this operation will panic at runtime --> $DIR/unconditional_panic_promoted.rs:7:13 | LL |     let _ = slice[2]; |             ^^^^^^^^ index out of bounds: the length is 2 but the index is 2 | = note: `#[deny(unconditional_panic)]` on by default error: aborting due to 1 previous error </ins>