diff options
| author | Jason Newcomb <jsnewcomb@pm.me> | 2021-09-23 00:22:27 -0400 |
|---|---|---|
| committer | Jason Newcomb <jsnewcomb@pm.me> | 2021-09-23 01:13:21 -0400 |
| commit | 5efd6bc6c3781f28f762fdf781d49e3db7fcc9d3 (patch) | |
| tree | 96e6623ea719a1b5b3151a9d3d1b6b0f250bb40e | |
| parent | 848e5518d66ff2084c10a4c1cfcf5da5e0534033 (diff) | |
| download | rust-5efd6bc6c3781f28f762fdf781d49e3db7fcc9d3.tar.gz rust-5efd6bc6c3781f28f762fdf781d49e3db7fcc9d3.zip | |
Don't lint `suspicious_else_formatting` inside proc-macros
| -rw-r--r-- | clippy_lints/src/formatting.rs | 57 |
1 files changed, 31 insertions, 26 deletions
diff --git a/clippy_lints/src/formatting.rs b/clippy_lints/src/formatting.rs index 4dd0ffe77ea..b4f186525c5 100644 --- a/clippy_lints/src/formatting.rs +++ b/clippy_lints/src/formatting.rs @@ -286,34 +286,39 @@ fn check_array(cx: &EarlyContext<'_>, expr: &Expr) { } fn check_missing_else(cx: &EarlyContext<'_>, first: &Expr, second: &Expr) { - if !differing_macro_contexts(first.span, second.span) - && !first.span.from_expansion() - && is_if(first) - && (is_block(second) || is_if(second)) - { - // where the else would be - let else_span = first.span.between(second.span); + if_chain! { + if !differing_macro_contexts(first.span, second.span); + if !first.span.from_expansion(); + if let ExprKind::If(cond_expr, ..) = &first.kind; + if is_block(second) || is_if(second); - if let Some(else_snippet) = snippet_opt(cx, else_span) { - if !else_snippet.contains('\n') { - let (looks_like, next_thing) = if is_if(second) { - ("an `else if`", "the second `if`") - } else { - ("an `else {..}`", "the next block") - }; + // Proc-macros can give weird spans. Make sure this is actually an `if`. + if let Some(if_snip) = snippet_opt(cx, first.span.until(cond_expr.span)); + if if_snip.starts_with("if"); - span_lint_and_note( - cx, - SUSPICIOUS_ELSE_FORMATTING, - else_span, - &format!("this looks like {} but the `else` is missing", looks_like), - None, - &format!( - "to remove this lint, add the missing `else` or add a new line before {}", - next_thing, - ), - ); - } + // If there is a line break between the two expressions, don't lint. + // If there is a non-whitespace character, this span came from a proc-macro. + let else_span = first.span.between(second.span); + if let Some(else_snippet) = snippet_opt(cx, else_span); + if !else_snippet.chars().any(|c| c == '\n' || !c.is_whitespace()); + then { + let (looks_like, next_thing) = if is_if(second) { + ("an `else if`", "the second `if`") + } else { + ("an `else {..}`", "the next block") + }; + + span_lint_and_note( + cx, + SUSPICIOUS_ELSE_FORMATTING, + else_span, + &format!("this looks like {} but the `else` is missing", looks_like), + None, + &format!( + "to remove this lint, add the missing `else` or add a new line before {}", + next_thing, + ), + ); } } } |
