Skip to content

Commit 41be515

Browse files
committed
mem_replace_with_default: use diagnostic items intead of paths
1 parent c86ba7f commit 41be515

File tree

3 files changed

+35
-24
lines changed

3 files changed

+35
-24
lines changed

clippy_lints/src/mem_replace.rs

+34-15
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::utils::{
44
};
55
use if_chain::if_chain;
66
use rustc_errors::Applicability;
7+
use rustc_hir::def_id::DefId;
78
use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, QPath};
89
use rustc_lint::{LateContext, LateLintPass, LintContext};
910
use rustc_middle::lint::in_external_macro;
@@ -12,6 +13,8 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
1213
use rustc_span::source_map::Span;
1314
use rustc_span::symbol::sym;
1415

16+
use clippy_utils::is_diagnostic_assoc_item;
17+
1518
declare_clippy_lint! {
1619
/// **What it does:** Checks for `mem::replace()` on an `Option` with
1720
/// `None`.
@@ -194,27 +197,43 @@ fn check_replace_with_uninit(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'
194197
}
195198
}
196199

200+
/// Returns true if the `def_id` associated with the `path` is recognized as a "default-equivalent"
201+
/// constructor from the std library
202+
fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath<'_>) -> bool {
203+
let std_types_symbols = &[
204+
sym::string_type,
205+
sym::vec_type,
206+
sym::vecdeque_type,
207+
sym::LinkedList,
208+
sym::hashmap_type,
209+
sym::BTreeMap,
210+
sym::hashset_type,
211+
sym::BTreeSet,
212+
sym::BinaryHeap,
213+
];
214+
215+
if std_types_symbols
216+
.iter()
217+
.any(|symbol| is_diagnostic_assoc_item(cx, def_id, *symbol))
218+
{
219+
if let QPath::TypeRelative(_, ref method) = path {
220+
if method.ident.name == sym::new {
221+
return true;
222+
}
223+
}
224+
}
225+
226+
false
227+
}
228+
197229
fn check_replace_with_default(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) {
198230
if let ExprKind::Call(ref repl_func, _) = src.kind {
199231
if_chain! {
200232
if !in_external_macro(cx.tcx.sess, expr_span);
201233
if let ExprKind::Path(ref repl_func_qpath) = repl_func.kind;
202234
if let Some(repl_def_id) = cx.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id();
203-
204-
let defaults = &[
205-
paths::DEFAULT_TRAIT_METHOD.as_ref(),
206-
paths::STRING_NEW.as_ref(),
207-
paths::VEC_NEW.as_ref(),
208-
paths::VEC_DEQUE_NEW.as_ref(),
209-
paths::LINKED_LIST_NEW.as_ref(),
210-
paths::HASHMAP_NEW.as_ref(),
211-
paths::BTREEMAP_NEW.as_ref(),
212-
paths::HASHSET_NEW.as_ref(),
213-
paths::BTREESET_NEW.as_ref(),
214-
paths::BINARY_HEAP_NEW.as_ref(),
215-
];
216-
217-
if defaults.iter().any(|x| match_def_path(cx, repl_def_id, &x));
235+
if is_diagnostic_assoc_item(cx, repl_def_id, sym::Default)
236+
|| is_default_equivalent_ctor(cx, repl_def_id, repl_func_qpath);
218237

219238
then {
220239
span_lint_and_then(

clippy_utils/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ pub fn match_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, path: &[&str])
279279
trt_id.map_or(false, |trt_id| match_def_path(cx, trt_id, path))
280280
}
281281

282-
/// Checks if the method call given in `expr` belongs to a trait or other container with a given
282+
/// Checks if the method call given in `def_id` belongs to a trait or other container with a given
283283
/// diagnostic item
284284
pub fn is_diagnostic_assoc_item(cx: &LateContext<'_>, def_id: DefId, diag_item: Symbol) -> bool {
285285
cx.tcx

clippy_utils/src/paths.rs

-8
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,10 @@ pub const ASREF_TRAIT: [&str; 3] = ["core", "convert", "AsRef"];
1111
pub(super) const BEGIN_PANIC: [&str; 3] = ["std", "panicking", "begin_panic"];
1212
pub(super) const BEGIN_PANIC_FMT: [&str; 3] = ["std", "panicking", "begin_panic_fmt"];
1313
pub const BINARY_HEAP: [&str; 4] = ["alloc", "collections", "binary_heap", "BinaryHeap"];
14-
pub const BINARY_HEAP_NEW: [&str; 5] = ["alloc", "collections", "binary_heap", "BinaryHeap", "new"];
1514
pub const BORROW_TRAIT: [&str; 3] = ["core", "borrow", "Borrow"];
1615
pub const BTREEMAP: [&str; 5] = ["alloc", "collections", "btree", "map", "BTreeMap"];
17-
pub const BTREEMAP_NEW: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "new"];
1816
pub const BTREEMAP_ENTRY: [&str; 6] = ["alloc", "collections", "btree", "map", "entry", "Entry"];
1917
pub const BTREESET: [&str; 5] = ["alloc", "collections", "btree", "set", "BTreeSet"];
20-
pub const BTREESET_NEW: [&str; 6] = ["alloc", "collections", "btree", "set", "BTreeSet", "new"];
2118
pub const CLONE_TRAIT_METHOD: [&str; 4] = ["core", "clone", "Clone", "clone"];
2219
pub const CMP_MAX: [&str; 3] = ["core", "cmp", "max"];
2320
pub const CMP_MIN: [&str; 3] = ["core", "cmp", "min"];
@@ -49,10 +46,8 @@ pub const FROM_ITERATOR: [&str; 5] = ["core", "iter", "traits", "collect", "From
4946
pub const FUTURE_FROM_GENERATOR: [&str; 3] = ["core", "future", "from_generator"];
5047
pub const HASH: [&str; 3] = ["core", "hash", "Hash"];
5148
pub const HASHMAP: [&str; 5] = ["std", "collections", "hash", "map", "HashMap"];
52-
pub const HASHMAP_NEW: [&str; 6] = ["std", "collections", "hash", "map", "HashMap", "new"];
5349
pub const HASHMAP_ENTRY: [&str; 5] = ["std", "collections", "hash", "map", "Entry"];
5450
pub const HASHSET: [&str; 5] = ["std", "collections", "hash", "set", "HashSet"];
55-
pub const HASHSET_NEW: [&str; 6] = ["std", "collections", "hash", "set", "HashSet", "new"];
5651
#[cfg(feature = "internal-lints")]
5752
pub const IDENT: [&str; 3] = ["rustc_span", "symbol", "Ident"];
5853
#[cfg(feature = "internal-lints")]
@@ -72,7 +67,6 @@ pub const KW_MODULE: [&str; 3] = ["rustc_span", "symbol", "kw"];
7267
#[cfg(feature = "internal-lints")]
7368
pub const LATE_CONTEXT: [&str; 2] = ["rustc_lint", "LateContext"];
7469
pub const LINKED_LIST: [&str; 4] = ["alloc", "collections", "linked_list", "LinkedList"];
75-
pub const LINKED_LIST_NEW: [&str; 5] = ["alloc", "collections", "linked_list", "LinkedList", "new"];
7670
#[cfg(feature = "internal-lints")]
7771
pub const LINT: [&str; 2] = ["rustc_lint_defs", "Lint"];
7872
pub const MEM_DISCRIMINANT: [&str; 3] = ["core", "mem", "discriminant"];
@@ -140,7 +134,6 @@ pub const STD_CONVERT_IDENTITY: [&str; 3] = ["std", "convert", "identity"];
140134
pub const STD_FS_CREATE_DIR: [&str; 3] = ["std", "fs", "create_dir"];
141135
pub const STD_MEM_TRANSMUTE: [&str; 3] = ["std", "mem", "transmute"];
142136
pub const STD_PTR_NULL: [&str; 3] = ["std", "ptr", "null"];
143-
pub const STRING_NEW: [&str; 4] = ["alloc", "string", "String", "new"];
144137
pub const STRING_AS_MUT_STR: [&str; 4] = ["alloc", "string", "String", "as_mut_str"];
145138
pub const STRING_AS_STR: [&str; 4] = ["alloc", "string", "String", "as_str"];
146139
pub const STR_ENDS_WITH: [&str; 4] = ["core", "str", "<impl str>", "ends_with"];
@@ -168,7 +161,6 @@ pub const VEC: [&str; 3] = ["alloc", "vec", "Vec"];
168161
pub const VEC_AS_MUT_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_mut_slice"];
169162
pub const VEC_AS_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_slice"];
170163
pub const VEC_DEQUE: [&str; 4] = ["alloc", "collections", "vec_deque", "VecDeque"];
171-
pub const VEC_DEQUE_NEW: [&str; 5] = ["alloc", "collections", "vec_deque", "VecDeque", "new"];
172164
pub const VEC_FROM_ELEM: [&str; 3] = ["alloc", "vec", "from_elem"];
173165
pub const VEC_NEW: [&str; 4] = ["alloc", "vec", "Vec", "new"];
174166
pub const VEC_RESIZE: [&str; 4] = ["alloc", "vec", "Vec", "resize"];

0 commit comments

Comments
 (0)