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