X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=clippy_lints%2Fsrc%2Fcollapsible_if.rs;h=0fd0abdc39d2326d5087aa875580cf21f4e134c6;hb=e5a5b0a0774625eebbe7b29c67b49dc6431544d1;hp=c1d39716083e8878b4e277a35743f95f6aed39e2;hpb=58e12130e4e8976f16c87190b51d2e5748691536;p=rust.git diff --git a/clippy_lints/src/collapsible_if.rs b/clippy_lints/src/collapsible_if.rs index c1d39716083..0fd0abdc39d 100644 --- a/clippy_lints/src/collapsible_if.rs +++ b/clippy_lints/src/collapsible_if.rs @@ -13,12 +13,13 @@ //! This lint is **warn** by default use if_chain::if_chain; +use rustc::declare_lint_pass; use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass}; -use rustc::{declare_lint_pass, declare_tool_lint}; +use rustc_session::declare_tool_lint; use syntax::ast; use crate::utils::sugg::Sugg; -use crate::utils::{in_macro, snippet_block, snippet_block_with_applicability, span_lint_and_sugg, span_lint_and_then}; +use crate::utils::{snippet_block, snippet_block_with_applicability, span_lint_and_sugg, span_lint_and_then}; use rustc_errors::Applicability; declare_clippy_lint! { @@ -75,25 +76,21 @@ impl EarlyLintPass for CollapsibleIf { fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) { - if !in_macro(expr.span) { + if !expr.span.from_expansion() { check_if(cx, expr) } } } fn check_if(cx: &EarlyContext<'_>, expr: &ast::Expr) { - match expr.node { - ast::ExprKind::If(ref check, ref then, ref else_) => { - if let Some(ref else_) = *else_ { - check_collapsible_maybe_if_let(cx, else_); - } else { - check_collapsible_no_if_let(cx, expr, check, then); - } - }, - ast::ExprKind::IfLet(_, _, _, Some(ref else_)) => { + if let ast::ExprKind::If(check, then, else_) = &expr.kind { + if let Some(else_) = else_ { check_collapsible_maybe_if_let(cx, else_); - }, - _ => (), + } else if let ast::ExprKind::Let(..) = check.kind { + // Prevent triggering on `if let a = b { if c { .. } }`. + } else { + check_collapsible_no_if_let(cx, expr, check, then); + } } } @@ -107,26 +104,22 @@ fn block_starts_with_comment(cx: &EarlyContext<'_>, expr: &ast::Block) -> bool { fn check_collapsible_maybe_if_let(cx: &EarlyContext<'_>, else_: &ast::Expr) { if_chain! { - if let ast::ExprKind::Block(ref block, _) = else_.node; + if let ast::ExprKind::Block(ref block, _) = else_.kind; if !block_starts_with_comment(cx, block); if let Some(else_) = expr_block(block); - if !in_macro(else_.span); + if !else_.span.from_expansion(); + if let ast::ExprKind::If(..) = else_.kind; then { - match else_.node { - ast::ExprKind::If(..) | ast::ExprKind::IfLet(..) => { - let mut applicability = Applicability::MachineApplicable; - span_lint_and_sugg( - cx, - COLLAPSIBLE_IF, - block.span, - "this `else { if .. }` block can be collapsed", - "try", - snippet_block_with_applicability(cx, else_.span, "..", &mut applicability).into_owned(), - applicability, - ); - } - _ => (), - } + let mut applicability = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + COLLAPSIBLE_IF, + block.span, + "this `else { if .. }` block can be collapsed", + "try", + snippet_block_with_applicability(cx, else_.span, "..", &mut applicability).into_owned(), + applicability, + ); } } } @@ -135,8 +128,13 @@ fn check_collapsible_no_if_let(cx: &EarlyContext<'_>, expr: &ast::Expr, check: & if_chain! { if !block_starts_with_comment(cx, then); if let Some(inner) = expr_block(then); - if let ast::ExprKind::If(ref check_inner, ref content, None) = inner.node; + if let ast::ExprKind::If(ref check_inner, ref content, None) = inner.kind; then { + if let ast::ExprKind::Let(..) = check_inner.kind { + // Prevent triggering on `if c { if let a = b { .. } }`. + return; + } + if expr.span.ctxt() != inner.span.ctxt() { return; } @@ -163,7 +161,7 @@ fn expr_block(block: &ast::Block) -> Option<&ast::Expr> { let mut it = block.stmts.iter(); if let (Some(stmt), None) = (it.next(), it.next()) { - match stmt.node { + match stmt.kind { ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => Some(expr), _ => None, }