diff options
Diffstat (limited to 'src/tools/clippy/clippy_lints/src/types/box_collection.rs')
-rw-r--r-- | src/tools/clippy/clippy_lints/src/types/box_collection.rs | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/tools/clippy/clippy_lints/src/types/box_collection.rs b/src/tools/clippy/clippy_lints/src/types/box_collection.rs new file mode 100644 index 000000000..ba51404d2 --- /dev/null +++ b/src/tools/clippy/clippy_lints/src/types/box_collection.rs @@ -0,0 +1,54 @@ +use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::{path_def_id, qpath_generic_tys}; +use rustc_hir::{self as hir, def_id::DefId, QPath}; +use rustc_lint::LateContext; +use rustc_span::{sym, Symbol}; + +use super::BOX_COLLECTION; + +pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool { + if_chain! { + if Some(def_id) == cx.tcx.lang_items().owned_box(); + if let Some(item_type) = get_std_collection(cx, qpath); + then { + let generic = match item_type { + sym::String => "", + _ => "<..>", + }; + + let box_content = format!("{outer}{generic}", outer = item_type); + span_lint_and_help( + cx, + BOX_COLLECTION, + hir_ty.span, + &format!( + "you seem to be trying to use `Box<{box_content}>`. Consider using just `{box_content}`"), + None, + &format!( + "`{box_content}` is already on the heap, `Box<{box_content}>` makes an extra allocation") + ); + true + } else { + false + } + } +} + +fn get_std_collection(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<Symbol> { + let param = qpath_generic_tys(qpath).next()?; + let id = path_def_id(cx, param)?; + cx.tcx.get_diagnostic_name(id).filter(|&name| { + matches!( + name, + sym::HashMap + | sym::String + | sym::Vec + | sym::HashSet + | sym::VecDeque + | sym::LinkedList + | sym::BTreeMap + | sym::BTreeSet + | sym::BinaryHeap + ) + }) +} |