Skip to content

Commit 11d2af7

Browse files
committed
Improve suggestion and make it work for macros
1 parent 0327c2e commit 11d2af7

File tree

3 files changed

+62
-6
lines changed

3 files changed

+62
-6
lines changed

clippy_lints/src/if_then_some_else_none.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,22 @@ impl LateLintPass<'_> for IfThenSomeElseNone {
8282
if let ExprKind::Path(ref els_call_qpath) = els_expr.kind;
8383
if utils::match_qpath(els_call_qpath, &utils::paths::OPTION_NONE);
8484
then {
85-
let cond_snip = utils::snippet(cx, cond.span, "[condition]");
86-
let arg_snip = utils::snippet(cx, then_arg.span, "");
85+
let cond_snip = utils::snippet_with_macro_callsite(cx, cond.span, "[condition]");
86+
let cond_snip = if matches!(cond.kind, ExprKind::Unary(_, _) | ExprKind::Binary(_, _, _)) {
87+
format!("({})", cond_snip)
88+
} else {
89+
cond_snip.into_owned()
90+
};
91+
let arg_snip = utils::snippet_with_macro_callsite(cx, then_arg.span, "");
92+
let closure_body = if then_block.stmts.is_empty() {
93+
arg_snip.into_owned()
94+
} else {
95+
format!("{{ /* snippet */ {} }}", arg_snip)
96+
};
8797
let help = format!(
88-
"consider using `bool::then` like: `{}.then(|| {{ /* snippet */ {} }})`",
98+
"consider using `bool::then` like: `{}.then(|| {})`",
8999
cond_snip,
90-
arg_snip,
100+
closure_body,
91101
);
92102
utils::span_lint_and_help(
93103
cx,

tests/ui/if_then_some_else_none.rs

+16
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,22 @@ fn main() {
1010
None
1111
};
1212

13+
// Should issue an error when macros are used.
14+
let _ = if matches!(true, true) {
15+
println!("true!");
16+
Some(matches!(true, false))
17+
} else {
18+
None
19+
};
20+
21+
// Should issue an error. Binary expression `o < 32` should be parenthesized.
22+
let x = Some(5);
23+
let _ = x.and_then(|o| if o < 32 { Some(o) } else { None });
24+
25+
// Should issue an error. Unary expression `!x` should be parenthesized.
26+
let x = true;
27+
let _ = if !x { Some(0) } else { None };
28+
1329
// Should not issue an error since the `else` block has a statement besides `None`.
1430
let _ = if foo() {
1531
println!("true!");

tests/ui/if_then_some_else_none.stderr

+32-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,37 @@ LL | | };
1414
= help: consider using `bool::then` like: `foo().then(|| { /* snippet */ "foo" })`
1515

1616
error: this could be simplified with `bool::then`
17-
--> $DIR/if_then_some_else_none.rs:66:13
17+
--> $DIR/if_then_some_else_none.rs:14:13
18+
|
19+
LL | let _ = if matches!(true, true) {
20+
| _____________^
21+
LL | | println!("true!");
22+
LL | | Some(matches!(true, false))
23+
LL | | } else {
24+
LL | | None
25+
LL | | };
26+
| |_____^
27+
|
28+
= help: consider using `bool::then` like: `matches!(true, true).then(|| { /* snippet */ matches!(true, false) })`
29+
30+
error: this could be simplified with `bool::then`
31+
--> $DIR/if_then_some_else_none.rs:23:28
32+
|
33+
LL | let _ = x.and_then(|o| if o < 32 { Some(o) } else { None });
34+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
35+
|
36+
= help: consider using `bool::then` like: `(o < 32).then(|| o)`
37+
38+
error: this could be simplified with `bool::then`
39+
--> $DIR/if_then_some_else_none.rs:27:13
40+
|
41+
LL | let _ = if !x { Some(0) } else { None };
42+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
43+
|
44+
= help: consider using `bool::then` like: `(!x).then(|| 0)`
45+
46+
error: this could be simplified with `bool::then`
47+
--> $DIR/if_then_some_else_none.rs:82:13
1848
|
1949
LL | let _ = if foo() {
2050
| _____________^
@@ -27,5 +57,5 @@ LL | | };
2757
|
2858
= help: consider using `bool::then` like: `foo().then(|| { /* snippet */ 150 })`
2959

30-
error: aborting due to 2 previous errors
60+
error: aborting due to 5 previous errors
3161

0 commit comments

Comments
 (0)