about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJubilee <workingjubilee@gmail.com>2024-10-04 19:19:22 -0700
committerGitHub <noreply@github.com>2024-10-04 19:19:22 -0700
commitf09e5a785b6be5a6c9acacb80c44427bbb0fa2e9 (patch)
treea50254ed6907fb33cbba554718909ece3c7ac9bf
parentbece740dad2061cbc64f067ed80ccf98fdfb78f2 (diff)
parent479779d6a90cc228fc45b5126c558ca52539b2c2 (diff)
downloadrust-f09e5a785b6be5a6c9acacb80c44427bbb0fa2e9.tar.gz
rust-f09e5a785b6be5a6c9acacb80c44427bbb0fa2e9.zip
Rollup merge of #129517 - cjgillot:known-panic-array, r=pnkfelix
Compute array length from type for unconditional panic lint.

Fixes https://github.com/rust-lang/rust/issues/98444

The cases that involve slicing are harder, so https://github.com/rust-lang/rust/issues/38035 remains open.
-rw-r--r--compiler/rustc_mir_transform/src/known_panics_lint.rs16
-rw-r--r--src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.fixed1
-rw-r--r--src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs1
-rw-r--r--src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr2
-rw-r--r--src/tools/clippy/tests/ui/get_unwrap.fixed1
-rw-r--r--src/tools/clippy/tests/ui/get_unwrap.rs1
-rw-r--r--src/tools/clippy/tests/ui/get_unwrap.stderr8
-rw-r--r--tests/ui/lint/unconditional_panic_promoted.rs8
-rw-r--r--tests/ui/lint/unconditional_panic_promoted.stderr10
9 files changed, 36 insertions, 12 deletions
diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs
index ccc029b1e28..8f490094d60 100644
--- a/compiler/rustc_mir_transform/src/known_panics_lint.rs
+++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs
@@ -600,13 +600,15 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
             }
 
             Len(place) => {
-                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,
-                    },
+                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,
+                    }
                 };
                 ImmTy::from_scalar(Scalar::from_target_usize(len, self), layout).into()
             }
diff --git a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.fixed b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.fixed
index baf939af24e..cdb8fa0454c 100644
--- a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.fixed
+++ b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.fixed
@@ -86,6 +86,7 @@ mod issue9612 {
         util();
     }
 
+    #[allow(unconditional_panic)]
     fn util() {
         let _a: u8 = 4.try_into().unwrap();
         let _a: u8 = 5.try_into().expect("");
diff --git a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs
index e300ba18c33..e53d53db5f7 100644
--- a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs
+++ b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs
@@ -86,6 +86,7 @@ mod issue9612 {
         util();
     }
 
+    #[allow(unconditional_panic)]
     fn util() {
         let _a: u8 = 4.try_into().unwrap();
         let _a: u8 = 5.try_into().expect("");
diff --git a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr
index 320578bfabc..b58ce9b8af3 100644
--- a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr
+++ b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr
@@ -274,7 +274,7 @@ LL |     let _ = &boxed_slice[1];
    |             ~~~~~~~~~~~~~~~
 
 error: called `.get().unwrap()` on a slice
-  --> tests/ui-toml/unwrap_used/unwrap_used.rs:93:17
+  --> tests/ui-toml/unwrap_used/unwrap_used.rs:94:17
    |
 LL |         let _ = Box::new([0]).get(1).unwrap();
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/get_unwrap.fixed b/src/tools/clippy/tests/ui/get_unwrap.fixed
index 62beb195939..2dd3c30a4e2 100644
--- a/src/tools/clippy/tests/ui/get_unwrap.fixed
+++ b/src/tools/clippy/tests/ui/get_unwrap.fixed
@@ -70,6 +70,7 @@ fn main() {
 mod issue9909 {
     #![allow(clippy::identity_op, clippy::unwrap_used, dead_code)]
 
+    #[allow(unconditional_panic)]
     fn reduced() {
         let f = &[1, 2, 3];
 
diff --git a/src/tools/clippy/tests/ui/get_unwrap.rs b/src/tools/clippy/tests/ui/get_unwrap.rs
index 1e09ff5c67e..94226564cac 100644
--- a/src/tools/clippy/tests/ui/get_unwrap.rs
+++ b/src/tools/clippy/tests/ui/get_unwrap.rs
@@ -70,6 +70,7 @@ fn main() {
 mod issue9909 {
     #![allow(clippy::identity_op, clippy::unwrap_used, dead_code)]
 
+    #[allow(unconditional_panic)]
     fn reduced() {
         let f = &[1, 2, 3];
 
diff --git a/src/tools/clippy/tests/ui/get_unwrap.stderr b/src/tools/clippy/tests/ui/get_unwrap.stderr
index 0f8b279da1e..8eacb249c60 100644
--- a/src/tools/clippy/tests/ui/get_unwrap.stderr
+++ b/src/tools/clippy/tests/ui/get_unwrap.stderr
@@ -266,7 +266,7 @@ LL |         let _ = some_vec.get_mut(0..1).unwrap().to_vec();
    = help: consider using `expect()` to provide a better panic message
 
 error: called `.get().unwrap()` on a slice
-  --> tests/ui/get_unwrap.rs:77:24
+  --> tests/ui/get_unwrap.rs:78:24
    |
 LL |         let _x: &i32 = f.get(1 + 2).unwrap();
    |                        ^^^^^^^^^^^^^^^^^^^^^
@@ -277,7 +277,7 @@ LL |         let _x: &i32 = &f[1 + 2];
    |                        ~~~~~~~~~
 
 error: called `.get().unwrap()` on a slice
-  --> tests/ui/get_unwrap.rs:80:18
+  --> tests/ui/get_unwrap.rs:81:18
    |
 LL |         let _x = f.get(1 + 2).unwrap().to_string();
    |                  ^^^^^^^^^^^^^^^^^^^^^
@@ -288,7 +288,7 @@ LL |         let _x = f[1 + 2].to_string();
    |                  ~~~~~~~~
 
 error: called `.get().unwrap()` on a slice
-  --> tests/ui/get_unwrap.rs:83:18
+  --> tests/ui/get_unwrap.rs:84:18
    |
 LL |         let _x = f.get(1 + 2).unwrap().abs();
    |                  ^^^^^^^^^^^^^^^^^^^^^
@@ -299,7 +299,7 @@ LL |         let _x = f[1 + 2].abs();
    |                  ~~~~~~~~
 
 error: called `.get_mut().unwrap()` on a slice
-  --> tests/ui/get_unwrap.rs:100:33
+  --> tests/ui/get_unwrap.rs:101:33
    |
 LL |                         let b = rest.get_mut(linidx(j, k) - linidx(i, k) - 1).unwrap();
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/unconditional_panic_promoted.rs b/tests/ui/lint/unconditional_panic_promoted.rs
new file mode 100644
index 00000000000..37bcf046513
--- /dev/null
+++ b/tests/ui/lint/unconditional_panic_promoted.rs
@@ -0,0 +1,8 @@
+//@ 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]
+}
diff --git a/tests/ui/lint/unconditional_panic_promoted.stderr b/tests/ui/lint/unconditional_panic_promoted.stderr
new file mode 100644
index 00000000000..647a84a55fd
--- /dev/null
+++ b/tests/ui/lint/unconditional_panic_promoted.stderr
@@ -0,0 +1,10 @@
+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
+