More diagnostic items

In particular for:

* `VecDeque`
* `String`
* `Mutex`
* `HashMap`
* `HashSet`

cc https://github.com/rust-lang/rust/pull/71414 https://github.com/rust-lang/rust-clippy/issues/5393
This commit is contained in:
Philipp Hansch 2020-04-23 08:09:42 +02:00
parent b7c802b5e3
commit 0480ff861a
No known key found for this signature in database
GPG Key ID: 2B4399C4BF4DCBDE
15 changed files with 57 additions and 52 deletions

View File

@ -1,5 +1,5 @@
use crate::utils::SpanlessEq; use crate::utils::SpanlessEq;
use crate::utils::{get_item_name, higher, match_type, paths, snippet, snippet_opt}; use crate::utils::{get_item_name, higher, is_type_diagnostic_item, match_type, paths, snippet, snippet_opt};
use crate::utils::{snippet_with_applicability, span_lint_and_then, walk_ptrs_ty}; use crate::utils::{snippet_with_applicability, span_lint_and_then, walk_ptrs_ty};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
@ -114,7 +114,7 @@ fn check_cond<'a, 'tcx, 'b>(
return if match_type(cx, obj_ty, &paths::BTREEMAP) { return if match_type(cx, obj_ty, &paths::BTREEMAP) {
Some(("BTreeMap", map, key)) Some(("BTreeMap", map, key))
} }
else if match_type(cx, obj_ty, &paths::HASHMAP) { else if is_type_diagnostic_item(cx, obj_ty, sym!(hashmap_type)) {
Some(("HashMap", map, key)) Some(("HashMap", map, key))
} }
else { else {

View File

@ -1,6 +1,6 @@
use crate::utils::paths; use crate::utils::paths;
use crate::utils::{ use crate::utils::{
is_expn_of, last_path_segment, match_def_path, match_function_call, match_type, snippet, span_lint_and_then, is_expn_of, is_type_diagnostic_item, last_path_segment, match_def_path, match_function_call, snippet, span_lint_and_then,
walk_ptrs_ty, walk_ptrs_ty,
}; };
use if_chain::if_chain; use if_chain::if_chain;
@ -91,7 +91,7 @@ fn on_argumentv1_new<'a, 'tcx>(
if pats.len() == 1; if pats.len() == 1;
then { then {
let ty = walk_ptrs_ty(cx.tables.pat_ty(&pats[0])); let ty = walk_ptrs_ty(cx.tables.pat_ty(&pats[0]));
if ty.kind != rustc_middle::ty::Str && !match_type(cx, ty, &paths::STRING) { if ty.kind != rustc_middle::ty::Str && !is_type_diagnostic_item(cx, ty, sym!(string_type)) {
return None; return None;
} }
if let ExprKind::Lit(ref lit) = format_args.kind { if let ExprKind::Lit(ref lit) = format_args.kind {

View File

@ -1,4 +1,4 @@
use crate::utils::{match_type, paths, span_lint_and_help, SpanlessEq}; use crate::utils::{is_type_diagnostic_item, span_lint_and_help, SpanlessEq};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_hir::intravisit::{self as visit, NestedVisitorMap, Visitor}; use rustc_hir::intravisit::{self as visit, NestedVisitorMap, Visitor};
use rustc_hir::{Expr, ExprKind, MatchSource}; use rustc_hir::{Expr, ExprKind, MatchSource};
@ -150,7 +150,7 @@ fn is_mutex_lock_call<'a>(cx: &LateContext<'a, '_>, expr: &'a Expr<'_>) -> Optio
if let ExprKind::MethodCall(path, _span, args) = &expr.kind; if let ExprKind::MethodCall(path, _span, args) = &expr.kind;
if path.ident.to_string() == "lock"; if path.ident.to_string() == "lock";
let ty = cx.tables.expr_ty(&args[0]); let ty = cx.tables.expr_ty(&args[0]);
if match_type(cx, ty, &paths::MUTEX); if is_type_diagnostic_item(cx, ty, sym!(mutex_type));
then { then {
Some(&args[0]) Some(&args[0])
} else { } else {

View File

@ -4,7 +4,7 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use crate::utils::{ use crate::utils::{
get_trait_def_id, implements_trait, match_type, paths, return_ty, span_lint_and_help, trait_ref_of_method, get_trait_def_id, is_type_diagnostic_item, implements_trait, paths, return_ty, span_lint_and_help, trait_ref_of_method,
walk_ptrs_ty, walk_ptrs_ty,
}; };
@ -107,7 +107,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InherentToString {
if decl.inputs.len() == 1; if decl.inputs.len() == 1;
// Check if return type is String // Check if return type is String
if match_type(cx, return_ty(cx, impl_item.hir_id), &paths::STRING); if is_type_diagnostic_item(cx, return_ty(cx, impl_item.hir_id), sym!(string_type));
// Filters instances of to_string which are required by a trait // Filters instances of to_string which are required by a trait
if trait_ref_of_method(cx, impl_item.hir_id).is_none(); if trait_ref_of_method(cx, impl_item.hir_id).is_none();

View File

@ -816,7 +816,7 @@ fn is_slice_like<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'_>) -> bool {
_ => false, _ => false,
}; };
is_slice || is_type_diagnostic_item(cx, ty, sym!(vec_type)) || match_type(cx, ty, &paths::VEC_DEQUE) is_slice || is_type_diagnostic_item(cx, ty, sym!(vec_type)) || is_type_diagnostic_item(cx, ty, sym!(vecdeque_type))
} }
fn get_fixed_offset_var<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr<'_>, var: HirId) -> Option<FixedOffsetVar> { fn get_fixed_offset_var<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr<'_>, var: HirId) -> Option<FixedOffsetVar> {
@ -1569,7 +1569,7 @@ fn check_for_loop_over_map_kv<'a, 'tcx>(
_ => arg, _ => arg,
}; };
if match_type(cx, ty, &paths::HASHMAP) || 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( span_lint_and_then(
cx, cx,
FOR_KV_MAP, FOR_KV_MAP,
@ -1971,9 +1971,9 @@ fn is_ref_iterable_type(cx: &LateContext<'_, '_>, e: &Expr<'_>) -> bool {
is_iterable_array(ty, cx) || is_iterable_array(ty, cx) ||
is_type_diagnostic_item(cx, ty, sym!(vec_type)) || is_type_diagnostic_item(cx, ty, sym!(vec_type)) ||
match_type(cx, ty, &paths::LINKED_LIST) || match_type(cx, ty, &paths::LINKED_LIST) ||
match_type(cx, ty, &paths::HASHMAP) || is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) ||
match_type(cx, ty, &paths::HASHSET) || is_type_diagnostic_item(cx, ty, sym!(hashset_type)) ||
match_type(cx, ty, &paths::VEC_DEQUE) || is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) ||
match_type(cx, ty, &paths::BINARY_HEAP) || match_type(cx, ty, &paths::BINARY_HEAP) ||
match_type(cx, ty, &paths::BTREEMAP) || match_type(cx, ty, &paths::BTREEMAP) ||
match_type(cx, ty, &paths::BTREESET) match_type(cx, ty, &paths::BTREESET)
@ -2480,9 +2480,9 @@ fn check_needless_collect<'a, 'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'a, '
then { then {
let ty = cx.tables.node_type(ty.hir_id); let ty = cx.tables.node_type(ty.hir_id);
if is_type_diagnostic_item(cx, ty, sym!(vec_type)) || if is_type_diagnostic_item(cx, ty, sym!(vec_type)) ||
match_type(cx, ty, &paths::VEC_DEQUE) || is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) ||
match_type(cx, ty, &paths::BTREEMAP) || match_type(cx, ty, &paths::BTREEMAP) ||
match_type(cx, ty, &paths::HASHMAP) { is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) {
if method.ident.name == sym!(len) { if method.ident.name == sym!(len) {
let span = shorten_needless_collect_span(expr); let span = shorten_needless_collect_span(expr);
span_lint_and_sugg( span_lint_and_sugg(

View File

@ -1,5 +1,5 @@
use super::INEFFICIENT_TO_STRING; use super::INEFFICIENT_TO_STRING;
use crate::utils::{match_def_path, paths, snippet_with_applicability, span_lint_and_then, walk_ptrs_ty_depth}; use crate::utils::{match_def_path, is_type_diagnostic_item, paths, snippet_with_applicability, span_lint_and_then, walk_ptrs_ty_depth};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
@ -44,12 +44,18 @@ pub fn lint<'tcx>(cx: &LateContext<'_, 'tcx>, expr: &hir::Expr<'_>, arg: &hir::E
/// Returns whether `ty` specializes `ToString`. /// Returns whether `ty` specializes `ToString`.
/// Currently, these are `str`, `String`, and `Cow<'_, str>`. /// Currently, these are `str`, `String`, and `Cow<'_, str>`.
fn specializes_tostring(cx: &LateContext<'_, '_>, ty: Ty<'_>) -> bool { fn specializes_tostring(cx: &LateContext<'_, '_>, ty: Ty<'_>) -> bool {
match ty.kind { if let ty::Str = ty.kind {
ty::Str => true, return true
ty::Adt(adt, substs) => { }
match_def_path(cx, adt.did, &paths::STRING)
|| (match_def_path(cx, adt.did, &paths::COW) && substs.type_at(1).is_str()) if is_type_diagnostic_item(cx, ty, sym!(string_type)) {
}, return true
_ => false, }
if let ty::Adt(adt, substs) = ty.kind {
match_def_path(cx, adt.did, &paths::COW) &&
substs.type_at(1).is_str()
} else {
false
} }
} }

View File

@ -1756,7 +1756,7 @@ fn lint_expect_fun_call(
&& { && {
let arg_type = cx.tables.expr_ty(&call_args[0]); let arg_type = cx.tables.expr_ty(&call_args[0]);
let base_type = walk_ptrs_ty(arg_type); let base_type = walk_ptrs_ty(arg_type);
base_type.kind == ty::Str || match_type(cx, base_type, &paths::STRING) base_type.kind == ty::Str || is_type_diagnostic_item(cx, base_type, sym!(string_type))
} }
{ {
&call_args[0] &call_args[0]
@ -1774,7 +1774,7 @@ fn lint_expect_fun_call(
// converted to string. // converted to string.
fn requires_to_string(cx: &LateContext<'_, '_>, arg: &hir::Expr<'_>) -> bool { fn requires_to_string(cx: &LateContext<'_, '_>, arg: &hir::Expr<'_>) -> bool {
let arg_ty = cx.tables.expr_ty(arg); let arg_ty = cx.tables.expr_ty(arg);
if match_type(cx, arg_ty, &paths::STRING) { if is_type_diagnostic_item(cx, arg_ty, sym!(string_type)) {
return false; return false;
} }
if let ty::Ref(_, ty, ..) = arg_ty.kind { if let ty::Ref(_, ty, ..) = arg_ty.kind {
@ -2054,7 +2054,7 @@ fn lint_string_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hi
let self_ty = walk_ptrs_ty(cx.tables.expr_ty(target)); let self_ty = walk_ptrs_ty(cx.tables.expr_ty(target));
let ref_str = if self_ty.kind == ty::Str { let ref_str = if self_ty.kind == ty::Str {
"" ""
} else if match_type(cx, self_ty, &paths::STRING) { } else if is_type_diagnostic_item(cx, self_ty, sym!(string_type)) {
"&" "&"
} else { } else {
return; return;
@ -2080,7 +2080,7 @@ fn lint_string_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hi
fn lint_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { fn lint_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(&args[0])); let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(&args[0]));
if match_type(cx, obj_ty, &paths::STRING) { if is_type_diagnostic_item(cx, obj_ty, sym!(string_type)) {
lint_string_extend(cx, expr, args); lint_string_extend(cx, expr, args);
} }
} }
@ -2242,7 +2242,7 @@ fn lint_iter_nth<'a, 'tcx>(
"slice" "slice"
} else if is_type_diagnostic_item(cx, cx.tables.expr_ty(&iter_args[0]), sym!(vec_type)) { } else if is_type_diagnostic_item(cx, cx.tables.expr_ty(&iter_args[0]), sym!(vec_type)) {
"Vec" "Vec"
} else if match_type(cx, cx.tables.expr_ty(&iter_args[0]), &paths::VEC_DEQUE) { } else if is_type_diagnostic_item(cx, cx.tables.expr_ty(&iter_args[0]), sym!(vecdeque_type)) {
"VecDeque" "VecDeque"
} else { } else {
let nth_args = nth_and_iter_args[0]; let nth_args = nth_and_iter_args[0];
@ -2301,10 +2301,10 @@ fn lint_get_unwrap<'a, 'tcx>(
} else if is_type_diagnostic_item(cx, expr_ty, sym!(vec_type)) { } else if is_type_diagnostic_item(cx, expr_ty, sym!(vec_type)) {
needs_ref = get_args_str.parse::<usize>().is_ok(); needs_ref = get_args_str.parse::<usize>().is_ok();
"Vec" "Vec"
} else if match_type(cx, expr_ty, &paths::VEC_DEQUE) { } else if is_type_diagnostic_item(cx, expr_ty, sym!(vecdeque_type)) {
needs_ref = get_args_str.parse::<usize>().is_ok(); needs_ref = get_args_str.parse::<usize>().is_ok();
"VecDeque" "VecDeque"
} else if !is_mut && match_type(cx, expr_ty, &paths::HASHMAP) { } else if !is_mut && is_type_diagnostic_item(cx, expr_ty, sym!(hashmap_type)) {
needs_ref = true; needs_ref = true;
"HashMap" "HashMap"
} else if !is_mut && match_type(cx, expr_ty, &paths::BTREEMAP) { } else if !is_mut && match_type(cx, expr_ty, &paths::BTREEMAP) {
@ -2510,7 +2510,7 @@ fn lint_map_flatten<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<
} }
// lint if caller of `.map().flatten()` is an Option // lint if caller of `.map().flatten()` is an Option
if match_type(cx, cx.tables.expr_ty(&map_args[0]), &paths::OPTION) { if is_type_diagnostic_item(cx, cx.tables.expr_ty(&map_args[0]), sym!(option_type)) {
let msg = "called `map(..).flatten()` on an `Option`. \ let msg = "called `map(..).flatten()` on an `Option`. \
This is more succinctly expressed by calling `.and_then(..)`"; This is more succinctly expressed by calling `.and_then(..)`";
let self_snippet = snippet(cx, map_args[0].span, ".."); let self_snippet = snippet(cx, map_args[0].span, "..");
@ -2678,7 +2678,7 @@ fn lint_option_and_then_some(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, arg
const NO_OP_MSG: &str = "using `Option.and_then(Some)`, which is a no-op"; const NO_OP_MSG: &str = "using `Option.and_then(Some)`, which is a no-op";
let ty = cx.tables.expr_ty(&args[0]); let ty = cx.tables.expr_ty(&args[0]);
if !match_type(cx, ty, &paths::OPTION) { if !is_type_diagnostic_item(cx, ty, sym!(option_type)) {
return; return;
} }
@ -3282,7 +3282,7 @@ fn lint_option_as_ref_deref<'a, 'tcx>(
let same_mutability = |m| (is_mut && m == &hir::Mutability::Mut) || (!is_mut && m == &hir::Mutability::Not); let same_mutability = |m| (is_mut && m == &hir::Mutability::Mut) || (!is_mut && m == &hir::Mutability::Not);
let option_ty = cx.tables.expr_ty(&as_ref_args[0]); let option_ty = cx.tables.expr_ty(&as_ref_args[0]);
if !match_type(cx, option_ty, &paths::OPTION) { if !is_type_diagnostic_item(cx, option_ty, sym!(option_type)) {
return; return;
} }

View File

@ -2,7 +2,7 @@
//! //!
//! This lint is **warn** by default //! This lint is **warn** by default
use crate::utils::{match_type, paths, span_lint}; use crate::utils::{is_type_diagnostic_item, span_lint};
use rustc_ast::ast; use rustc_ast::ast;
use rustc_hir::Expr; use rustc_hir::Expr;
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
@ -58,7 +58,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Mutex {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) {
let ty = cx.tables.expr_ty(expr); let ty = cx.tables.expr_ty(expr);
if let ty::Adt(_, subst) = ty.kind { if let ty::Adt(_, subst) = ty.kind {
if match_type(cx, ty, &paths::MUTEX) { if is_type_diagnostic_item(cx, ty, sym!(mutex_type)) {
let mutex_param = subst.type_at(0); let mutex_param = subst.type_at(0);
if let Some(atomic_name) = get_atomic_name(mutex_param) { if let Some(atomic_name) = get_atomic_name(mutex_param) {
let msg = format!( let msg = format!(

View File

@ -1,6 +1,6 @@
use crate::utils::ptr::get_spans; use crate::utils::ptr::get_spans;
use crate::utils::{ use crate::utils::{
get_trait_def_id, implements_trait, is_copy, is_self, is_type_diagnostic_item, match_type, multispan_sugg, paths, get_trait_def_id, implements_trait, is_copy, is_self, is_type_diagnostic_item, multispan_sugg, paths,
snippet, snippet_opt, span_lint_and_then, snippet, snippet_opt, span_lint_and_then,
}; };
use if_chain::if_chain; use if_chain::if_chain;
@ -254,7 +254,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
} }
} }
if match_type(cx, ty, &paths::STRING) { if is_type_diagnostic_item(cx, ty, sym!(string_type)) {
if let Some(clone_spans) = if let Some(clone_spans) =
get_spans(cx, Some(body.id()), idx, &[("clone", ".to_string()"), ("as_str", "")]) { get_spans(cx, Some(body.id()), idx, &[("clone", ".to_string()"), ("as_str", "")]) {
diag.span_suggestion( diag.span_suggestion(

View File

@ -197,7 +197,7 @@ fn check_fn(cx: &LateContext<'_, '_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_
}, },
); );
} }
} else if match_type(cx, ty, &paths::STRING) { } else if is_type_diagnostic_item(cx, ty, sym!(string_type)) {
if let Some(spans) = get_spans(cx, opt_body_id, idx, &[("clone", ".to_string()"), ("as_str", "")]) { if let Some(spans) = get_spans(cx, opt_body_id, idx, &[("clone", ".to_string()"), ("as_str", "")]) {
span_lint_and_then( span_lint_and_then(
cx, cx,

View File

@ -1,5 +1,5 @@
use crate::utils::{ use crate::utils::{
fn_has_unsatisfiable_preds, has_drop, is_copy, match_def_path, match_type, paths, snippet_opt, span_lint_hir, fn_has_unsatisfiable_preds, has_drop, is_copy, is_type_diagnostic_item, match_def_path, match_type, paths, snippet_opt, span_lint_hir,
span_lint_hir_and_then, walk_ptrs_ty_depth, span_lint_hir_and_then, walk_ptrs_ty_depth,
}; };
use if_chain::if_chain; use if_chain::if_chain;
@ -113,7 +113,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantClone {
let from_borrow = match_def_path(cx, fn_def_id, &paths::CLONE_TRAIT_METHOD) let from_borrow = match_def_path(cx, fn_def_id, &paths::CLONE_TRAIT_METHOD)
|| match_def_path(cx, fn_def_id, &paths::TO_OWNED_METHOD) || match_def_path(cx, fn_def_id, &paths::TO_OWNED_METHOD)
|| (match_def_path(cx, fn_def_id, &paths::TO_STRING_METHOD) && match_type(cx, arg_ty, &paths::STRING)); || (match_def_path(cx, fn_def_id, &paths::TO_STRING_METHOD) && is_type_diagnostic_item(cx, arg_ty, sym!(string_type)));
let from_deref = !from_borrow let from_deref = !from_borrow
&& (match_def_path(cx, fn_def_id, &paths::PATH_TO_PATH_BUF) && (match_def_path(cx, fn_def_id, &paths::PATH_TO_PATH_BUF)

View File

@ -8,7 +8,7 @@ use rustc_span::source_map::Spanned;
use if_chain::if_chain; use if_chain::if_chain;
use crate::utils::SpanlessEq; use crate::utils::SpanlessEq;
use crate::utils::{get_parent_expr, is_allowed, match_type, paths, span_lint, span_lint_and_sugg, walk_ptrs_ty}; use crate::utils::{get_parent_expr, is_allowed, is_type_diagnostic_item, span_lint, span_lint_and_sugg, walk_ptrs_ty};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for string appends of the form `x = x + y` (without /// **What it does:** Checks for string appends of the form `x = x + y` (without
@ -126,7 +126,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringAdd {
} }
fn is_string(cx: &LateContext<'_, '_>, e: &Expr<'_>) -> bool { fn is_string(cx: &LateContext<'_, '_>, e: &Expr<'_>) -> bool {
match_type(cx, walk_ptrs_ty(cx.tables.expr_ty(e)), &paths::STRING) is_type_diagnostic_item(cx, walk_ptrs_ty(cx.tables.expr_ty(e)), sym!(string_type))
} }
fn is_add(cx: &LateContext<'_, '_>, src: &Expr<'_>, target: &Expr<'_>) -> bool { fn is_add(cx: &LateContext<'_, '_>, src: &Expr<'_>, target: &Expr<'_>) -> bool {

View File

@ -1,6 +1,6 @@
use crate::utils::sugg::Sugg; use crate::utils::sugg::Sugg;
use crate::utils::{ use crate::utils::{
differing_macro_contexts, is_type_diagnostic_item, match_type, paths, snippet_with_applicability, differing_macro_contexts, is_type_diagnostic_item, snippet_with_applicability,
span_lint_and_then, walk_ptrs_ty, SpanlessEq, span_lint_and_then, walk_ptrs_ty, SpanlessEq,
}; };
use if_chain::if_chain; use if_chain::if_chain;
@ -199,7 +199,7 @@ fn check_for_slice<'a>(cx: &LateContext<'_, '_>, lhs1: &'a Expr<'_>, lhs2: &'a E
if matches!(ty.kind, ty::Slice(_)) if matches!(ty.kind, ty::Slice(_))
|| matches!(ty.kind, ty::Array(_, _)) || matches!(ty.kind, ty::Array(_, _))
|| is_type_diagnostic_item(cx, ty, sym!(vec_type)) || is_type_diagnostic_item(cx, ty, sym!(vec_type))
|| match_type(cx, ty, &paths::VEC_DEQUE) || is_type_diagnostic_item(cx, ty, sym!(vecdeque_type))
{ {
return Slice::Swappable(lhs1, idx1, idx2); return Slice::Swappable(lhs1, idx1, idx2);
} }

View File

@ -29,7 +29,7 @@ use rustc_typeck::hir_ty_to_ty;
use crate::consts::{constant, Constant}; use crate::consts::{constant, Constant};
use crate::utils::paths; use crate::utils::paths;
use crate::utils::{ use crate::utils::{
clip, comparisons, differing_macro_contexts, higher, in_constant, int_bits, last_path_segment, match_def_path, clip, comparisons, differing_macro_contexts, higher, in_constant, int_bits, is_type_diagnostic_item, last_path_segment, match_def_path,
match_path, method_chain_args, multispan_sugg, numeric_literal::NumericLiteral, qpath_res, same_tys, sext, snippet, match_path, method_chain_args, multispan_sugg, numeric_literal::NumericLiteral, qpath_res, same_tys, sext, snippet,
snippet_opt, snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help, snippet_opt, snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help,
span_lint_and_sugg, span_lint_and_then, unsext, span_lint_and_sugg, span_lint_and_then, unsext,
@ -2352,14 +2352,14 @@ impl<'tcx> ImplicitHasherType<'tcx> {
let ty = hir_ty_to_ty(cx.tcx, hir_ty); let ty = hir_ty_to_ty(cx.tcx, hir_ty);
if match_path(path, &paths::HASHMAP) && params_len == 2 { if is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) && params_len == 2 {
Some(ImplicitHasherType::HashMap( Some(ImplicitHasherType::HashMap(
hir_ty.span, hir_ty.span,
ty, ty,
snippet(cx, params[0].span, "K"), snippet(cx, params[0].span, "K"),
snippet(cx, params[1].span, "V"), snippet(cx, params[1].span, "V"),
)) ))
} else if match_path(path, &paths::HASHSET) && params_len == 1 { } else if is_type_diagnostic_item(cx, ty, sym!(hashset_type)) && params_len == 1 {
Some(ImplicitHasherType::HashSet( Some(ImplicitHasherType::HashSet(
hir_ty.span, hir_ty.span,
ty, ty,
@ -2460,13 +2460,14 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'a, 'b, 't
if_chain! { if_chain! {
if let ExprKind::Call(ref fun, ref args) = e.kind; if let ExprKind::Call(ref fun, ref args) = e.kind;
if let ExprKind::Path(QPath::TypeRelative(ref ty, ref method)) = fun.kind; if let ExprKind::Path(QPath::TypeRelative(ref ty, ref method)) = fun.kind;
if let TyKind::Path(QPath::Resolved(None, ref ty_path)) = ty.kind;
then { then {
if !same_tys(self.cx, self.target.ty(), self.body.expr_ty(e)) { if !same_tys(self.cx, self.target.ty(), self.body.expr_ty(e)) {
return; return;
} }
if match_path(ty_path, &paths::HASHMAP) { let ty = hir_ty_to_ty(self.cx.tcx, ty);
if is_type_diagnostic_item(self.cx, ty, sym!(hashmap_type)) {
if method.ident.name == sym!(new) { if method.ident.name == sym!(new) {
self.suggestions self.suggestions
.insert(e.span, "HashMap::default()".to_string()); .insert(e.span, "HashMap::default()".to_string());
@ -2479,7 +2480,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'a, 'b, 't
), ),
); );
} }
} else if match_path(ty_path, &paths::HASHSET) { } else if is_type_diagnostic_item(self.cx, ty, sym!(hashset_type)) {
if method.ident.name == sym!(new) { if method.ident.name == sym!(new) {
self.suggestions self.suggestions
.insert(e.span, "HashSet::default()".to_string()); .insert(e.span, "HashSet::default()".to_string());

View File

@ -61,7 +61,6 @@ pub const MEM_FORGET: [&str; 3] = ["core", "mem", "forget"];
pub const MEM_MAYBEUNINIT: [&str; 4] = ["core", "mem", "maybe_uninit", "MaybeUninit"]; pub const MEM_MAYBEUNINIT: [&str; 4] = ["core", "mem", "maybe_uninit", "MaybeUninit"];
pub const MEM_MAYBEUNINIT_UNINIT: [&str; 5] = ["core", "mem", "maybe_uninit", "MaybeUninit", "uninit"]; pub const MEM_MAYBEUNINIT_UNINIT: [&str; 5] = ["core", "mem", "maybe_uninit", "MaybeUninit", "uninit"];
pub const MEM_REPLACE: [&str; 3] = ["core", "mem", "replace"]; pub const MEM_REPLACE: [&str; 3] = ["core", "mem", "replace"];
pub const MUTEX: [&str; 4] = ["std", "sync", "mutex", "Mutex"];
pub const MUTEX_GUARD: [&str; 4] = ["std", "sync", "mutex", "MutexGuard"]; pub const MUTEX_GUARD: [&str; 4] = ["std", "sync", "mutex", "MutexGuard"];
pub const OPEN_OPTIONS: [&str; 3] = ["std", "fs", "OpenOptions"]; pub const OPEN_OPTIONS: [&str; 3] = ["std", "fs", "OpenOptions"];
pub const OPS_MODULE: [&str; 2] = ["core", "ops"]; pub const OPS_MODULE: [&str; 2] = ["core", "ops"];
@ -120,7 +119,6 @@ pub const STDOUT: [&str; 4] = ["std", "io", "stdio", "stdout"];
pub const STD_CONVERT_IDENTITY: [&str; 3] = ["std", "convert", "identity"]; pub const STD_CONVERT_IDENTITY: [&str; 3] = ["std", "convert", "identity"];
pub const STD_MEM_TRANSMUTE: [&str; 3] = ["std", "mem", "transmute"]; pub const STD_MEM_TRANSMUTE: [&str; 3] = ["std", "mem", "transmute"];
pub const STD_PTR_NULL: [&str; 3] = ["std", "ptr", "null"]; pub const STD_PTR_NULL: [&str; 3] = ["std", "ptr", "null"];
pub const STRING: [&str; 3] = ["alloc", "string", "String"];
pub const STRING_AS_MUT_STR: [&str; 4] = ["alloc", "string", "String", "as_mut_str"]; pub const STRING_AS_MUT_STR: [&str; 4] = ["alloc", "string", "String", "as_mut_str"];
pub const STRING_AS_STR: [&str; 4] = ["alloc", "string", "String", "as_str"]; pub const STRING_AS_STR: [&str; 4] = ["alloc", "string", "String", "as_str"];
pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"]; pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"];