Skip to content

Commit 7ba8b14

Browse files
committed
fix: if_then_some_else_none suggests wrongly when then ends with comment
1 parent 34fab5c commit 7ba8b14

File tree

4 files changed

+133
-16
lines changed

4 files changed

+133
-16
lines changed

clippy_lints/src/if_then_some_else_none.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,19 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
109109
.maybe_paren()
110110
.to_string();
111111
let arg_snip = snippet_with_context(cx, then_arg.span, ctxt, "[body]", &mut app).0;
112-
let method_body = if let Some(first_stmt) = then_block.stmts.first()
113-
&& let Some(first_stmt_span) = walk_span_to_context(first_stmt.span, ctxt)
112+
let method_body = if let Some(_) = then_block.stmts.first()
113+
&& let Some(then_span) = walk_span_to_context(then.span, ctxt)
114114
{
115-
let block_snippet =
116-
snippet_with_applicability(cx, first_stmt_span.until(then_expr.span), "..", &mut app);
115+
let block_before_snippet =
116+
snippet_with_applicability(cx, then_span.until(then_expr.span), "..", &mut app);
117+
let block_after_snippet = snippet_with_applicability(
118+
cx,
119+
then_expr.span.shrink_to_hi().until(then_span.shrink_to_hi()),
120+
"..",
121+
&mut app,
122+
);
117123
let closure = if method_name == sym::then { "|| " } else { "" };
118-
format!("{closure} {{ {} {arg_snip} }}", block_snippet.trim_end())
124+
format!("{closure}{block_before_snippet}{arg_snip}{block_after_snippet}")
119125
} else if method_name == sym::then {
120126
(std::borrow::Cow::Borrowed("|| ") + arg_snip).into_owned()
121127
} else {

tests/ui/if_then_some_else_none.fixed

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,20 @@
33

44
fn main() {
55
// Should issue an error.
6-
let _ = foo().then(|| { println!("true!"); "foo" });
6+
let _ = foo().then(|| {
7+
//~^ if_then_some_else_none
8+
9+
println!("true!");
10+
"foo"
11+
});
712

813
// Should issue an error when macros are used.
9-
let _ = matches!(true, true).then(|| { println!("true!"); matches!(true, false) });
14+
let _ = matches!(true, true).then(|| {
15+
//~^ if_then_some_else_none
16+
17+
println!("true!");
18+
matches!(true, false)
19+
});
1020

1121
// Should issue an error. Binary expression `o < 32` should be parenthesized.
1222
let x = Some(5);
@@ -71,7 +81,12 @@ fn _msrv_1_49() {
7181

7282
#[clippy::msrv = "1.50"]
7383
fn _msrv_1_50() {
74-
let _ = foo().then(|| { println!("true!"); 150 });
84+
let _ = foo().then(|| {
85+
//~^ if_then_some_else_none
86+
87+
println!("true!");
88+
150
89+
});
7590
}
7691

7792
fn foo() -> bool {
@@ -182,7 +197,10 @@ fn issue15005() {
182197

183198
fn next(&mut self) -> Option<Self::Item> {
184199
//~v if_then_some_else_none
185-
(self.count < 5).then(|| { self.count += 1; self.count })
200+
(self.count < 5).then(|| {
201+
self.count += 1;
202+
self.count
203+
})
186204
}
187205
}
188206
}
@@ -195,7 +213,10 @@ fn statements_from_macro() {
195213
};
196214
}
197215
//~v if_then_some_else_none
198-
let _ = true.then(|| { mac!(); 42 });
216+
let _ = true.then(|| {
217+
mac!();
218+
42
219+
});
199220
}
200221

201222
fn dont_lint_inside_macros() {
@@ -228,3 +249,14 @@ mod issue16176 {
228249
if cond { Some(foo().await) } else { None } // OK
229250
}
230251
}
252+
253+
fn issue16269() -> Option<i32> {
254+
use std::cell::UnsafeCell;
255+
256+
//~v if_then_some_else_none
257+
(1 <= 3).then(|| {
258+
let a = UnsafeCell::new(1);
259+
// SAFETY: `bytes` bytes starting at `new_end` were just reserved.
260+
unsafe { *a.get() }
261+
})
262+
}

tests/ui/if_then_some_else_none.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,3 +284,16 @@ mod issue16176 {
284284
if cond { Some(foo().await) } else { None } // OK
285285
}
286286
}
287+
288+
fn issue16269() -> Option<i32> {
289+
use std::cell::UnsafeCell;
290+
291+
//~v if_then_some_else_none
292+
if 1 <= 3 {
293+
let a = UnsafeCell::new(1);
294+
// SAFETY: `bytes` bytes starting at `new_end` were just reserved.
295+
Some(unsafe { *a.get() })
296+
} else {
297+
None
298+
}
299+
}

