]> git.lizzy.rs Git - rust.git/blob - clippy_utils/src/ptr.rs
0226f74906b5152b66a678c960200fcd844564da
[rust.git] / clippy_utils / src / ptr.rs
1 use crate::source::snippet;
2 use crate::visitors::expr_visitor_no_bodies;
3 use crate::{path_to_local_id, strip_pat_refs};
4 use rustc_hir::intravisit::Visitor;
5 use rustc_hir::{Body, BodyId, ExprKind, HirId, PatKind};
6 use rustc_lint::LateContext;
7 use rustc_span::Span;
8 use std::borrow::Cow;
9
10 pub fn get_spans(
11     cx: &LateContext<'_>,
12     opt_body_id: Option<BodyId>,
13     idx: usize,
14     replacements: &[(&'static str, &'static str)],
15 ) -> Option<Vec<(Span, Cow<'static, str>)>> {
16     if let Some(body) = opt_body_id.map(|id| cx.tcx.hir().body(id)) {
17         if let PatKind::Binding(_, binding_id, _, _) = strip_pat_refs(body.params[idx].pat).kind {
18             extract_clone_suggestions(cx, binding_id, replacements, body)
19         } else {
20             Some(vec![])
21         }
22     } else {
23         Some(vec![])
24     }
25 }
26
27 fn extract_clone_suggestions<'tcx>(
28     cx: &LateContext<'tcx>,
29     id: HirId,
30     replace: &[(&'static str, &'static str)],
31     body: &'tcx Body<'_>,
32 ) -> Option<Vec<(Span, Cow<'static, str>)>> {
33     let mut abort = false;
34     let mut spans = Vec::new();
35     expr_visitor_no_bodies(|expr| {
36         if abort {
37             return false;
38         }
39         if let ExprKind::MethodCall(seg, recv, [], _) = expr.kind {
40             if path_to_local_id(recv, id) {
41                 if seg.ident.name.as_str() == "capacity" {
42                     abort = true;
43                     return false;
44                 }
45                 for &(fn_name, suffix) in replace {
46                     if seg.ident.name.as_str() == fn_name {
47                         spans.push((expr.span, snippet(cx, recv.span, "_") + suffix));
48                         return false;
49                     }
50                 }
51             }
52         }
53         !abort
54     })
55     .visit_body(body);
56     if abort { None } else { Some(spans) }
57 }