|
1 | 1 | use clippy_config::Conf;
|
2 | 2 | use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
|
| 3 | +use clippy_utils::peel_blocks_with_stmt; |
3 | 4 | use clippy_utils::source::{IntoSpan as _, SpanRangeExt, snippet, snippet_block, snippet_block_with_applicability};
|
4 | 5 | use rustc_ast::BinOpKind;
|
5 | 6 | use rustc_errors::Applicability;
|
6 |
| -use rustc_hir::{Block, Expr, ExprKind, StmtKind}; |
| 7 | +use rustc_hir::{Expr, ExprKind}; |
7 | 8 | use rustc_lint::{LateContext, LateLintPass};
|
8 | 9 | use rustc_middle::ty::TyCtxt;
|
9 | 10 | use rustc_session::impl_lint_pass;
|
@@ -90,9 +91,10 @@ impl CollapsibleIf {
|
90 | 91 | }
|
91 | 92 | }
|
92 | 93 |
|
93 |
| - fn check_collapsible_else_if(cx: &LateContext<'_>, then_span: Span, else_block: &Block<'_>) { |
| 94 | + fn check_collapsible_else_if(cx: &LateContext<'_>, then_span: Span, else_block: &Expr<'_>) { |
94 | 95 | if !block_starts_with_comment(cx, else_block)
|
95 |
| - && let Some(else_) = expr_block(else_block) |
| 96 | + && let else_ = peel_blocks_with_stmt(else_block) |
| 97 | + && else_.hir_id != else_block.hir_id |
96 | 98 | && cx.tcx.hir_attrs(else_.hir_id).is_empty()
|
97 | 99 | && !else_.span.from_expansion()
|
98 | 100 | && let ExprKind::If(..) = else_.kind
|
@@ -123,8 +125,9 @@ impl CollapsibleIf {
|
123 | 125 | }
|
124 | 126 | }
|
125 | 127 |
|
126 |
| - fn check_collapsible_if_if(&self, cx: &LateContext<'_>, expr: &Expr<'_>, check: &Expr<'_>, then: &Block<'_>) { |
127 |
| - if let Some(inner) = expr_block(then) |
| 128 | + fn check_collapsible_if_if(&self, cx: &LateContext<'_>, expr: &Expr<'_>, check: &Expr<'_>, then: &Expr<'_>) { |
| 129 | + let inner = peel_blocks_with_stmt(then); |
| 130 | + if inner.hir_id != then.hir_id |
128 | 131 | && cx.tcx.hir_attrs(inner.hir_id).is_empty()
|
129 | 132 | && let ExprKind::If(check_inner, _, None) = &inner.kind
|
130 | 133 | && self.eligible_condition(check_inner)
|
@@ -176,43 +179,27 @@ impl LateLintPass<'_> for CollapsibleIf {
|
176 | 179 | && !expr.span.from_expansion()
|
177 | 180 | {
|
178 | 181 | if let Some(else_) = else_
|
179 |
| - && let ExprKind::Block(else_, None) = else_.kind |
| 182 | + && let ExprKind::Block(_, None) = else_.kind |
180 | 183 | {
|
181 | 184 | Self::check_collapsible_else_if(cx, then.span, else_);
|
182 | 185 | } else if else_.is_none()
|
183 | 186 | && self.eligible_condition(cond)
|
184 |
| - && let ExprKind::Block(then, None) = then.kind |
| 187 | + && let ExprKind::Block(_, None) = then.kind |
185 | 188 | {
|
186 | 189 | self.check_collapsible_if_if(cx, expr, cond, then);
|
187 | 190 | }
|
188 | 191 | }
|
189 | 192 | }
|
190 | 193 | }
|
191 | 194 |
|
192 |
| -fn block_starts_with_comment(cx: &LateContext<'_>, block: &Block<'_>) -> bool { |
| 195 | +fn block_starts_with_comment(cx: &LateContext<'_>, block: &Expr<'_>) -> bool { |
193 | 196 | // We trim all opening braces and whitespaces and then check if the next string is a comment.
|
194 | 197 | let trimmed_block_text = snippet_block(cx, block.span, "..", None)
|
195 | 198 | .trim_start_matches(|c: char| c.is_whitespace() || c == '{')
|
196 | 199 | .to_owned();
|
197 | 200 | trimmed_block_text.starts_with("//") || trimmed_block_text.starts_with("/*")
|
198 | 201 | }
|
199 | 202 |
|
200 |
| -/// If `block` is a block with either one expression or a statement containing an expression, |
201 |
| -/// return the expression. We don't peel blocks recursively, as extra blocks might be intentional. |
202 |
| -fn expr_block<'tcx>(block: &Block<'tcx>) -> Option<&'tcx Expr<'tcx>> { |
203 |
| - match block.stmts { |
204 |
| - [] => block.expr, |
205 |
| - [stmt] => { |
206 |
| - if let StmtKind::Semi(expr) = stmt.kind { |
207 |
| - Some(expr) |
208 |
| - } else { |
209 |
| - None |
210 |
| - } |
211 |
| - }, |
212 |
| - _ => None, |
213 |
| - } |
214 |
| -} |
215 |
| - |
216 | 203 | /// If the expression is a `||`, suggest parentheses around it.
|
217 | 204 | fn parens_around(expr: &Expr<'_>) -> Vec<(Span, String)> {
|
218 | 205 | if let ExprKind::Binary(op, _, _) = expr.peel_drop_temps().kind
|
|
0 commit comments