]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/types/redundant_allocation.rs
8280b2c5629cfbd2635129f2077d8a7affc14889
[rust.git] / clippy_lints / src / types / redundant_allocation.rs
1 use rustc_errors::Applicability;
2 use rustc_hir::{self as hir, def_id::DefId, LangItem, QPath, TyKind};
3 use rustc_lint::LateContext;
4 use rustc_span::symbol::sym;
5
6 use crate::utils::{
7     get_qpath_generic_tys, is_ty_param_diagnostic_item, is_ty_param_lang_item, snippet_with_applicability,
8     span_lint_and_sugg,
9 };
10
11 use super::{utils, REDUNDANT_ALLOCATION};
12
13 pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) {
14     if Some(def_id) == cx.tcx.lang_items().owned_box() {
15         if let Some(span) = utils::match_borrows_parameter(cx, qpath) {
16             let mut applicability = Applicability::MachineApplicable;
17             span_lint_and_sugg(
18                 cx,
19                 REDUNDANT_ALLOCATION,
20                 hir_ty.span,
21                 "usage of `Box<&T>`",
22                 "try",
23                 snippet_with_applicability(cx, span, "..", &mut applicability).to_string(),
24                 applicability,
25             );
26             return;
27         }
28     }
29
30     if cx.tcx.is_diagnostic_item(sym::Rc, def_id) {
31         if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::Rc) {
32             let mut applicability = Applicability::MachineApplicable;
33             span_lint_and_sugg(
34                 cx,
35                 REDUNDANT_ALLOCATION,
36                 hir_ty.span,
37                 "usage of `Rc<Rc<T>>`",
38                 "try",
39                 snippet_with_applicability(cx, ty.span, "..", &mut applicability).to_string(),
40                 applicability,
41             );
42         } else if let Some(ty) = is_ty_param_lang_item(cx, qpath, LangItem::OwnedBox) {
43             let qpath = match &ty.kind {
44                 TyKind::Path(qpath) => qpath,
45                 _ => return,
46             };
47             let inner_span = match get_qpath_generic_tys(qpath).next() {
48                 Some(ty) => ty.span,
49                 None => return,
50             };
51             let mut applicability = Applicability::MachineApplicable;
52             span_lint_and_sugg(
53                 cx,
54                 REDUNDANT_ALLOCATION,
55                 hir_ty.span,
56                 "usage of `Rc<Box<T>>`",
57                 "try",
58                 format!(
59                     "Rc<{}>",
60                     snippet_with_applicability(cx, inner_span, "..", &mut applicability)
61                 ),
62                 applicability,
63             );
64         } else if let Some(span) = utils::match_borrows_parameter(cx, qpath) {
65             let mut applicability = Applicability::MachineApplicable;
66             span_lint_and_sugg(
67                 cx,
68                 REDUNDANT_ALLOCATION,
69                 hir_ty.span,
70                 "usage of `Rc<&T>`",
71                 "try",
72                 snippet_with_applicability(cx, span, "..", &mut applicability).to_string(),
73                 applicability,
74             );
75             return; // don't recurse into the type
76         }
77     }
78 }