]> git.lizzy.rs Git - rust.git/blobdiff - clippy_utils/src/ptr.rs
fix `box-default` linting `no_std` non-boxes
[rust.git] / clippy_utils / src / ptr.rs
index baeff08e02cd8f6738678b71e2cdf1d039f772ef..88837d8a143eddf15d7472ae89321195667ddb3e 100644 (file)
@@ -1,9 +1,10 @@
-use crate::{get_pat_name, match_var, snippet};
-use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
-use rustc_hir::{Body, BodyId, Expr, ExprKind, Param};
+use crate::source::snippet;
+use crate::visitors::{for_each_expr, Descend};
+use crate::{path_to_local_id, strip_pat_refs};
+use core::ops::ControlFlow;
+use rustc_hir::{Body, BodyId, ExprKind, HirId, PatKind};
 use rustc_lint::LateContext;
-use rustc_middle::hir::map::Map;
-use rustc_span::{Span, Symbol};
+use rustc_span::Span;
 use std::borrow::Cow;
 
 pub fn get_spans(
@@ -13,10 +14,11 @@ pub fn get_spans(
     replacements: &[(&'static str, &'static str)],
 ) -> Option<Vec<(Span, Cow<'static, str>)>> {
     if let Some(body) = opt_body_id.map(|id| cx.tcx.hir().body(id)) {
-        get_binding_name(&body.params[idx]).map_or_else(
-            || Some(vec![]),
-            |name| extract_clone_suggestions(cx, name, replacements, body),
-        )
+        if let PatKind::Binding(_, binding_id, _, _) = strip_pat_refs(body.params[idx].pat).kind {
+            extract_clone_suggestions(cx, binding_id, replacements, body)
+        } else {
+            Some(vec![])
+        }
     } else {
         Some(vec![])
     }
@@ -24,63 +26,27 @@ pub fn get_spans(
 
 fn extract_clone_suggestions<'tcx>(
     cx: &LateContext<'tcx>,
-    name: Symbol,
+    id: HirId,
     replace: &[(&'static str, &'static str)],
     body: &'tcx Body<'_>,
 ) -> Option<Vec<(Span, Cow<'static, str>)>> {
-    let mut visitor = PtrCloneVisitor {
-        cx,
-        name,
-        replace,
-        spans: vec![],
-        abort: false,
-    };
-    visitor.visit_body(body);
-    if visitor.abort {
-        None
-    } else {
-        Some(visitor.spans)
-    }
-}
-
-struct PtrCloneVisitor<'a, 'tcx> {
-    cx: &'a LateContext<'tcx>,
-    name: Symbol,
-    replace: &'a [(&'static str, &'static str)],
-    spans: Vec<(Span, Cow<'static, str>)>,
-    abort: bool,
-}
-
-impl<'a, 'tcx> Visitor<'tcx> for PtrCloneVisitor<'a, 'tcx> {
-    type Map = Map<'tcx>;
-
-    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
-        if self.abort {
-            return;
-        }
-        if let ExprKind::MethodCall(ref seg, _, ref args, _) = expr.kind {
-            if args.len() == 1 && match_var(&args[0], self.name) {
-                if seg.ident.name.as_str() == "capacity" {
-                    self.abort = true;
-                    return;
-                }
-                for &(fn_name, suffix) in self.replace {
-                    if seg.ident.name.as_str() == fn_name {
-                        self.spans
-                            .push((expr.span, snippet(self.cx, args[0].span, "_") + suffix));
-                        return;
-                    }
+    let mut spans = Vec::new();
+    for_each_expr(body, |e| {
+        if let ExprKind::MethodCall(seg, recv, [], _) = e.kind
+            && path_to_local_id(recv, id)
+        {
+            if seg.ident.as_str() == "capacity" {
+                return ControlFlow::Break(());
+            }
+            for &(fn_name, suffix) in replace {
+                if seg.ident.as_str() == fn_name {
+                    spans.push((e.span, snippet(cx, recv.span, "_") + suffix));
+                    return ControlFlow::Continue(Descend::No);
                 }
             }
         }
-        walk_expr(self, expr);
-    }
-
-    fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
-        NestedVisitorMap::None
-    }
-}
-
-fn get_binding_name(arg: &Param<'_>) -> Option<Symbol> {
-    get_pat_name(&arg.pat)
+        ControlFlow::Continue(Descend::Yes)
+    })
+    .is_none()
+    .then_some(spans)
 }