Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use more diagnostic items #5509

Merged
merged 3 commits into from Apr 26, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -1,5 +1,5 @@
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 if_chain::if_chain;
use rustc_errors::Applicability;
@@ -114,7 +114,7 @@ fn check_cond<'a, 'tcx, 'b>(
return if match_type(cx, obj_ty, &paths::BTREEMAP) {
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))
}
else {
@@ -1,7 +1,7 @@
use crate::utils::paths;
use crate::utils::{
is_expn_of, last_path_segment, match_def_path, match_function_call, match_type, snippet, span_lint_and_then,
walk_ptrs_ty,
is_expn_of, is_type_diagnostic_item, last_path_segment, match_def_path, match_function_call, snippet,
span_lint_and_then, walk_ptrs_ty,
};
use if_chain::if_chain;
use rustc_ast::ast::LitKind;
@@ -91,7 +91,7 @@ fn on_argumentv1_new<'a, 'tcx>(
if pats.len() == 1;
then {
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;
}
if let ExprKind::Lit(ref lit) = format_args.kind {
@@ -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 rustc_hir::intravisit::{self as visit, NestedVisitorMap, Visitor};
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 path.ident.to_string() == "lock";
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 {
Some(&args[0])
} else {
@@ -4,8 +4,8 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};

use crate::utils::{
get_trait_def_id, implements_trait, match_type, paths, return_ty, span_lint_and_help, trait_ref_of_method,
walk_ptrs_ty,
get_trait_def_id, implements_trait, is_type_diagnostic_item, paths, return_ty, span_lint_and_help,
trait_ref_of_method, walk_ptrs_ty,
};

declare_clippy_lint! {
@@ -107,7 +107,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InherentToString {
if decl.inputs.len() == 1;

// 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
if trait_ref_of_method(cx, impl_item.hir_id).is_none();
@@ -816,7 +816,7 @@ fn is_slice_like<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'_>) -> bool {
_ => 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> {
@@ -1569,7 +1569,7 @@ fn check_for_loop_over_map_kv<'a, 'tcx>(
_ => 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(
cx,
FOR_KV_MAP,
@@ -1971,9 +1971,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) ||
match_type(cx, ty, &paths::HASHMAP) ||
match_type(cx, ty, &paths::HASHSET) ||
match_type(cx, ty, &paths::VEC_DEQUE) ||
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)
@@ -2480,9 +2480,9 @@ fn check_needless_collect<'a, 'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'a, '
then {
let ty = cx.tables.node_type(ty.hir_id);
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::HASHMAP) {
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(
@@ -1,5 +1,7 @@
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::{
is_type_diagnostic_item, match_def_path, paths, snippet_with_applicability, span_lint_and_then, walk_ptrs_ty_depth,
};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir as hir;
@@ -44,12 +46,17 @@ pub fn lint<'tcx>(cx: &LateContext<'_, 'tcx>, expr: &hir::Expr<'_>, arg: &hir::E
/// Returns whether `ty` specializes `ToString`.
/// Currently, these are `str`, `String`, and `Cow<'_, str>`.
fn specializes_tostring(cx: &LateContext<'_, '_>, ty: Ty<'_>) -> bool {
match ty.kind {
ty::Str => 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())
},
_ => false,
if let ty::Str = ty.kind {
return true;
}

if is_type_diagnostic_item(cx, ty, sym!(string_type)) {
return true;
}

if let ty::Adt(adt, substs) = ty.kind {
match_def_path(cx, adt.did, &paths::COW) && substs.type_at(1).is_str()
} else {
false
}
}
@@ -1756,7 +1756,7 @@ fn lint_expect_fun_call(
&& {
let arg_type = cx.tables.expr_ty(&call_args[0]);
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]
@@ -1774,7 +1774,7 @@ fn lint_expect_fun_call(
// converted to string.
fn requires_to_string(cx: &LateContext<'_, '_>, arg: &hir::Expr<'_>) -> bool {
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;
}
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 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 {
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<'_>]) {
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);
}
}
@@ -2242,7 +2242,7 @@ fn lint_iter_nth<'a, 'tcx>(
"slice"
} else if is_type_diagnostic_item(cx, cx.tables.expr_ty(&iter_args[0]), sym!(vec_type)) {
"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"
} else {
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)) {
needs_ref = get_args_str.parse::<usize>().is_ok();
"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();
"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;
"HashMap"
} 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
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`. \
This is more succinctly expressed by calling `.and_then(..)`";
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";

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;
}

@@ -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 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;
}

@@ -2,7 +2,7 @@
//!
//! 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_hir::Expr;
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<'_>) {
let ty = cx.tables.expr_ty(expr);
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);
if let Some(atomic_name) = get_atomic_name(mutex_param) {
let msg = format!(
@@ -1,7 +1,7 @@
use crate::utils::ptr::get_spans;
use crate::utils::{
get_trait_def_id, implements_trait, is_copy, is_self, is_type_diagnostic_item, match_type, multispan_sugg, paths,
snippet, snippet_opt, span_lint_and_then,
get_trait_def_id, implements_trait, is_copy, is_self, is_type_diagnostic_item, multispan_sugg, paths, snippet,
snippet_opt, span_lint_and_then,
};
use if_chain::if_chain;
use rustc_ast::ast::Attribute;
@@ -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) =
get_spans(cx, Some(body.id()), idx, &[("clone", ".to_string()"), ("as_str", "")]) {
diag.span_suggestion(
@@ -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", "")]) {
span_lint_and_then(
cx,
@@ -1,6 +1,6 @@
use crate::utils::{
fn_has_unsatisfiable_preds, has_drop, is_copy, match_def_path, match_type, paths, snippet_opt, span_lint_hir,
span_lint_hir_and_then, walk_ptrs_ty_depth,
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,
};
use if_chain::if_chain;
use rustc_data_structures::{fx::FxHashMap, transitive_relation::TransitiveRelation};
@@ -113,7 +113,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantClone {

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_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
&& (match_def_path(cx, fn_def_id, &paths::PATH_TO_PATH_BUF)
@@ -8,7 +8,7 @@ use rustc_span::source_map::Spanned;
use if_chain::if_chain;

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! {
/// **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 {
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 {
@@ -1,7 +1,7 @@
use crate::utils::sugg::Sugg;
use crate::utils::{
differing_macro_contexts, is_type_diagnostic_item, match_type, paths, snippet_with_applicability,
span_lint_and_then, walk_ptrs_ty, SpanlessEq,
differing_macro_contexts, is_type_diagnostic_item, snippet_with_applicability, span_lint_and_then, walk_ptrs_ty,
SpanlessEq,
};
use if_chain::if_chain;
use rustc_errors::Applicability;
@@ -199,7 +199,7 @@ fn check_for_slice<'a>(cx: &LateContext<'_, '_>, lhs1: &'a Expr<'_>, lhs2: &'a E
if matches!(ty.kind, ty::Slice(_))
|| matches!(ty.kind, ty::Array(_, _))
|| 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);
}
@@ -29,10 +29,10 @@ use rustc_typeck::hir_ty_to_ty;
use crate::consts::{constant, Constant};
use crate::utils::paths;
use crate::utils::{
clip, comparisons, differing_macro_contexts, higher, in_constant, int_bits, last_path_segment, match_def_path,
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,
span_lint_and_sugg, span_lint_and_then, unsext,
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, snippet_opt, snippet_with_applicability, snippet_with_macro_callsite,
span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, unsext,
};

declare_clippy_lint! {
@@ -2352,14 +2352,14 @@ impl<'tcx> ImplicitHasherType<'tcx> {

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(
hir_ty.span,
ty,
snippet(cx, params[0].span, "K"),
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(
hir_ty.span,
ty,
@@ -2460,7 +2460,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'a, 'b, 't
if_chain! {
if let ExprKind::Call(ref fun, ref args) = e.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;
if let TyKind::Path(QPath::Resolved(None, ty_path)) = ty.kind;
then {
if !same_tys(self.cx, self.target.ty(), self.body.expr_ty(e)) {
return;
@@ -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_UNINIT: [&str; 5] = ["core", "mem", "maybe_uninit", "MaybeUninit", "uninit"];
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 OPEN_OPTIONS: [&str; 3] = ["std", "fs", "OpenOptions"];
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_MEM_TRANSMUTE: [&str; 3] = ["std", "mem", "transmute"];
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_STR: [&str; 4] = ["alloc", "string", "String", "as_str"];
pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"];