X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=clippy_lints%2Fsrc%2Flet_if_seq.rs;h=a7dae9497db4b2e4664f78156e929104cf06cc01;hb=e5a5b0a0774625eebbe7b29c67b49dc6431544d1;hp=5ef3d8dd4abf101602edf3a7442f01f9f931e875;hpb=6937d5581af14b71e23af0db81241a3fea11c70a;p=rust.git diff --git a/clippy_lints/src/let_if_seq.rs b/clippy_lints/src/let_if_seq.rs index 5ef3d8dd4ab..a7dae9497db 100644 --- a/clippy_lints/src/let_if_seq.rs +++ b/clippy_lints/src/let_if_seq.rs @@ -1,11 +1,12 @@ -use crate::utils::{snippet, span_lint_and_then}; +use crate::utils::{higher, qpath_res, snippet, span_lint_and_then}; use if_chain::if_chain; +use rustc::declare_lint_pass; use rustc::hir; -use rustc::hir::def::Def; +use rustc::hir::def::Res; use rustc::hir::BindingAnnotation; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; -use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; +use rustc_session::declare_tool_lint; declare_clippy_lint! { /// **What it does:** Checks for variable declarations immediately followed by a @@ -52,18 +53,7 @@ "unidiomatic `let mut` declaration followed by initialization in `if`" } -#[derive(Copy, Clone)] -pub struct LetIfSeq; - -impl LintPass for LetIfSeq { - fn get_lints(&self) -> LintArray { - lint_array!(USELESS_LET_IF_SEQ) - } - - fn name(&self) -> &'static str { - "LetIfSeq" - } -} +declare_lint_pass!(LetIfSeq => [USELESS_LET_IF_SEQ]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetIfSeq { fn check_block(&mut self, cx: &LateContext<'a, 'tcx>, block: &'tcx hir::Block) { @@ -71,19 +61,26 @@ fn check_block(&mut self, cx: &LateContext<'a, 'tcx>, block: &'tcx hir::Block) { while let Some(stmt) = it.next() { if_chain! { if let Some(expr) = it.peek(); - if let hir::StmtKind::Local(ref local) = stmt.node; - if let hir::PatKind::Binding(mode, canonical_id, ident, None) = local.pat.node; - if let hir::StmtKind::Expr(ref if_) = expr.node; - if let hir::ExprKind::If(ref cond, ref then, ref else_) = if_.node; + if let hir::StmtKind::Local(ref local) = stmt.kind; + if let hir::PatKind::Binding(mode, canonical_id, ident, None) = local.pat.kind; + if let hir::StmtKind::Expr(ref if_) = expr.kind; + if let Some((ref cond, ref then, ref else_)) = higher::if_block(&if_); if !used_in_expr(cx, canonical_id, cond); - if let hir::ExprKind::Block(ref then, _) = then.node; + if let hir::ExprKind::Block(ref then, _) = then.kind; if let Some(value) = check_assign(cx, canonical_id, &*then); if !used_in_expr(cx, canonical_id, value); then { let span = stmt.span.to(if_.span); + let has_interior_mutability = !cx.tables.node_type(canonical_id).is_freeze( + cx.tcx, + cx.param_env, + span + ); + if has_interior_mutability { return; } + let (default_multi_stmts, default) = if let Some(ref else_) = *else_ { - if let hir::ExprKind::Block(ref else_, _) = else_.node { + if let hir::ExprKind::Block(ref else_, _) = else_.kind { if let Some(default) = check_assign(cx, canonical_id, else_) { (else_.stmts.len() > 1, default) } else if let Some(ref default) = local.init { @@ -139,7 +136,7 @@ fn check_block(&mut self, cx: &LateContext<'a, 'tcx>, block: &'tcx hir::Block) { } } -struct UsedVisitor<'a, 'tcx: 'a> { +struct UsedVisitor<'a, 'tcx> { cx: &'a LateContext<'a, 'tcx>, id: hir::HirId, used: bool, @@ -148,9 +145,9 @@ struct UsedVisitor<'a, 'tcx: 'a> { impl<'a, 'tcx> hir::intravisit::Visitor<'tcx> for UsedVisitor<'a, 'tcx> { fn visit_expr(&mut self, expr: &'tcx hir::Expr) { if_chain! { - if let hir::ExprKind::Path(ref qpath) = expr.node; - if let Def::Local(local_id) = self.cx.tables.qpath_def(qpath, expr.hir_id); - if self.id == self.cx.tcx.hir().node_to_hir_id(local_id); + if let hir::ExprKind::Path(ref qpath) = expr.kind; + if let Res::Local(local_id) = qpath_res(self.cx, qpath, expr.hir_id); + if self.id == local_id; then { self.used = true; return; @@ -171,11 +168,11 @@ fn check_assign<'a, 'tcx>( if_chain! { if block.expr.is_none(); if let Some(expr) = block.stmts.iter().last(); - if let hir::StmtKind::Semi(ref expr) = expr.node; - if let hir::ExprKind::Assign(ref var, ref value) = expr.node; - if let hir::ExprKind::Path(ref qpath) = var.node; - if let Def::Local(local_id) = cx.tables.qpath_def(qpath, var.hir_id); - if decl == cx.tcx.hir().node_to_hir_id(local_id); + if let hir::StmtKind::Semi(ref expr) = expr.kind; + if let hir::ExprKind::Assign(ref var, ref value) = expr.kind; + if let hir::ExprKind::Path(ref qpath) = var.kind; + if let Res::Local(local_id) = qpath_res(cx, qpath, var.hir_id); + if decl == local_id; then { let mut v = UsedVisitor { cx, @@ -198,7 +195,7 @@ fn check_assign<'a, 'tcx>( None } -fn used_in_expr<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, id: hir::HirId, expr: &'tcx hir::Expr) -> bool { +fn used_in_expr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, id: hir::HirId, expr: &'tcx hir::Expr) -> bool { let mut v = UsedVisitor { cx, id, used: false }; hir::intravisit::walk_expr(&mut v, expr); v.used