Skip to content

Commit 264403a

Browse files
committed
extend obfuscated_if_else to support then().unwrap_or_else() and then_some().unwrap_or_else()
1 parent a8b1782 commit 264403a

File tree

5 files changed

+77
-12
lines changed

5 files changed

+77
-12
lines changed

clippy_lints/src/methods/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5367,7 +5367,7 @@ impl Methods {
53675367
option_map_unwrap_or::check(cx, expr, m_recv, m_arg, recv, u_arg, span, &self.msrv);
53685368
},
53695369
Some((then_method @ ("then" | "then_some"), t_recv, [t_arg], _, _)) => {
5370-
obfuscated_if_else::check(cx, expr, t_recv, t_arg, u_arg, then_method);
5370+
obfuscated_if_else::check(cx, expr, t_recv, t_arg, u_arg, then_method, "unwrap_or");
53715371
},
53725372
_ => {},
53735373
}
@@ -5386,6 +5386,9 @@ impl Methods {
53865386
match method_call(recv) {
53875387
Some(("map", recv, [map_arg], _, _))
53885388
if map_unwrap_or::check(cx, expr, recv, map_arg, u_arg, &self.msrv) => {},
5389+
Some((then_method @ ("then" | "then_some"), t_recv, [t_arg], _, _)) => {
5390+
obfuscated_if_else::check(cx, expr, t_recv, t_arg, u_arg, then_method, "unwrap_or_else");
5391+
},
53895392
_ => {
53905393
unnecessary_lazy_eval::check(cx, expr, recv, u_arg, "unwrap_or");
53915394
},

clippy_lints/src/methods/obfuscated_if_else.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub(super) fn check<'tcx>(
1616
then_arg: &'tcx hir::Expr<'_>,
1717
unwrap_arg: &'tcx hir::Expr<'_>,
1818
then_method_name: &str,
19+
unwrap_method_name: &str,
1920
) {
2021
let recv_ty = cx.typeck_results().expr_ty(then_recv);
2122

@@ -32,14 +33,23 @@ pub(super) fn check<'tcx>(
3233
snippet_with_applicability(cx, body.value.span, "..", &mut applicability)
3334
},
3435
"then_some" => snippet_with_applicability(cx, then_arg.span, "..", &mut applicability),
35-
_ => String::new().into(),
36+
_ => return,
37+
};
38+
39+
let els = match unwrap_method_name {
40+
"unwrap_or" => snippet_with_applicability(cx, unwrap_arg.span, "..", &mut applicability),
41+
"unwrap_or_else" if let ExprKind::Closure(closure) = unwrap_arg.kind => {
42+
let body = cx.tcx.hir().body(closure.body);
43+
snippet_with_applicability(cx, body.value.span, "..", &mut applicability)
44+
},
45+
_ => return,
3646
};
3747

3848
let sugg = format!(
3949
"if {} {{ {} }} else {{ {} }}",
4050
Sugg::hir_with_applicability(cx, then_recv, "..", &mut applicability),
4151
if_then,
42-
snippet_with_applicability(cx, unwrap_arg.span, "..", &mut applicability)
52+
els
4353
);
4454

4555
// To be parsed as an expression, the `if { … } else { … }` as the left operand of a binary operator

tests/ui/obfuscated_if_else.fixed

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,20 @@ fn main() {
2424

2525
if true { () } else { a += 2 };
2626
//~^ obfuscated_if_else
27+
28+
let mut n = 1;
29+
if true { n = 1 } else { n = 2 };
30+
//~^ obfuscated_if_else
31+
if true { 1 } else { n * 2 };
32+
//~^ obfuscated_if_else
33+
if true { n += 1 } else { () };
34+
//~^ obfuscated_if_else
35+
36+
let _ = if true { 1 } else { n * 2 };
37+
//~^ obfuscated_if_else
38+
39+
let partial = true.then_some(1);
40+
partial.unwrap_or_else(|| n * 2); // not lint
2741
}
2842

