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 { - 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