diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index 239d453a9..b2d6c178b 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -1,36 +1,34 @@ -use crate::reexport::*; -use if_chain::if_chain; -use itertools::Itertools; -use rustc::lint::in_external_macro; -use rustc::middle::region; -use rustc_hir::def::{DefKind, Res}; -use rustc_hir::def_id; -use rustc_hir::intravisit::{walk_block, walk_expr, walk_pat, walk_stmt, NestedVisitorMap, Visitor}; -use rustc_hir::*; -use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_session::{declare_lint_pass, declare_tool_lint}; -// use rustc::middle::region::CodeExtent; use crate::consts::{constant, Constant}; -use crate::utils::usage::mutated_variables; -use crate::utils::{is_type_diagnostic_item, qpath_res, same_tys, sext, sugg}; -use rustc::hir::map::Map; -use rustc::ty::{self, Ty}; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::Applicability; -use rustc_span::source_map::Span; -use rustc_span::{BytePos, Symbol}; -use rustc_typeck::expr_use_visitor::*; -use std::iter::{once, Iterator}; -use std::mem; -use syntax::ast; - +use crate::reexport::*; use crate::utils::paths; +use crate::utils::usage::{is_unused, mutated_variables}; use crate::utils::{ get_enclosing_block, get_parent_expr, get_trait_def_id, has_iter_method, higher, implements_trait, is_integer_const, is_refutable, last_path_segment, match_trait_method, match_type, match_var, multispan_sugg, snippet, snippet_opt, snippet_with_applicability, span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then, SpanlessEq, }; +use crate::utils::{is_type_diagnostic_item, qpath_res, same_tys, sext, sugg}; +use if_chain::if_chain; +use itertools::Itertools; +use rustc::hir::map::Map; +use rustc::lint::in_external_macro; +use rustc::middle::region; +use rustc::ty::{self, Ty}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_errors::Applicability; +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::def_id; +use rustc_hir::intravisit::{walk_block, walk_expr, walk_pat, walk_stmt, NestedVisitorMap, Visitor}; +use rustc_hir::*; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::source_map::Span; +use rustc_span::{BytePos, Symbol}; +use rustc_typeck::expr_use_visitor::*; +use std::iter::{once, Iterator}; +use std::mem; +use syntax::ast; declare_clippy_lint! { /// **What it does:** Checks for for-loops that manually copy items between @@ -1689,39 +1687,11 @@ fn check_for_mutation( fn pat_is_wild<'tcx>(pat: &'tcx PatKind<'_>, body: &'tcx Expr<'_>) -> bool { match *pat { PatKind::Wild => true, - PatKind::Binding(.., ident, None) if ident.as_str().starts_with('_') => { - let mut visitor = UsedVisitor { - var: ident.name, - used: false, - }; - walk_expr(&mut visitor, body); - !visitor.used - }, + PatKind::Binding(.., ident, None) if ident.as_str().starts_with('_') => is_unused(&ident, body), _ => false, } } -struct UsedVisitor { - var: ast::Name, // var to look for - used: bool, // has the var been used otherwise? -} - -impl<'tcx> Visitor<'tcx> for UsedVisitor { - type Map = Map<'tcx>; - - fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { - if match_var(expr, self.var) { - self.used = true; - } else { - walk_expr(self, expr); - } - } - - fn nested_visit_map(&mut self) -> NestedVisitorMap<'_, Self::Map> { - NestedVisitorMap::None - } -} - struct LocalUsedVisitor<'a, 'tcx> { cx: &'a LateContext<'a, 'tcx>, local: HirId, diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index ee7155c1a..cddd479d7 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -1,26 +1,24 @@ use crate::consts::{constant, miri_to_const, Constant}; use crate::utils::paths; use crate::utils::sugg::Sugg; +use crate::utils::usage::is_unused; use crate::utils::{ - expr_block, is_allowed, is_expn_of, match_qpath, match_type, match_var, multispan_sugg, remove_blocks, snippet, + expr_block, is_allowed, is_expn_of, is_wild, match_qpath, match_type, multispan_sugg, remove_blocks, snippet, snippet_with_applicability, span_help_and_lint, span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, }; use if_chain::if_chain; -use rustc::hir::map::Map; -use rustc::lint::{in_external_macro, LateContext, LateLintPass, LintArray, LintContext, LintPass}; +use rustc::lint::in_external_macro; use rustc::ty::{self, Ty}; use rustc_errors::Applicability; use rustc_hir::def::CtorKind; -use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor}; use rustc_hir::*; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; -use rustc_span::symbol::Ident; use std::cmp::Ordering; use std::collections::Bound; -use syntax::ast::{self, LitKind}; +use syntax::ast::LitKind; declare_clippy_lint! { /// **What it does:** Checks for matches with a single arm where an `if let` @@ -464,43 +462,6 @@ fn check_overlapping_arms<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ex: &'tcx Expr<' } } -fn is_wild<'tcx>(pat: &impl std::ops::Deref>) -> bool { - match pat.kind { - PatKind::Wild => true, - _ => false, - } -} - -fn is_unused<'tcx>(ident: &'tcx Ident, body: &'tcx Expr<'_>) -> bool { - let mut visitor = UsedVisitor { - var: ident.name, - used: false, - }; - walk_expr(&mut visitor, body); - !visitor.used -} - -struct UsedVisitor { - var: ast::Name, // var to look for - used: bool, // has the var been used otherwise? -} - -impl<'tcx> Visitor<'tcx> for UsedVisitor { - type Map = Map<'tcx>; - - fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { - if match_var(expr, self.var) { - self.used = true; - } else { - walk_expr(self, expr); - } - } - - fn nested_visit_map(&mut self) -> NestedVisitorMap<'_, Self::Map> { - NestedVisitorMap::None - } -} - fn check_wild_err_arm(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>]) { let ex_ty = walk_ptrs_ty(cx.tables.expr_ty(ex)); if match_type(cx, ex_ty, &paths::RESULT) { diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 797bccc29..eca2baa8c 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -127,6 +127,14 @@ pub fn is_present_in_source(cx: &T, span: Span) -> bool { true } +/// Checks if given pattern is a wildcard (`_`) +pub fn is_wild<'tcx>(pat: &impl std::ops::Deref>) -> bool { + match pat.kind { + PatKind::Wild => true, + _ => false, + } +} + /// Checks if type is struct, enum or union type with the given def path. pub fn match_type(cx: &LateContext<'_, '_>, ty: Ty<'_>, path: &[&str]) -> bool { match ty.kind { diff --git a/clippy_lints/src/utils/usage.rs b/clippy_lints/src/utils/usage.rs index 18fb01c5b..7939d7d08 100644 --- a/clippy_lints/src/utils/usage.rs +++ b/clippy_lints/src/utils/usage.rs @@ -1,9 +1,14 @@ +use crate::utils::match_var; +use rustc::hir::map::Map; use rustc::ty; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def::Res; +use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor}; use rustc_hir::*; use rustc_lint::LateContext; +use rustc_span::symbol::Ident; use rustc_typeck::expr_use_visitor::*; +use syntax::ast; /// Returns a set of mutated local variable IDs, or `None` if mutations could not be determined. pub fn mutated_variables<'a, 'tcx>(expr: &'tcx Expr<'_>, cx: &'a LateContext<'a, 'tcx>) -> Option> { @@ -70,3 +75,33 @@ impl<'tcx> Delegate<'tcx> for MutVarsDelegate { self.update(&cmt) } } + +pub struct UsedVisitor { + pub var: ast::Name, // var to look for + pub used: bool, // has the var been used otherwise? +} + +impl<'tcx> Visitor<'tcx> for UsedVisitor { + type Map = Map<'tcx>; + + fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { + if match_var(expr, self.var) { + self.used = true; + } else { + walk_expr(self, expr); + } + } + + fn nested_visit_map(&mut self) -> NestedVisitorMap<'_, Self::Map> { + NestedVisitorMap::None + } +} + +pub fn is_unused<'tcx>(ident: &'tcx Ident, body: &'tcx Expr<'_>) -> bool { + let mut visitor = UsedVisitor { + var: ident.name, + used: false, + }; + walk_expr(&mut visitor, body); + !visitor.used +}