]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/types/box_collection.rs
538c10a5b2045403640a0cae49cb1ce8ba9db760
[rust.git] / clippy_lints / src / types / box_collection.rs
1 use clippy_utils::diagnostics::span_lint_and_help;
2 use clippy_utils::is_ty_param_diagnostic_item;
3 use rustc_hir::{self as hir, def_id::DefId, QPath};
4 use rustc_lint::LateContext;
5 use rustc_span::symbol::sym;
6
7 use super::BOX_COLLECTION;
8
9 pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool {
10     if_chain! {
11         if Some(def_id) == cx.tcx.lang_items().owned_box();
12         if let Some(item_type) = get_std_collection(cx, qpath);
13         then {
14             let generic = if item_type == "String" {
15                 ""
16             } else {
17                 "<..>"
18             };
19             span_lint_and_help(
20                 cx,
21                 BOX_COLLECTION,
22                 hir_ty.span,
23                 &format!(
24                     "you seem to be trying to use `Box<{outer}{generic}>`. Consider using just `{outer}{generic}`",
25                     outer=item_type,
26                     generic = generic),
27                 None,
28                 &format!(
29                     "`{outer}{generic}` is already on the heap, `Box<{outer}{generic}>` makes an extra allocation",
30                     outer=item_type,
31                     generic = generic)
32             );
33             true
34         } else {
35             false
36         }
37     }
38 }
39
40 fn get_std_collection(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<&'static str> {
41     if is_ty_param_diagnostic_item(cx, qpath, sym::Vec).is_some() {
42         Some("Vec")
43     } else if is_ty_param_diagnostic_item(cx, qpath, sym::String).is_some() {
44         Some("String")
45     } else if is_ty_param_diagnostic_item(cx, qpath, sym::HashMap).is_some() {
46         Some("HashMap")
47     } else {
48         None
49     }
50 }