|
1 | 1 | use clippy_config::Conf;
|
2 | 2 | use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
|
3 | 3 | use clippy_utils::msrvs::{self, Msrv};
|
4 |
| -use clippy_utils::source::{IntoSpan as _, SpanRangeExt, snippet, snippet_block, snippet_block_with_applicability}; |
| 4 | +use clippy_utils::source::{ |
| 5 | + IntoSpan as _, SpanRangeExt, snippet, snippet_block, snippet_block_with_applicability, snippet_opt, |
| 6 | +}; |
| 7 | +use clippy_utils::tokenize_with_text; |
5 | 8 | use rustc_ast::BinOpKind;
|
6 | 9 | use rustc_errors::Applicability;
|
7 | 10 | use rustc_hir::{Block, Expr, ExprKind, Stmt, StmtKind};
|
| 11 | +use rustc_lexer::TokenKind; |
8 | 12 | use rustc_lint::{LateContext, LateLintPass};
|
9 | 13 | use rustc_session::impl_lint_pass;
|
10 | 14 | use rustc_span::Span;
|
@@ -96,6 +100,8 @@ impl CollapsibleIf {
|
96 | 100 | && cx.tcx.hir_attrs(else_.hir_id).is_empty()
|
97 | 101 | && !else_.span.from_expansion()
|
98 | 102 | && let ExprKind::If(..) = else_.kind
|
| 103 | + && let up_to_if = else_block.span.until(else_.span) |
| 104 | + && span_not_contain_stmt(cx, up_to_if) |
99 | 105 | {
|
100 | 106 | // Prevent "elseif"
|
101 | 107 | // Check that the "else" is followed by whitespace
|
@@ -198,6 +204,12 @@ fn block_starts_with_comment(cx: &LateContext<'_>, block: &Block<'_>) -> bool {
|
198 | 204 | trimmed_block_text.starts_with("//") || trimmed_block_text.starts_with("/*")
|
199 | 205 | }
|
200 | 206 |
|
| 207 | +fn span_not_contain_stmt(cx: &LateContext<'_>, span: Span) -> bool { |
| 208 | + matches!(snippet_opt(cx, span), Some(text) if tokenize_with_text(&text[1..]).all(|(token, _, _)| { |
| 209 | + matches!(token, TokenKind::LineComment { .. } | TokenKind::BlockComment { .. } | TokenKind::Whitespace) |
| 210 | + })) |
| 211 | +} |
| 212 | + |
201 | 213 | /// If `block` is a block with either one expression or a statement containing an expression,
|
202 | 214 | /// return the expression. We don't peel blocks recursively, as extra blocks might be intentional.
|
203 | 215 | fn expr_block<'tcx>(block: &Block<'tcx>) -> Option<&'tcx Expr<'tcx>> {
|
|
0 commit comments