2943
fn issue11141() {

tests/ui/obfuscated_if_else.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,20 @@ fn main() {
2424

2525
true.then_some(()).unwrap_or(a += 2);
2626
//~^ obfuscated_if_else
27+
28+
let mut n = 1;
29+
true.then(|| n = 1).unwrap_or_else(|| n = 2);
30+
//~^ obfuscated_if_else
31+
true.then_some(1).unwrap_or_else(|| n * 2);
32+
//~^ obfuscated_if_else
33+
true.then_some(n += 1).unwrap_or_else(|| ());
34+
//~^ obfuscated_if_else
35+
36+
let _ = true.then_some(1).unwrap_or_else(|| n * 2);
37+
//~^ obfuscated_if_else
38+
39+
let partial = true.then_some(1);
40+
partial.unwrap_or_else(|| n * 2); // not lint
2741
}
2842

2943
fn issue11141() {

tests/ui/obfuscated_if_else.stderr

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,52 +38,76 @@ LL | true.then_some(()).unwrap_or(a += 2);
3838
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { () } else { a += 2 }`
3939

4040
error: this method chain can be written more clearly with `if .. else ..`
41-
--> tests/ui/obfuscated_if_else.rs:31:13
41+
--> tests/ui/obfuscated_if_else.rs:29:5
42+
|
43+
LL | true.then(|| n = 1).unwrap_or_else(|| n = 2);
44+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { n = 1 } else { n = 2 }`
45+
46+
error: this method chain can be written more clearly with `if .. else ..`
47+
--> tests/ui/obfuscated_if_else.rs:31:5
48+
|
49+
LL | true.then_some(1).unwrap_or_else(|| n * 2);
50+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 1 } else { n * 2 }`
51+
52+
error: this method chain can be written more clearly with `if .. else ..`
53+
--> tests/ui/obfuscated_if_else.rs:33:5
54+
|
55+
LL | true.then_some(n += 1).unwrap_or_else(|| ());
56+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { n += 1 } else { () }`
57+
58+
error: this method chain can be written more clearly with `if .. else ..`
59+
--> tests/ui/obfuscated_if_else.rs:36:13
60+
|
61+
LL | let _ = true.then_some(1).unwrap_or_else(|| n * 2);
62+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 1 } else { n * 2 }`
63+
64+
error: this method chain can be written more clearly with `if .. else ..`
65+
--> tests/ui/obfuscated_if_else.rs:45:13
4266
|
4367
LL | let _ = true.then_some(40).unwrap_or(17) | 2;
4468
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(if true { 40 } else { 17 })`
4569

4670
error: this method chain can be written more clearly with `if .. else ..`
47-
--> tests/ui/obfuscated_if_else.rs:35:13
71+
--> tests/ui/obfuscated_if_else.rs:49:13
4872
|
4973
LL | let _ = true.then_some(30).unwrap_or(17) | true.then_some(2).unwrap_or(3) | true.then_some(10).unwrap_or(1);
5074
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(if true { 30 } else { 17 })`
5175

5276
error: this method chain can be written more clearly with `if .. else ..`
53-
--> tests/ui/obfuscated_if_else.rs:35:48
77+
--> tests/ui/obfuscated_if_else.rs:49:48
5478
|
5579
LL | let _ = true.then_some(30).unwrap_or(17) | true.then_some(2).unwrap_or(3) | true.then_some(10).unwrap_or(1);
5680
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 2 } else { 3 }`
5781

5882
error: this method chain can be written more clearly with `if .. else ..`
59-
--> tests/ui/obfuscated_if_else.rs:35:81
83+
--> tests/ui/obfuscated_if_else.rs:49:81
6084
|
6185
LL | let _ = true.then_some(30).unwrap_or(17) | true.then_some(2).unwrap_or(3) | true.then_some(10).unwrap_or(1);
6286
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 10 } else { 1 }`
6387

6488
error: this method chain can be written more clearly with `if .. else ..`
65-
--> tests/ui/obfuscated_if_else.rs:41:17
89+
--> tests/ui/obfuscated_if_else.rs:55:17
6690
|
6791
LL | let _ = 2 | true.then_some(40).unwrap_or(17);
6892
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 40 } else { 17 }`
6993

7094
error: this method chain can be written more clearly with `if .. else ..`
71-
--> tests/ui/obfuscated_if_else.rs:45:13
95+
--> tests/ui/obfuscated_if_else.rs:59:13
7296
|
7397
LL | let _ = true.then_some(42).unwrap_or(17) as u8;
7498
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 42 } else { 17 }`
7599

76100
error: this method chain can be written more clearly with `if .. else ..`
77-
--> tests/ui/obfuscated_if_else.rs:49:14
101+
--> tests/ui/obfuscated_if_else.rs:63:14
78102
|
79103
LL | let _ = *true.then_some(&42).unwrap_or(&17);
80104
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { &42 } else { &17 }`
81105

82106
error: this method chain can be written more clearly with `if .. else ..`
83-
--> tests/ui/obfuscated_if_else.rs:53:14
107+
--> tests/ui/obfuscated_if_else.rs:67:14
84108
|
85109
LL | let _ = *true.then_some(&42).unwrap_or(&17) as u8;
86110
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { &42 } else { &17 }`
87111

88-
error: aborting due to 14 previous errors
112+
error: aborting due to 18 previous errors
89113

0 commit comments

Comments
 (0)