Skip to content

Commit f09e5a7

Browse files
Rollup merge of #129517 - cjgillot:known-panic-array, r=pnkfelix
Compute array length from type for unconditional panic lint. Fixes #98444 The cases that involve slicing are harder, so #38035 remains open.
2 parents bece740 + 479779d commit f09e5a7

File tree

9 files changed

+36
-12
lines changed

9 files changed

+36
-12
lines changed

compiler/rustc_mir_transform/src/known_panics_lint.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -600,13 +600,15 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
600600
}
601601

602602
Len(place) => {
603-
let len = match self.get_const(place)? {
604-
Value::Immediate(src) => src.len(&self.ecx).discard_err()?,
605-
Value::Aggregate { fields, .. } => fields.len() as u64,
606-
Value::Uninit => match place.ty(self.local_decls(), self.tcx).ty.kind() {
607-
ty::Array(_, n) => n.try_eval_target_usize(self.tcx, self.param_env)?,
608-
_ => return None,
609-
},
603+
let len = if let ty::Array(_, n) = place.ty(self.local_decls(), self.tcx).ty.kind()
604+
{
605+
n.try_eval_target_usize(self.tcx, self.param_env)?
606+
} else {
607+
match self.get_const(place)? {
608+
Value::Immediate(src) => src.len(&self.ecx).discard_err()?,
609+
Value::Aggregate { fields, .. } => fields.len() as u64,
610+
Value::Uninit => return None,
611+
}
610612
};
611613
ImmTy::from_scalar(Scalar::from_target_usize(len, self), layout).into()
612614
}

src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.fixed

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ mod issue9612 {
8686
util();
8787
}
8888

89+
#[allow(unconditional_panic)]
8990
fn util() {
9091
let _a: u8 = 4.try_into().unwrap();
9192
let _a: u8 = 5.try_into().expect("");

src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ mod issue9612 {
8686
util();
8787
}
8888

89+
#[allow(unconditional_panic)]
8990
fn util() {
9091
let _a: u8 = 4.try_into().unwrap();
9192
let _a: u8 = 5.try_into().expect("");

src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ LL | let _ = &boxed_slice[1];
274274
| ~~~~~~~~~~~~~~~
275275

276276
error: called `.get().unwrap()` on a slice
277-
--> tests/ui-toml/unwrap_used/unwrap_used.rs:93:17
277+
--> tests/ui-toml/unwrap_used/unwrap_used.rs:94:17
278278
|
279279
LL | let _ = Box::new([0]).get(1).unwrap();
280280
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

src/tools/clippy/tests/ui/get_unwrap.fixed

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ fn main() {
7070
mod issue9909 {
7171
#![allow(clippy::identity_op, clippy::unwrap_used, dead_code)]
7272

73+
#[allow(unconditional_panic)]
7374
fn reduced() {
7475
let f = &[1, 2, 3];
7576

src/tools/clippy/tests/ui/get_unwrap.rs

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ fn main() {
7070
mod issue9909 {
7171
#![allow(clippy::identity_op, clippy::unwrap_used, dead_code)]
7272

73+
#[allow(unconditional_panic)]
7374
fn reduced() {
7475
let f = &[1, 2, 3];
7576

src/tools/clippy/tests/ui/get_unwrap.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec();
266266
= help: consider using `expect()` to provide a better panic message
267267

268268
error: called `.get().unwrap()` on a slice
269-
--> tests/ui/get_unwrap.rs:77:24
269+
--> tests/ui/get_unwrap.rs:78:24
270270
|
271271
LL | let _x: &i32 = f.get(1 + 2).unwrap();
272272
| ^^^^^^^^^^^^^^^^^^^^^
@@ -277,7 +277,7 @@ LL | let _x: &i32 = &f[1 + 2];
277277
| ~~~~~~~~~
278278

279279
error: called `.get().unwrap()` on a slice
280-
--> tests/ui/get_unwrap.rs:80:18
280+
--> tests/ui/get_unwrap.rs:81:18
281281
|
282282
LL | let _x = f.get(1 + 2).unwrap().to_string();
283283
| ^^^^^^^^^^^^^^^^^^^^^
@@ -288,7 +288,7 @@ LL | let _x = f[1 + 2].to_string();
288288
| ~~~~~~~~
289289

290290
error: called `.get().unwrap()` on a slice
291-
--> tests/ui/get_unwrap.rs:83:18
291+
--> tests/ui/get_unwrap.rs:84:18
292292
|
293293
LL | let _x = f.get(1 + 2).unwrap().abs();
294294
| ^^^^^^^^^^^^^^^^^^^^^
@@ -299,7 +299,7 @@ LL | let _x = f[1 + 2].abs();
299299
| ~~~~~~~~
300300

301301
error: called `.get_mut().unwrap()` on a slice
302-
--> tests/ui/get_unwrap.rs:100:33
302+
--> tests/ui/get_unwrap.rs:101:33
303303
|
304304
LL | let b = rest.get_mut(linidx(j, k) - linidx(i, k) - 1).unwrap();
305305
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//@ build-fail
2+
3+
fn main() {
4+
// MIR encodes this as a reborrow from a promoted constant.
5+
// But the array lenth can still be gotten from the type.
6+
let slice = &[0, 1];
7+
let _ = slice[2]; //~ ERROR: this operation will panic at runtime [unconditional_panic]
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: this operation will panic at runtime
2+
--> $DIR/unconditional_panic_promoted.rs:7:13
3+
|
4+
LL | let _ = slice[2];
5+
| ^^^^^^^^ index out of bounds: the length is 2 but the index is 2
6+
|
7+
= note: `#[deny(unconditional_panic)]` on by default
8+
9+
error: aborting due to 1 previous error
10+

0 commit comments

Comments
 (0)