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;
12 opt_body_id: Option<BodyId>,
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)
27 fn extract_clone_suggestions<'tcx>(
28 cx: &LateContext<'tcx>,
30 replace: &[(&'static str, &'static str)],
32 ) -> Option<Vec<(Span, Cow<'static, str>)>> {
33 let mut abort = false;
34 let mut spans = Vec::new();
35 expr_visitor_no_bodies(|expr| {
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" {
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));
56 if abort { None } else { Some(spans) }