tests/ui/if_then_some_else_none.stderr

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,19 @@ LL | | println!("true!");
99
... |
1010
LL | | None
1111
LL | | };
12-
| |_____^ help: try: `foo().then(|| { println!("true!"); "foo" })`
12+
| |_____^
1313
|
1414
= note: `-D clippy::if-then-some-else-none` implied by `-D warnings`
1515
= help: to override `-D warnings` add `#[allow(clippy::if_then_some_else_none)]`
16+
help: try
17+
|
18+
LL ~ let _ = foo().then(|| {
19+
LL +
20+
LL +
21+
LL + println!("true!");
22+
LL + "foo"
23+
LL ~ });
24+
|
1625

1726
error: this could be simplified with `bool::then`
1827
--> tests/ui/if_then_some_else_none.rs:16:13
@@ -25,7 +34,17 @@ LL | | println!("true!");
2534
... |
2635
LL | | None
2736
LL | | };
28-
| |_____^ help: try: `matches!(true, true).then(|| { println!("true!"); matches!(true, false) })`
37+
| |_____^
38+
|
39+
help: try
40+
|
41+
LL ~ let _ = matches!(true, true).then(|| {
42+
LL +
43+
LL +
44+
LL + println!("true!");
45+
LL + matches!(true, false)
46+
LL ~ });
47+
|
2948

3049
error: this could be simplified with `bool::then_some`
3150
--> tests/ui/if_then_some_else_none.rs:27:28
@@ -50,7 +69,17 @@ LL | | println!("true!");
5069
... |
5170
LL | | None
5271
LL | | };
53-
| |_____^ help: try: `foo().then(|| { println!("true!"); 150 })`
72+
| |_____^
73+
|
74+
help: try
75+
|
76+
LL ~ let _ = foo().then(|| {
77+
LL +
78+
LL +
79+
LL + println!("true!");
80+
LL + 150
81+
LL ~ });
82+
|
5483

5584
error: this could be simplified with `bool::then`
5685
--> tests/ui/if_then_some_else_none.rs:138:5
@@ -125,7 +154,15 @@ LL | | Some(self.count)
125154
LL | | } else {
126155
LL | | None
127156
LL | | }
128-
| |_____________^ help: try: `(self.count < 5).then(|| { self.count += 1; self.count })`
157+
| |_____________^
158+
|
159+
help: try
160+
|
161+
LL ~ (self.count < 5).then(|| {
162+
LL + self.count += 1;
163+
LL + self.count
164+
LL + })
165+
|
129166

130167
error: this could be simplified with `bool::then`
131168
--> tests/ui/if_then_some_else_none.rs:249:13
@@ -137,7 +174,36 @@ LL | | Some(42)
137174
LL | | } else {
138175
LL | | None
139176
LL | | };
140-
| |_____^ help: try: `true.then(|| { mac!(); 42 })`
177+
| |_____^
178+
|
179+
help: try
180+
|
181+
LL ~ let _ = true.then(|| {
182+
LL + mac!();
183+
LL + 42
184+
LL ~ });
185+
|
186+
187+
error: this could be simplified with `bool::then`
188+
--> tests/ui/if_then_some_else_none.rs:292:5
189+
|
190+
LL | / if 1 <= 3 {
191+
LL | | let a = UnsafeCell::new(1);
192+
LL | | // SAFETY: `bytes` bytes starting at `new_end` were just reserved.
193+
LL | | Some(unsafe { *a.get() })
194+
LL | | } else {
195+
LL | | None
196+
LL | | }
197+
| |_____^
198+
|
199+
help: try
200+
|
201+
LL ~ (1 <= 3).then(|| {
202+
LL + let a = UnsafeCell::new(1);
203+
LL + // SAFETY: `bytes` bytes starting at `new_end` were just reserved.
204+
LL + unsafe { *a.get() }
205+
LL + })
206+
|
141207

142-
error: aborting due to 13 previous errors
208+
error: aborting due to 14 previous errors
143209

0 commit comments

Comments
 (0)