From 4a6e67ead7a29bca80b7f4a315ac666e2c6e2260 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Fri, 26 Feb 2021 22:04:02 -0600 Subject: [PATCH 1/3] Add missing diagnostic item Symbols --- compiler/rustc_span/src/symbol.rs | 2 ++ src/tools/clippy/clippy_lints/src/entry.rs | 3 ++- src/tools/clippy/clippy_lints/src/loops.rs | 16 ++++++++-------- src/tools/clippy/clippy_lints/src/methods/mod.rs | 6 +++--- src/tools/clippy/clippy_lints/src/swap.rs | 2 +- src/tools/clippy/clippy_lints/src/types.rs | 4 ++-- .../clippy_lints/src/zero_sized_map_values.rs | 3 ++- .../clippy/clippy_utils/src/eager_or_lazy.rs | 3 ++- 8 files changed, 22 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 6fe65a8a1cd..c8a4085069f 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -592,6 +592,8 @@ symbols! { gt, half_open_range_patterns, hash, + hashmap_type, + hashset_type, hexagon_target_feature, hidden, homogeneous_aggregate, diff --git a/src/tools/clippy/clippy_lints/src/entry.rs b/src/tools/clippy/clippy_lints/src/entry.rs index 6b9f9a56754..55575969927 100644 --- a/src/tools/clippy/clippy_lints/src/entry.rs +++ b/src/tools/clippy/clippy_lints/src/entry.rs @@ -9,6 +9,7 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::map::Map; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; +use rustc_span::sym; declare_clippy_lint! { /// **What it does:** Checks for uses of `contains_key` + `insert` on `HashMap` @@ -111,7 +112,7 @@ fn check_cond<'a>(cx: &LateContext<'_>, check: &'a Expr<'a>) -> Option<(&'static return if match_type(cx, obj_ty, &paths::BTREEMAP) { Some(("BTreeMap", map, key)) } - else if is_type_diagnostic_item(cx, obj_ty, sym!(hashmap_type)) { + else if is_type_diagnostic_item(cx, obj_ty, sym::hashmap_type) { Some(("HashMap", map, key)) } else { diff --git a/src/tools/clippy/clippy_lints/src/loops.rs b/src/tools/clippy/clippy_lints/src/loops.rs index 1c9373a756c..63d9b7f8645 100644 --- a/src/tools/clippy/clippy_lints/src/loops.rs +++ b/src/tools/clippy/clippy_lints/src/loops.rs @@ -1010,7 +1010,7 @@ fn is_slice_like<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'_>) -> bool { _ => false, }; - is_slice || is_type_diagnostic_item(cx, ty, sym::vec_type) || is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) + is_slice || is_type_diagnostic_item(cx, ty, sym::vec_type) || is_type_diagnostic_item(cx, ty, sym::vecdeque_type) } fn fetch_cloned_expr<'tcx>(expr: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> { @@ -1908,7 +1908,7 @@ fn check_for_loop_over_map_kv<'tcx>( _ => arg, }; - if is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) || match_type(cx, ty, &paths::BTREEMAP) { + if is_type_diagnostic_item(cx, ty, sym::hashmap_type) || match_type(cx, ty, &paths::BTREEMAP) { span_lint_and_then( cx, FOR_KV_MAP, @@ -2386,9 +2386,9 @@ fn is_ref_iterable_type(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { is_iterable_array(ty, cx) || is_type_diagnostic_item(cx, ty, sym::vec_type) || match_type(cx, ty, &paths::LINKED_LIST) || - is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) || - is_type_diagnostic_item(cx, ty, sym!(hashset_type)) || - is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) || + is_type_diagnostic_item(cx, ty, sym::hashmap_type) || + is_type_diagnostic_item(cx, ty, sym::hashset_type) || + is_type_diagnostic_item(cx, ty, sym::vecdeque_type) || match_type(cx, ty, &paths::BINARY_HEAP) || match_type(cx, ty, &paths::BTREEMAP) || match_type(cx, ty, &paths::BTREESET) @@ -2922,9 +2922,9 @@ fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCont then { let ty = cx.typeck_results().node_type(ty.hir_id); if is_type_diagnostic_item(cx, ty, sym::vec_type) || - is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) || + is_type_diagnostic_item(cx, ty, sym::vecdeque_type) || match_type(cx, ty, &paths::BTREEMAP) || - is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) { + is_type_diagnostic_item(cx, ty, sym::hashmap_type) { if method.ident.name == sym!(len) { let span = shorten_needless_collect_span(expr); span_lint_and_sugg( @@ -2992,7 +2992,7 @@ fn check_needless_collect_indirect_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCo if let Some(GenericArg::Type(ref ty)) = generic_args.args.get(0); if let ty = cx.typeck_results().node_type(ty.hir_id); if is_type_diagnostic_item(cx, ty, sym::vec_type) || - is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) || + is_type_diagnostic_item(cx, ty, sym::vecdeque_type) || match_type(cx, ty, &paths::LINKED_LIST); if let Some(iter_calls) = detect_iter_and_into_iters(block, *ident); if iter_calls.len() == 1; diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index ebd8af93dd0..f101b6476f5 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -2598,7 +2598,7 @@ fn lint_iter_nth<'tcx>( "slice" } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym::vec_type) { "Vec" - } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym!(vecdeque_type)) { + } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym::vecdeque_type) { "VecDeque" } else { let nth_args = nth_and_iter_args[0]; @@ -2652,10 +2652,10 @@ fn lint_get_unwrap<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, get_args: } else if is_type_diagnostic_item(cx, expr_ty, sym::vec_type) { needs_ref = get_args_str.parse::().is_ok(); "Vec" - } else if is_type_diagnostic_item(cx, expr_ty, sym!(vecdeque_type)) { + } else if is_type_diagnostic_item(cx, expr_ty, sym::vecdeque_type) { needs_ref = get_args_str.parse::().is_ok(); "VecDeque" - } else if !is_mut && is_type_diagnostic_item(cx, expr_ty, sym!(hashmap_type)) { + } else if !is_mut && is_type_diagnostic_item(cx, expr_ty, sym::hashmap_type) { needs_ref = true; "HashMap" } else if !is_mut && match_type(cx, expr_ty, &paths::BTREEMAP) { diff --git a/src/tools/clippy/clippy_lints/src/swap.rs b/src/tools/clippy/clippy_lints/src/swap.rs index 699fd51ccc1..9d8a0c24833 100644 --- a/src/tools/clippy/clippy_lints/src/swap.rs +++ b/src/tools/clippy/clippy_lints/src/swap.rs @@ -199,7 +199,7 @@ fn check_for_slice<'a>(cx: &LateContext<'_>, lhs1: &'a Expr<'_>, lhs2: &'a Expr< if matches!(ty.kind(), ty::Slice(_)) || matches!(ty.kind(), ty::Array(_, _)) || is_type_diagnostic_item(cx, ty, sym::vec_type) - || is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) + || is_type_diagnostic_item(cx, ty, sym::vecdeque_type) { return Slice::Swappable(lhs1, idx1, idx2); } diff --git a/src/tools/clippy/clippy_lints/src/types.rs b/src/tools/clippy/clippy_lints/src/types.rs index 05754503163..eb2016db3dc 100644 --- a/src/tools/clippy/clippy_lints/src/types.rs +++ b/src/tools/clippy/clippy_lints/src/types.rs @@ -2680,14 +2680,14 @@ impl<'tcx> ImplicitHasherType<'tcx> { let ty = hir_ty_to_ty(cx.tcx, hir_ty); - if is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) && params_len == 2 { + if is_type_diagnostic_item(cx, ty, sym::hashmap_type) && params_len == 2 { Some(ImplicitHasherType::HashMap( hir_ty.span, ty, snippet(cx, params[0].span, "K"), snippet(cx, params[1].span, "V"), )) - } else if is_type_diagnostic_item(cx, ty, sym!(hashset_type)) && params_len == 1 { + } else if is_type_diagnostic_item(cx, ty, sym::hashset_type) && params_len == 1 { Some(ImplicitHasherType::HashSet( hir_ty.span, ty, diff --git a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs index 319b85ac42a..316b8d820a7 100644 --- a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs +++ b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs @@ -5,6 +5,7 @@ use rustc_middle::ty::{Adt, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_target::abi::LayoutOf as _; use rustc_typeck::hir_ty_to_ty; +use rustc_span::sym; use crate::utils::{is_normalizable, is_type_diagnostic_item, match_type, paths, span_lint_and_help}; @@ -47,7 +48,7 @@ impl LateLintPass<'_> for ZeroSizedMapValues { if !hir_ty.span.from_expansion(); if !in_trait_impl(cx, hir_ty.hir_id); let ty = ty_from_hir_ty(cx, hir_ty); - if is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) || match_type(cx, ty, &paths::BTREEMAP); + if is_type_diagnostic_item(cx, ty, sym::hashmap_type) || match_type(cx, ty, &paths::BTREEMAP); if let Adt(_, ref substs) = ty.kind(); let ty = substs.type_at(1); // Do this to prevent `layout_of` crashing, being unable to fully normalize `ty`. diff --git a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs index 52a33e9b170..81cd99c0558 100644 --- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs +++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs @@ -18,6 +18,7 @@ use rustc_hir::intravisit::{NestedVisitorMap, Visitor}; use rustc_hir::{Block, Expr, ExprKind, Path, QPath}; use rustc_lint::LateContext; use rustc_middle::hir::map::Map; +use rustc_span::sym; /// Is the expr pure (is it free from side-effects)? /// This function is named so to stress that it isn't exhaustive and returns FNs. @@ -99,7 +100,7 @@ fn identify_some_potentially_expensive_patterns<'tcx>(cx: &LateContext<'tcx>, ex ExprKind::Call(..) => !is_ctor_or_promotable_const_function(self.cx, expr), ExprKind::Index(obj, _) => { let ty = self.cx.typeck_results().expr_ty(obj); - is_type_diagnostic_item(self.cx, ty, sym!(hashmap_type)) + is_type_diagnostic_item(self.cx, ty, sym::hashmap_type) || match_type(self.cx, ty, &paths::BTREEMAP) }, ExprKind::MethodCall(..) => true, From eada4d1c457f4421713cdabe7b57d70ae23a4278 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Fri, 26 Feb 2021 21:23:42 -0600 Subject: [PATCH 2/3] Add diagnostic items --- compiler/rustc_span/src/symbol.rs | 5 +++++ library/alloc/src/collections/binary_heap.rs | 1 + library/alloc/src/collections/btree/map.rs | 1 + library/alloc/src/collections/btree/set.rs | 1 + library/alloc/src/collections/linked_list.rs | 1 + library/std/src/sync/mpsc/mod.rs | 1 + 6 files changed, 10 insertions(+) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index c8a4085069f..1cc43fa8eb2 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -126,6 +126,9 @@ symbols! { Argument, ArgumentV1, Arguments, + BTreeMap, + BTreeSet, + BinaryHeap, C, CString, Center, @@ -163,6 +166,7 @@ symbols! { Iterator, Layout, Left, + LinkedList, LintPass, None, Ok, @@ -1258,6 +1262,7 @@ symbols! { variant_count, vec, vec_type, + vecdeque_type, version, vis, visible_private_types, diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs index 33bd98d467c..4377780e15f 100644 --- a/library/alloc/src/collections/binary_heap.rs +++ b/library/alloc/src/collections/binary_heap.rs @@ -247,6 +247,7 @@ use super::SpecExtend; /// [peek]: BinaryHeap::peek /// [peek\_mut]: BinaryHeap::peek_mut #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(not(test), rustc_diagnostic_item = "BinaryHeap")] pub struct BinaryHeap { data: Vec, } diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 3ba95d9f47a..783f88f026b 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -138,6 +138,7 @@ pub(super) const MIN_LEN: usize = node::MIN_LEN_AFTER_SPLIT; /// *stat += random_stat_buff(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(not(test), rustc_diagnostic_item = "BTreeMap")] pub struct BTreeMap { root: Option>, length: usize, diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index f2ec2774484..a331b8d8e4b 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -61,6 +61,7 @@ use super::Recover; /// ``` #[derive(Hash, PartialEq, Eq, Ord, PartialOrd)] #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(not(test), rustc_diagnostic_item = "BTreeSet")] pub struct BTreeSet { map: BTreeMap, } diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index 397e774f1a0..a5481fd175e 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -35,6 +35,7 @@ mod tests; /// array-based containers are generally faster, /// more memory efficient, and make better use of CPU cache. #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(not(test), rustc_diagnostic_item = "LinkedList")] pub struct LinkedList { head: Option>>, tail: Option>>, diff --git a/library/std/src/sync/mpsc/mod.rs b/library/std/src/sync/mpsc/mod.rs index db0777ee9f0..b12e7eeb138 100644 --- a/library/std/src/sync/mpsc/mod.rs +++ b/library/std/src/sync/mpsc/mod.rs @@ -310,6 +310,7 @@ mod cache_aligned; /// println!("{}", recv.recv().unwrap()); // Received after 2 seconds /// ``` #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(not(test), rustc_diagnostic_item = "Receiver")] pub struct Receiver { inner: UnsafeCell>, } From 6a3b834b39e0d6418e96cd7e3abd8043afd89d1c Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Fri, 26 Feb 2021 21:17:29 -0600 Subject: [PATCH 3/3] Use diagnostic items in into_iter_collections --- compiler/rustc_span/src/symbol.rs | 1 + .../clippy/clippy_lints/src/methods/mod.rs | 4 +- src/tools/clippy/clippy_utils/src/lib.rs | 40 +++++++++---------- src/tools/clippy/clippy_utils/src/paths.rs | 2 - 4 files changed, 23 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 1cc43fa8eb2..f87267da9f6 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -195,6 +195,7 @@ symbols! { RangeToInclusive, Rc, Ready, + Receiver, Result, Return, Right, diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index f101b6476f5..5163074453b 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -24,7 +24,7 @@ use rustc_middle::ty::{self, TraitRef, Ty, TyS}; use rustc_semver::RustcVersion; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::source_map::Span; -use rustc_span::symbol::{sym, SymbolStr}; +use rustc_span::symbol::{sym, Symbol, SymbolStr}; use rustc_typeck::hir_ty_to_ty; use crate::consts::{constant, Constant}; @@ -3619,7 +3619,7 @@ fn lint_asref(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str, as_re } } -fn ty_has_iter_method(cx: &LateContext<'_>, self_ref_ty: Ty<'_>) -> Option<(&'static str, &'static str)> { +fn ty_has_iter_method(cx: &LateContext<'_>, self_ref_ty: Ty<'_>) -> Option<(Symbol, &'static str)> { has_iter_method(cx, self_ref_ty).map(|ty_name| { let mutbl = match self_ref_ty.kind() { ty::Ref(_, _, mutbl) => mutbl, diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 94b7339c7eb..42512cadfb1 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -1295,24 +1295,24 @@ pub fn any_parent_is_automatically_derived(tcx: TyCtxt<'_>, node: HirId) -> bool } /// Returns true if ty has `iter` or `iter_mut` methods -pub fn has_iter_method(cx: &LateContext<'_>, probably_ref_ty: Ty<'_>) -> Option<&'static str> { +pub fn has_iter_method(cx: &LateContext<'_>, probably_ref_ty: Ty<'_>) -> Option { // FIXME: instead of this hard-coded list, we should check if `::iter` // exists and has the desired signature. Unfortunately FnCtxt is not exported // so we can't use its `lookup_method` method. - let into_iter_collections: [&[&str]; 13] = [ - &paths::VEC, - &paths::OPTION, - &paths::RESULT, - &paths::BTREESET, - &paths::BTREEMAP, - &paths::VEC_DEQUE, - &paths::LINKED_LIST, - &paths::BINARY_HEAP, - &paths::HASHSET, - &paths::HASHMAP, - &paths::PATH_BUF, - &paths::PATH, - &paths::RECEIVER, + let into_iter_collections: &[Symbol] = &[ + sym::vec_type, + sym::option_type, + sym::result_type, + sym::BTreeMap, + sym::BTreeSet, + sym::vecdeque_type, + sym::LinkedList, + sym::BinaryHeap, + sym::hashset_type, + sym::hashmap_type, + sym::PathBuf, + sym::Path, + sym::Receiver, ]; let ty_to_check = match probably_ref_ty.kind() { @@ -1321,15 +1321,15 @@ pub fn has_iter_method(cx: &LateContext<'_>, probably_ref_ty: Ty<'_>) -> Option< }; let def_id = match ty_to_check.kind() { - ty::Array(..) => return Some("array"), - ty::Slice(..) => return Some("slice"), + ty::Array(..) => return Some(sym::array), + ty::Slice(..) => return Some(sym::slice), ty::Adt(adt, _) => adt.did, _ => return None, }; - for path in &into_iter_collections { - if match_def_path(cx, def_id, path) { - return Some(*path.last().unwrap()); + for &name in into_iter_collections { + if cx.tcx.is_diagnostic_item(name, def_id) { + return Some(cx.tcx.item_name(def_id)); } } None diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs index e6178679647..c2da1f9b7c9 100644 --- a/src/tools/clippy/clippy_utils/src/paths.rs +++ b/src/tools/clippy/clippy_utils/src/paths.rs @@ -99,7 +99,6 @@ pub(super) const PANIC_ANY: [&str; 3] = ["std", "panic", "panic_any"]; pub const PARKING_LOT_MUTEX_GUARD: [&str; 2] = ["parking_lot", "MutexGuard"]; pub const PARKING_LOT_RWLOCK_READ_GUARD: [&str; 2] = ["parking_lot", "RwLockReadGuard"]; pub const PARKING_LOT_RWLOCK_WRITE_GUARD: [&str; 2] = ["parking_lot", "RwLockWriteGuard"]; -pub const PATH: [&str; 3] = ["std", "path", "Path"]; pub const PATH_BUF: [&str; 3] = ["std", "path", "PathBuf"]; pub const PATH_BUF_AS_PATH: [&str; 4] = ["std", "path", "PathBuf", "as_path"]; pub const PATH_TO_PATH_BUF: [&str; 4] = ["std", "path", "Path", "to_path_buf"]; @@ -116,7 +115,6 @@ pub const PUSH_STR: [&str; 4] = ["alloc", "string", "String", "push_str"]; pub const RANGE_ARGUMENT_TRAIT: [&str; 3] = ["core", "ops", "RangeBounds"]; pub const RC: [&str; 3] = ["alloc", "rc", "Rc"]; pub const RC_PTR_EQ: [&str; 4] = ["alloc", "rc", "Rc", "ptr_eq"]; -pub const RECEIVER: [&str; 4] = ["std", "sync", "mpsc", "Receiver"]; pub const REFCELL_REF: [&str; 3] = ["core", "cell", "Ref"]; pub const REFCELL_REFMUT: [&str; 3] = ["core", "cell", "RefMut"]; pub const REGEX_BUILDER_NEW: [&str; 5] = ["regex", "re_builder", "unicode", "RegexBuilder", "new"];