Skip to content

Commit 2a62200

Browse files
committed
fix: suspicious_else_formatting false positive when else is included in comments
1 parent 95c62ff commit 2a62200

File tree

2 files changed

+70
-1
lines changed

2 files changed

+70
-1
lines changed

clippy_lints/src/formatting.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ fn check_else(cx: &EarlyContext<'_>, expr: &Expr) {
214214
// the snippet should look like " else \n " with maybe comments anywhere
215215
// it’s bad when there is a ‘\n’ after the “else”
216216
&& let Some(else_snippet) = snippet_opt(cx, else_span)
217-
&& let Some((pre_else, post_else)) = else_snippet.split_once("else")
217+
&& let Some((pre_else, post_else)) = split_once_with_else(&else_snippet)
218218
&& let Some((_, post_else_post_eol)) = post_else.split_once('\n')
219219
{
220220
// Allow allman style braces `} \n else \n {`
@@ -323,3 +323,44 @@ fn is_block(expr: &Expr) -> bool {
323323
fn is_if(expr: &Expr) -> bool {
324324
matches!(expr.kind, ExprKind::If(..))
325325
}
326+
327+
fn split_once_with_else(base: &str) -> Option<(&str, &str)> {
328+
let else_str = "else";
329+
330+
let indices: Vec<_> = base.match_indices(else_str).map(|(i, _)| i).collect();
331+
332+
match indices.len() {
333+
0 => return None,
334+
1 => return base.split_once(else_str),
335+
_ => {},
336+
}
337+
338+
let mut i = 0;
339+
let mut is_in_comment = false;
340+
341+
for line in base.lines() {
342+
if let Some(else_pos) = line.find(else_str) {
343+
if let Some(pos) = line.find("//") {
344+
if pos > else_pos {
345+
return Some(base.split_at(indices[i]));
346+
}
347+
} else if let Some(pos) = line.find("/*") {
348+
if pos > else_pos {
349+
return Some(base.split_at(indices[i]));
350+
}
351+
is_in_comment = true;
352+
} else if let Some(pos) = line.find("*/") {
353+
if pos < else_pos {
354+
return Some(base.split_at(indices[i]));
355+
}
356+
is_in_comment = false;
357+
} else if !is_in_comment {
358+
return Some(base.split_at(indices[i]));
359+
}
360+
361+
i += 1;
362+
}
363+
}
364+
365+
None
366+
}

tests/ui/suspicious_else_formatting.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,34 @@ fn main() {
120120
/* whelp */
121121
{
122122
}
123+
124+
// #12497 Don't trigger lint as rustfmt wants it
125+
if true {
126+
println!("true");
127+
}
128+
/*else if false {
129+
}*/
130+
else {
131+
println!("false");
132+
}
133+
134+
if true {
135+
println!("true");
136+
} // else if false {}
137+
else {
138+
println!("false");
139+
}
140+
141+
if true {
142+
println!("true");
143+
} /* if true {
144+
println!("true");
145+
}
146+
*/
147+
else {
148+
println!("false");
149+
}
150+
123151
}
124152

125153
// #7650 - Don't lint. Proc-macro using bad spans for `if` expressions.

0 commit comments

Comments
 (0)