X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=clippy_lints%2Fsrc%2Fvec_init_then_push.rs;h=0413c02b230e5307ee32f9fbf5318e99ee071561;hb=d9c3f0d69029cd9ffd97fe2d1b7a3701ea0ac51a;hp=e632a7e57ee87b22fd351a80a3497bec5804a4de;hpb=9009f8f0319fb0f1a9ef712e6f379c2bfda2d101;p=rust.git diff --git a/clippy_lints/src/vec_init_then_push.rs b/clippy_lints/src/vec_init_then_push.rs index e632a7e57ee..0413c02b230 100644 --- a/clippy_lints/src/vec_init_then_push.rs +++ b/clippy_lints/src/vec_init_then_push.rs @@ -1,24 +1,26 @@ -use crate::utils::{is_type_diagnostic_item, match_def_path, paths, snippet, span_lint_and_sugg}; +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::snippet; +use clippy_utils::ty::is_type_diagnostic_item; +use clippy_utils::{match_def_path, path_to_local, path_to_local_id, paths}; use if_chain::if_chain; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; -use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, Local, PatKind, QPath, Stmt, StmtKind}; +use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, HirId, Local, PatKind, QPath, Stmt, StmtKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::{symbol::sym, Span, Symbol}; +use rustc_span::{symbol::sym, Span}; use std::convert::TryInto; declare_clippy_lint! { - /// **What it does:** Checks for calls to `push` immediately after creating a new `Vec`. + /// ### What it does + /// Checks for calls to `push` immediately after creating a new `Vec`. /// - /// **Why is this bad?** The `vec![]` macro is both more performant and easier to read than + /// ### Why is this bad? + /// The `vec![]` macro is both more performant and easier to read than /// multiple `push` calls. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// let mut v = Vec::new(); /// v.push(0); @@ -45,8 +47,8 @@ enum VecInitKind { WithCapacity(u64), } struct VecPushSearcher { + local_id: HirId, init: VecInitKind, - name: Symbol, lhs_is_local: bool, lhs_span: Span, err_span: Span, @@ -81,17 +83,20 @@ fn display_err(&self, cx: &LateContext<'_>) { } impl LateLintPass<'_> for VecInitThenPush { - fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) { + fn check_block(&mut self, _: &LateContext<'tcx>, _: &'tcx Block<'tcx>) { self.searcher = None; + } + + fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) { if_chain! { if !in_external_macro(cx.sess(), local.span); if let Some(init) = local.init; - if let PatKind::Binding(BindingAnnotation::Mutable, _, ident, None) = local.pat.kind; + if let PatKind::Binding(BindingAnnotation::Mutable, id, _, None) = local.pat.kind; if let Some(init_kind) = get_vec_init_kind(cx, init); then { self.searcher = Some(VecPushSearcher { + local_id: id, init: init_kind, - name: ident.name, lhs_is_local: true, lhs_span: local.ty.map_or(local.pat.span, |t| local.pat.span.to(t.span)), err_span: local.span, @@ -102,23 +107,21 @@ fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) { } fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if self.searcher.is_none() { - if_chain! { - if !in_external_macro(cx.sess(), expr.span); - if let ExprKind::Assign(left, right, _) = expr.kind; - if let ExprKind::Path(QPath::Resolved(_, path)) = left.kind; - if let Some(name) = path.segments.get(0); - if let Some(init_kind) = get_vec_init_kind(cx, right); - then { - self.searcher = Some(VecPushSearcher { - init: init_kind, - name: name.ident.name, - lhs_is_local: false, - lhs_span: left.span, - err_span: expr.span, - found: 0, - }); - } + if_chain! { + if self.searcher.is_none(); + if !in_external_macro(cx.sess(), expr.span); + if let ExprKind::Assign(left, right, _) = expr.kind; + if let Some(id) = path_to_local(left); + if let Some(init_kind) = get_vec_init_kind(cx, right); + then { + self.searcher = Some(VecPushSearcher { + local_id: id, + init: init_kind, + lhs_is_local: false, + lhs_span: left.span, + err_span: expr.span, + found: 0, + }); } } } @@ -128,10 +131,8 @@ fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) { if_chain! { if let StmtKind::Expr(expr) | StmtKind::Semi(expr) = stmt.kind; if let ExprKind::MethodCall(path, _, [self_arg, _], _) = expr.kind; + if path_to_local_id(self_arg, searcher.local_id); if path.ident.name.as_str() == "push"; - if let ExprKind::Path(QPath::Resolved(_, self_path)) = self_arg.kind; - if let [self_name] = self_path.segments; - if self_name.ident.name == searcher.name; then { self.searcher = Some(VecPushSearcher { found: searcher.found + 1,