about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/mixed_read_write_in_expression.rs23
-rw-r--r--clippy_utils/src/macros.rs16
-rw-r--r--tests/ui/match_same_arms_non_exhaustive.rs20
-rw-r--r--tests/ui/match_same_arms_non_exhaustive.stderr16
4 files changed, 52 insertions, 23 deletions
diff --git a/clippy_lints/src/mixed_read_write_in_expression.rs b/clippy_lints/src/mixed_read_write_in_expression.rs
index 367cd6bd413..ea6a9bc5657 100644
--- a/clippy_lints/src/mixed_read_write_in_expression.rs
+++ b/clippy_lints/src/mixed_read_write_in_expression.rs
@@ -134,15 +134,30 @@ impl<'a, 'tcx> DivergenceVisitor<'a, 'tcx> {
     }
 }
 
+fn stmt_might_diverge(stmt: &Stmt<'_>) -> bool {
+    match stmt.kind {
+        StmtKind::Item(..) => false,
+        _ => true,
+    }
+}
+
 impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> {
     fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
         match e.kind {
             // fix #10776
             ExprKind::Block(block, ..) => match (block.stmts, block.expr) {
-                ([], Some(e)) => self.visit_expr(e),
-                ([stmt], None) => match stmt.kind {
-                    StmtKind::Expr(e) | StmtKind::Semi(e) => self.visit_expr(e),
-                    _ => {},
+                (stmts, Some(e)) => {
+                    if stmts.iter().all(|stmt| !stmt_might_diverge(stmt)) {
+                        self.visit_expr(e)
+                    }
+                },
+                ([first @ .., stmt], None) => {
+                    if first.iter().all(|stmt| !stmt_might_diverge(stmt)) {
+                        match stmt.kind {
+                            StmtKind::Expr(e) | StmtKind::Semi(e) => self.visit_expr(e),
+                            _ => {},
+                        }
+                    }
                 },
                 _ => {},
             },
diff --git a/clippy_utils/src/macros.rs b/clippy_utils/src/macros.rs
index 173f9841d44..94334f55109 100644
--- a/clippy_utils/src/macros.rs
+++ b/clippy_utils/src/macros.rs
@@ -227,16 +227,26 @@ pub enum PanicExpn<'a> {
 
 impl<'a> PanicExpn<'a> {
     pub fn parse(expr: &'a Expr<'a>) -> Option<Self> {
-        let ExprKind::Call(callee, [arg, rest @ ..]) = &expr.kind else {
+        let ExprKind::Call(callee, args) = &expr.kind else {
             return None;
         };
         let ExprKind::Path(QPath::Resolved(_, path)) = &callee.kind else {
             return None;
         };
-        let result = match path.segments.last().unwrap().ident.as_str() {
+        let name = path.segments.last().unwrap().ident.as_str();
+
+        // This has no argument
+        if name == "panic_cold_explicit" {
+            return Some(Self::Empty);
+        };
+
+        let [arg, rest @ ..] = args else {
+            return None;
+        };
+        let result = match name {
             "panic" if arg.span.ctxt() == expr.span.ctxt() => Self::Empty,
             "panic" | "panic_str" => Self::Str(arg),
-            "panic_display" => {
+            "panic_display" | "panic_cold_display" => {
                 let ExprKind::AddrOf(_, _, e) = &arg.kind else {
                     return None;
                 };
diff --git a/tests/ui/match_same_arms_non_exhaustive.rs b/tests/ui/match_same_arms_non_exhaustive.rs
index 1ee048bf7f6..e1b95aa5776 100644
--- a/tests/ui/match_same_arms_non_exhaustive.rs
+++ b/tests/ui/match_same_arms_non_exhaustive.rs
@@ -4,14 +4,18 @@
 //@no-rustfix
 use std::sync::atomic::Ordering; // #[non_exhaustive] enum
 
+fn repeat() -> ! {
+    panic!()
+}
+
 pub fn f(x: Ordering) {
     match x {
         Ordering::Relaxed => println!("relaxed"),
         Ordering::Release => println!("release"),
         Ordering::Acquire => println!("acquire"),
-        Ordering::AcqRel | Ordering::SeqCst => panic!(),
+        Ordering::AcqRel | Ordering::SeqCst => repeat(),
         #[deny(non_exhaustive_omitted_patterns)]
-        _ => panic!(),
+        _ => repeat(),
     }
 }
 
@@ -25,8 +29,8 @@ mod f {
             Ordering::Relaxed => println!("relaxed"),
             Ordering::Release => println!("release"),
             Ordering::Acquire => println!("acquire"),
-            Ordering::AcqRel | Ordering::SeqCst => panic!(),
-            _ => panic!(),
+            Ordering::AcqRel | Ordering::SeqCst => repeat(),
+            _ => repeat(),
         }
     }
 }
@@ -38,9 +42,9 @@ pub fn g(x: Ordering) {
         Ordering::Relaxed => println!("relaxed"),
         Ordering::Release => println!("release"),
         Ordering::Acquire => println!("acquire"),
-        Ordering::AcqRel | Ordering::SeqCst => panic!(),
+        Ordering::AcqRel | Ordering::SeqCst => repeat(),
         //~^ ERROR: this match arm has an identical body to the `_` wildcard arm
-        _ => panic!(),
+        _ => repeat(),
     }
 }
 
@@ -52,9 +56,9 @@ mod g {
             Ordering::Relaxed => println!("relaxed"),
             Ordering::Release => println!("release"),
             Ordering::Acquire => println!("acquire"),
-            Ordering::AcqRel | Ordering::SeqCst => panic!(),
+            Ordering::AcqRel | Ordering::SeqCst => repeat(),
             //~^ ERROR: this match arm has an identical body to the `_` wildcard arm
-            _ => panic!(),
+            _ => repeat(),
         }
     }
 }
diff --git a/tests/ui/match_same_arms_non_exhaustive.stderr b/tests/ui/match_same_arms_non_exhaustive.stderr
index a039536338b..ae6b02ab1b5 100644
--- a/tests/ui/match_same_arms_non_exhaustive.stderr
+++ b/tests/ui/match_same_arms_non_exhaustive.stderr
@@ -1,29 +1,29 @@
 error: this match arm has an identical body to the `_` wildcard arm
-  --> $DIR/match_same_arms_non_exhaustive.rs:41:9
+  --> $DIR/match_same_arms_non_exhaustive.rs:45:9
    |
-LL |         Ordering::AcqRel | Ordering::SeqCst => panic!(),
+LL |         Ordering::AcqRel | Ordering::SeqCst => repeat(),
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try removing the arm
    |
    = help: or try changing either arm body
 note: `_` wildcard arm here
-  --> $DIR/match_same_arms_non_exhaustive.rs:43:9
+  --> $DIR/match_same_arms_non_exhaustive.rs:47:9
    |
-LL |         _ => panic!(),
+LL |         _ => repeat(),
    |         ^^^^^^^^^^^^^
    = note: `-D clippy::match-same-arms` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::match_same_arms)]`
 
 error: this match arm has an identical body to the `_` wildcard arm
-  --> $DIR/match_same_arms_non_exhaustive.rs:55:13
+  --> $DIR/match_same_arms_non_exhaustive.rs:59:13
    |
-LL |             Ordering::AcqRel | Ordering::SeqCst => panic!(),
+LL |             Ordering::AcqRel | Ordering::SeqCst => repeat(),
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try removing the arm
    |
    = help: or try changing either arm body
 note: `_` wildcard arm here
-  --> $DIR/match_same_arms_non_exhaustive.rs:57:13
+  --> $DIR/match_same_arms_non_exhaustive.rs:61:13
    |
-LL |             _ => panic!(),
+LL |             _ => repeat(),
    |             ^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors