Skip to content

Commit b5941a2

Browse files
committed
Partially outline code inside the panic! macro
1 parent a86e758 commit b5941a2

File tree

4 files changed

+52
-23
lines changed

4 files changed

+52
-23
lines changed

clippy_lints/src/mixed_read_write_in_expression.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,30 @@ impl<'a, 'tcx> DivergenceVisitor<'a, 'tcx> {
134134
}
135135
}
136136

137+
fn stmt_might_diverge(stmt: &Stmt<'_>) -> bool {
138+
match stmt.kind {
139+
StmtKind::Item(..) => false,
140+
_ => true,
141+
}
142+
}
143+
137144
impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> {
138145
fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
139146
match e.kind {
140147
// fix #10776
141148
ExprKind::Block(block, ..) => match (block.stmts, block.expr) {
142-
([], Some(e)) => self.visit_expr(e),
143-
([stmt], None) => match stmt.kind {
144-
StmtKind::Expr(e) | StmtKind::Semi(e) => self.visit_expr(e),
145-
_ => {},
149+
(stmts, Some(e)) => {
150+
if stmts.iter().all(|stmt| !stmt_might_diverge(stmt)) {
151+
self.visit_expr(e)
152+
}
153+
},
154+
([first @ .., stmt], None) => {
155+
if first.iter().all(|stmt| !stmt_might_diverge(stmt)) {
156+
match stmt.kind {
157+
StmtKind::Expr(e) | StmtKind::Semi(e) => self.visit_expr(e),
158+
_ => {},
159+
}
160+
}
146161
},
147162
_ => {},
148163
},

clippy_utils/src/macros.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,16 +227,26 @@ pub enum PanicExpn<'a> {
227227

228228
impl<'a> PanicExpn<'a> {
229229
pub fn parse(expr: &'a Expr<'a>) -> Option<Self> {
230-
let ExprKind::Call(callee, [arg, rest @ ..]) = &expr.kind else {
230+
let ExprKind::Call(callee, args) = &expr.kind else {
231231
return None;
232232
};
233233
let ExprKind::Path(QPath::Resolved(_, path)) = &callee.kind else {
234234
return None;
235235
};
236-
let result = match path.segments.last().unwrap().ident.as_str() {
236+
let name = path.segments.last().unwrap().ident.as_str();
237+
238+
// This has no argument
239+
if name == "panic_cold_explicit" {
240+
return Some(Self::Empty);
241+
};
242+
243+
let [arg, rest @ ..] = args else {
244+
return None;
245+
};
246+
let result = match name {
237247
"panic" if arg.span.ctxt() == expr.span.ctxt() => Self::Empty,
238248
"panic" | "panic_str" => Self::Str(arg),
239-
"panic_display" => {
249+
"panic_display" | "panic_cold_display" => {
240250
let ExprKind::AddrOf(_, _, e) = &arg.kind else {
241251
return None;
242252
};

tests/ui/match_same_arms_non_exhaustive.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@
44
//@no-rustfix
55
use std::sync::atomic::Ordering; // #[non_exhaustive] enum
66

7+
fn repeat() -> ! {
8+
panic!()
9+
}
10+
711
pub fn f(x: Ordering) {
812
match x {
913
Ordering::Relaxed => println!("relaxed"),
1014
Ordering::Release => println!("release"),
1115
Ordering::Acquire => println!("acquire"),
12-
Ordering::AcqRel | Ordering::SeqCst => panic!(),
16+
Ordering::AcqRel | Ordering::SeqCst => repeat(),
1317
#[deny(non_exhaustive_omitted_patterns)]
14-
_ => panic!(),
18+
_ => repeat(),
1519
}
1620
}
1721

@@ -25,8 +29,8 @@ mod f {
2529
Ordering::Relaxed => println!("relaxed"),
2630
Ordering::Release => println!("release"),
2731
Ordering::Acquire => println!("acquire"),
28-
Ordering::AcqRel | Ordering::SeqCst => panic!(),
29-
_ => panic!(),
32+
Ordering::AcqRel | Ordering::SeqCst => repeat(),
33+
_ => repeat(),
3034
}
3135
}
3236
}
@@ -38,9 +42,9 @@ pub fn g(x: Ordering) {
3842
Ordering::Relaxed => println!("relaxed"),
3943
Ordering::Release => println!("release"),
4044
Ordering::Acquire => println!("acquire"),
41-
Ordering::AcqRel | Ordering::SeqCst => panic!(),
45+
Ordering::AcqRel | Ordering::SeqCst => repeat(),
4246
//~^ ERROR: this match arm has an identical body to the `_` wildcard arm
43-
_ => panic!(),
47+
_ => repeat(),
4448
}
4549
}
4650

@@ -52,9 +56,9 @@ mod g {
5256
Ordering::Relaxed => println!("relaxed"),
5357
Ordering::Release => println!("release"),
5458
Ordering::Acquire => println!("acquire"),
55-
Ordering::AcqRel | Ordering::SeqCst => panic!(),
59+
Ordering::AcqRel | Ordering::SeqCst => repeat(),
5660
//~^ ERROR: this match arm has an identical body to the `_` wildcard arm
57-
_ => panic!(),
61+
_ => repeat(),
5862
}
5963
}
6064
}

tests/ui/match_same_arms_non_exhaustive.stderr

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
11
error: this match arm has an identical body to the `_` wildcard arm
2-
--> $DIR/match_same_arms_non_exhaustive.rs:41:9
2+
--> $DIR/match_same_arms_non_exhaustive.rs:45:9
33
|
4-
LL | Ordering::AcqRel | Ordering::SeqCst => panic!(),
4+
LL | Ordering::AcqRel | Ordering::SeqCst => repeat(),
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try removing the arm
66
|
77
= help: or try changing either arm body
88
note: `_` wildcard arm here
9-
--> $DIR/match_same_arms_non_exhaustive.rs:43:9
9+
--> $DIR/match_same_arms_non_exhaustive.rs:47:9
1010
|
11-
LL | _ => panic!(),
11+
LL | _ => repeat(),
1212
| ^^^^^^^^^^^^^
1313
= note: `-D clippy::match-same-arms` implied by `-D warnings`
1414
= help: to override `-D warnings` add `#[allow(clippy::match_same_arms)]`
1515

1616
error: this match arm has an identical body to the `_` wildcard arm
17-
--> $DIR/match_same_arms_non_exhaustive.rs:55:13
17+
--> $DIR/match_same_arms_non_exhaustive.rs:59:13
1818
|
19-
LL | Ordering::AcqRel | Ordering::SeqCst => panic!(),
19+
LL | Ordering::AcqRel | Ordering::SeqCst => repeat(),
2020
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try removing the arm
2121
|
2222
= help: or try changing either arm body
2323
note: `_` wildcard arm here
24-
--> $DIR/match_same_arms_non_exhaustive.rs:57:13
24+
--> $DIR/match_same_arms_non_exhaustive.rs:61:13
2525
|
26-
LL | _ => panic!(),
26+
LL | _ => repeat(),
2727
| ^^^^^^^^^^^^^
2828

2929
error: aborting due to 2 previous errors

0 commit comments

Comments
 (0)