Skip to content

Commit 162aa19

Browse files
committed
Fix and improve internal lint checking for match_type usages
* Check for `const`s and `static`s from external crates * Check for `LangItem`s * Handle inherent functions which have the same name as a field * Also check the following functions: * `match_trait_method` * `match_def_path` * `is_expr_path_def_path` * `is_qpath_def_path` * Handle checking for a constructor to a diagnostic item or `LangItem`
1 parent 8e7af6b commit 162aa19

26 files changed

+534
-176
lines changed

clippy_lints/src/await_holding_invalid.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_hir::{def::Res, AsyncGeneratorKind, Body, BodyId, GeneratorKind};
66
use rustc_lint::{LateContext, LateLintPass};
77
use rustc_middle::ty::GeneratorInteriorTypeCause;
88
use rustc_session::{declare_tool_lint, impl_lint_pass};
9-
use rustc_span::Span;
9+
use rustc_span::{sym, Span};
1010

1111
use crate::utils::conf::DisallowedType;
1212

@@ -276,9 +276,9 @@ fn emit_invalid_type(cx: &LateContext<'_>, span: Span, disallowed: &DisallowedTy
276276
}
277277

278278
fn is_mutex_guard(cx: &LateContext<'_>, def_id: DefId) -> bool {
279-
match_def_path(cx, def_id, &paths::MUTEX_GUARD)
280-
|| match_def_path(cx, def_id, &paths::RWLOCK_READ_GUARD)
281-
|| match_def_path(cx, def_id, &paths::RWLOCK_WRITE_GUARD)
279+
cx.tcx.is_diagnostic_item(sym::MutexGuard, def_id)
280+
|| cx.tcx.is_diagnostic_item(sym::RwLockReadGuard, def_id)
281+
|| cx.tcx.is_diagnostic_item(sym::RwLockWriteGuard, def_id)
282282
|| match_def_path(cx, def_id, &paths::PARKING_LOT_MUTEX_GUARD)
283283
|| match_def_path(cx, def_id, &paths::PARKING_LOT_RWLOCK_READ_GUARD)
284284
|| match_def_path(cx, def_id, &paths::PARKING_LOT_RWLOCK_WRITE_GUARD)

clippy_lints/src/infinite_iter.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::span_lint;
2+
use clippy_utils::higher;
23
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
3-
use clippy_utils::{higher, match_def_path, path_def_id, paths};
44
use rustc_hir::{BorrowKind, Closure, Expr, ExprKind};
55
use rustc_lint::{LateContext, LateLintPass};
66
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -168,9 +168,16 @@ fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
168168
},
169169
ExprKind::Block(block, _) => block.expr.as_ref().map_or(Finite, |e| is_infinite(cx, e)),
170170
ExprKind::Box(e) | ExprKind::AddrOf(BorrowKind::Ref, _, e) => is_infinite(cx, e),
171-
ExprKind::Call(path, _) => path_def_id(cx, path)
172-
.map_or(false, |id| match_def_path(cx, id, &paths::ITER_REPEAT))
173-
.into(),
171+
ExprKind::Call(path, _) => {
172+
if let ExprKind::Path(ref qpath) = path.kind {
173+
cx.qpath_res(qpath, path.hir_id)
174+
.opt_def_id()
175+
.map_or(false, |id| cx.tcx.is_diagnostic_item(sym::iter_repeat, id))
176+
.into()
177+
} else {
178+
Finite
179+
}
180+
},
174181
ExprKind::Struct(..) => higher::Range::hir(expr).map_or(false, |r| r.end.is_none()).into(),
175182
_ => Finite,
176183
}

clippy_lints/src/inherent_to_string.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::span_lint_and_help;
22
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
3-
use clippy_utils::{get_trait_def_id, paths, return_ty, trait_ref_of_method};
3+
use clippy_utils::{return_ty, trait_ref_of_method};
44
use if_chain::if_chain;
55
use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind};
66
use rustc_lint::{LateContext, LateLintPass};
@@ -118,7 +118,10 @@ impl<'tcx> LateLintPass<'tcx> for InherentToString {
118118
}
119119

120120
fn show_lint(cx: &LateContext<'_>, item: &ImplItem<'_>) {
121-
let display_trait_id = get_trait_def_id(cx, &paths::DISPLAY_TRAIT).expect("Failed to get trait ID of `Display`!");
121+
let display_trait_id = cx
122+
.tcx
123+
.get_diagnostic_item(sym::Display)
124+
.expect("Failed to get trait ID of `Display`!");
122125

123126
// Get the real type of 'self'
124127
let self_type = cx.tcx.fn_sig(item.def_id).input(0);

clippy_lints/src/lib.register_internal.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ store.register_group(true, "clippy::internal", Some("clippy_internal"), vec![
1313
LintId::of(utils::internal_lints::INVALID_CLIPPY_VERSION_ATTRIBUTE),
1414
LintId::of(utils::internal_lints::INVALID_PATHS),
1515
LintId::of(utils::internal_lints::LINT_WITHOUT_LINT_PASS),
16-
LintId::of(utils::internal_lints::MATCH_TYPE_ON_DIAGNOSTIC_ITEM),
1716
LintId::of(utils::internal_lints::MISSING_CLIPPY_VERSION_ATTRIBUTE),
1817
LintId::of(utils::internal_lints::MISSING_MSRV_ATTR_IMPL),
1918
LintId::of(utils::internal_lints::OUTER_EXPN_EXPN_DATA),
2019
LintId::of(utils::internal_lints::PRODUCE_ICE),
20+
LintId::of(utils::internal_lints::UNNECESSARY_DEF_PATH),
2121
LintId::of(utils::internal_lints::UNNECESSARY_SYMBOL_STR),
2222
])

clippy_lints/src/lib.register_lints.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ store.register_lints(&[
2424
#[cfg(feature = "internal")]
2525
utils::internal_lints::LINT_WITHOUT_LINT_PASS,
2626
#[cfg(feature = "internal")]
27-
utils::internal_lints::MATCH_TYPE_ON_DIAGNOSTIC_ITEM,
28-
#[cfg(feature = "internal")]
2927
utils::internal_lints::MISSING_CLIPPY_VERSION_ATTRIBUTE,
3028
#[cfg(feature = "internal")]
3129
utils::internal_lints::MISSING_MSRV_ATTR_IMPL,
@@ -34,6 +32,8 @@ store.register_lints(&[
3432
#[cfg(feature = "internal")]
3533
utils::internal_lints::PRODUCE_ICE,
3634
#[cfg(feature = "internal")]
35+
utils::internal_lints::UNNECESSARY_DEF_PATH,
36+
#[cfg(feature = "internal")]
3737
utils::internal_lints::UNNECESSARY_SYMBOL_STR,
3838
almost_complete_letter_range::ALMOST_COMPLETE_LETTER_RANGE,
3939
approx_const::APPROX_CONSTANT,

clippy_lints/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
535535
store.register_late_pass(|_| Box::new(utils::internal_lints::InvalidPaths));
536536
store.register_late_pass(|_| Box::<utils::internal_lints::InterningDefinedSymbol>::default());
537537
store.register_late_pass(|_| Box::<utils::internal_lints::LintWithoutLintPass>::default());
538-
store.register_late_pass(|_| Box::new(utils::internal_lints::MatchTypeOnDiagItem));
538+
store.register_late_pass(|_| Box::new(utils::internal_lints::UnnecessaryDefPath));
539539
store.register_late_pass(|_| Box::new(utils::internal_lints::OuterExpnDataPass));
540540
store.register_late_pass(|_| Box::new(utils::internal_lints::MsrvAttrImpl));
541541
}

clippy_lints/src/manual_retain.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ fn check_into_iter(
9292
&& match_def_path(cx, filter_def_id, &paths::CORE_ITER_FILTER)
9393
&& let hir::ExprKind::MethodCall(_, struct_expr, [], _) = &into_iter_expr.kind
9494
&& let Some(into_iter_def_id) = cx.typeck_results().type_dependent_def_id(into_iter_expr.hir_id)
95-
&& match_def_path(cx, into_iter_def_id, &paths::CORE_ITER_INTO_ITER)
95+
&& cx.tcx.lang_items().require(hir::LangItem::IntoIterIntoIter).ok() == Some(into_iter_def_id)
9696
&& match_acceptable_type(cx, left_expr, msrv)
9797
&& SpanlessEq::new(cx).eq_expr(left_expr, struct_expr) {
9898
suggest(cx, parent_expr, left_expr, target_expr);

clippy_lints/src/methods/filetype_is_file.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
use clippy_utils::diagnostics::span_lint_and_help;
2-
use clippy_utils::ty::match_type;
3-
use clippy_utils::{get_parent_expr, paths};
2+
use clippy_utils::get_parent_expr;
3+
use clippy_utils::ty::is_type_diagnostic_item;
44
use if_chain::if_chain;
55
use rustc_hir as hir;
66
use rustc_lint::LateContext;
77
use rustc_span::source_map::Span;
8+
use rustc_span::sym;
89

910
use super::FILETYPE_IS_FILE;
1011

1112
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) {
1213
let ty = cx.typeck_results().expr_ty(recv);
1314

14-
if !match_type(cx, ty, &paths::FILE_TYPE) {
15+
if !is_type_diagnostic_item(cx, ty, sym::FileType) {
1516
return;
1617
}
1718

clippy_lints/src/methods/inefficient_to_string.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ fn specializes_tostring(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
6565
}
6666

6767
if let ty::Adt(adt, substs) = ty.kind() {
68-
match_def_path(cx, adt.did(), &paths::COW) && substs.type_at(1).is_str()
68+
cx.tcx.is_diagnostic_item(sym::Cow, adt.did()) && substs.type_at(1).is_str()
6969
} else {
7070
false
7171
}

clippy_lints/src/methods/manual_str_repeat.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
2+
use clippy_utils::is_path_diagnostic_item;
23
use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
34
use clippy_utils::sugg::Sugg;
4-
use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item, match_type};
5-
use clippy_utils::{is_expr_path_def_path, paths};
5+
use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
66
use if_chain::if_chain;
77
use rustc_ast::LitKind;
88
use rustc_errors::Applicability;
@@ -38,7 +38,7 @@ fn parse_repeat_arg(cx: &LateContext<'_>, e: &Expr<'_>) -> Option<RepeatKind> {
3838
let ty = cx.typeck_results().expr_ty(e);
3939
if is_type_diagnostic_item(cx, ty, sym::String)
4040
|| (is_type_lang_item(cx, ty, LangItem::OwnedBox) && get_ty_param(ty).map_or(false, Ty::is_str))
41-
|| (match_type(cx, ty, &paths::COW) && get_ty_param(ty).map_or(false, Ty::is_str))
41+
|| (is_type_diagnostic_item(cx, ty, sym::Cow) && get_ty_param(ty).map_or(false, Ty::is_str))
4242
{
4343
Some(RepeatKind::String)
4444
} else {
@@ -57,7 +57,7 @@ pub(super) fn check(
5757
) {
5858
if_chain! {
5959
if let ExprKind::Call(repeat_fn, [repeat_arg]) = take_self_arg.kind;
60-
if is_expr_path_def_path(cx, repeat_fn, &paths::ITER_REPEAT);
60+
if is_path_diagnostic_item(cx, repeat_fn, sym::iter_repeat);
6161
if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(collect_expr), sym::String);
6262
if let Some(collect_id) = cx.typeck_results().type_dependent_def_id(collect_expr.hir_id);
6363
if let Some(take_id) = cx.typeck_results().type_dependent_def_id(take_expr.hir_id);

clippy_lints/src/methods/useless_asref.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
22
use clippy_utils::source::snippet_with_applicability;
33
use clippy_utils::ty::walk_ptrs_ty_depth;
4-
use clippy_utils::{get_parent_expr, match_trait_method, paths};
4+
use clippy_utils::{get_parent_expr, is_trait_method};
55
use if_chain::if_chain;
66
use rustc_errors::Applicability;
77
use rustc_hir as hir;
88
use rustc_lint::LateContext;
9+
use rustc_span::sym;
910

1011
use super::USELESS_ASREF;
1112

1213
/// Checks for the `USELESS_ASREF` lint.
1314
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str, recvr: &hir::Expr<'_>) {
1415
// when we get here, we've already checked that the call name is "as_ref" or "as_mut"
1516
// check if the call is to the actual `AsRef` or `AsMut` trait
16-
if match_trait_method(cx, expr, &paths::ASREF_TRAIT) || match_trait_method(cx, expr, &paths::ASMUT_TRAIT) {
17+
if is_trait_method(cx, expr, sym::AsRef) || is_trait_method(cx, expr, sym::AsMut) {
1718
// check if the type after `as_ref` or `as_mut` is the same as before
1819
let rcv_ty = cx.typeck_results().expr_ty(recvr);
1920
let res_ty = cx.typeck_results().expr_ty(expr);

clippy_lints/src/minmax.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::consts::{constant_simple, Constant};
22
use clippy_utils::diagnostics::span_lint;
3-
use clippy_utils::{match_trait_method, paths};
3+
use clippy_utils::is_trait_method;
44
use rustc_hir::{Expr, ExprKind};
55
use rustc_lint::{LateContext, LateLintPass};
66
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -83,7 +83,7 @@ fn min_max<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<(MinMax, Cons
8383
}
8484
},
8585
ExprKind::MethodCall(path, receiver, args @ [_], _) => {
86-
if cx.typeck_results().expr_ty(receiver).is_floating_point() || match_trait_method(cx, expr, &paths::ORD) {
86+
if cx.typeck_results().expr_ty(receiver).is_floating_point() || is_trait_method(cx, expr, sym::Ord) {
8787
if path.ident.name == sym!(max) {
8888
fetch_const(cx, Some(receiver), args, MinMax::Max)
8989
} else if path.ident.name == sym!(min) {

clippy_lints/src/non_octal_unix_permissions.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
22
use clippy_utils::source::{snippet_opt, snippet_with_applicability};
3-
use clippy_utils::ty::match_type;
3+
use clippy_utils::ty::{is_type_diagnostic_item, match_type};
44
use clippy_utils::{match_def_path, paths};
55
use if_chain::if_chain;
66
use rustc_errors::Applicability;
77
use rustc_hir::{Expr, ExprKind};
88
use rustc_lint::{LateContext, LateLintPass};
99
use rustc_session::{declare_lint_pass, declare_tool_lint};
10+
use rustc_span::sym;
1011

1112
declare_clippy_lint! {
1213
/// ### What it does
@@ -49,7 +50,7 @@ impl<'tcx> LateLintPass<'tcx> for NonOctalUnixPermissions {
4950
if_chain! {
5051
if (path.ident.name == sym!(mode)
5152
&& (match_type(cx, obj_ty, &paths::OPEN_OPTIONS)
52-
|| match_type(cx, obj_ty, &paths::DIR_BUILDER)))
53+
|| is_type_diagnostic_item(cx, obj_ty, sym::DirBuilder)))
5354
|| (path.ident.name == sym!(set_mode) && match_type(cx, obj_ty, &paths::PERMISSIONS));
5455
if let ExprKind::Lit(_) = param.kind;
5556

clippy_lints/src/slow_vector_initialization.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
22
use clippy_utils::sugg::Sugg;
33
use clippy_utils::ty::is_type_diagnostic_item;
44
use clippy_utils::{
5-
get_enclosing_block, is_expr_path_def_path, is_integer_literal, path_to_local, path_to_local_id, paths, SpanlessEq,
5+
get_enclosing_block, is_integer_literal, is_path_diagnostic_item, path_to_local, path_to_local_id, SpanlessEq,
66
};
77
use if_chain::if_chain;
88
use rustc_errors::Applicability;
@@ -254,7 +254,7 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
254254
fn is_repeat_zero(&self, expr: &Expr<'_>) -> bool {
255255
if_chain! {
256256
if let ExprKind::Call(fn_expr, [repeat_arg]) = expr.kind;
257-
if is_expr_path_def_path(self.cx, fn_expr, &paths::ITER_REPEAT);
257+
if is_path_diagnostic_item(self.cx, fn_expr, sym::iter_repeat);
258258
if is_integer_literal(repeat_arg, 0);
259259
then {
260260
true

clippy_lints/src/unnecessary_owned_empty_strings.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use clippy_utils::{match_def_path, paths};
33
use if_chain::if_chain;
44
use rustc_ast::ast::LitKind;
55
use rustc_errors::Applicability;
6-
use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability};
6+
use rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability};
77
use rustc_lint::{LateContext, LateLintPass};
88
use rustc_middle::ty;
99
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -55,7 +55,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryOwnedEmptyStrings {
5555
);
5656
} else {
5757
if_chain! {
58-
if match_def_path(cx, fun_def_id, &paths::FROM_FROM);
58+
if cx.tcx.lang_items().require(LangItem::FromFrom).ok() == Some(fun_def_id);
5959
if let [.., last_arg] = args;
6060
if let ExprKind::Lit(spanned) = &last_arg.kind;
6161
if let LitKind::Str(symbol, _) = spanned.node;

clippy_lints/src/unused_io_amount.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
2-
use clippy_utils::{is_try, match_trait_method, paths};
2+
use clippy_utils::{is_trait_method, is_try, match_trait_method, paths};
33
use rustc_hir as hir;
44
use rustc_lint::{LateContext, LateLintPass};
55
use rustc_session::{declare_lint_pass, declare_tool_lint};
6+
use rustc_span::sym;
67

78
declare_clippy_lint! {
89
/// ### What it does
@@ -116,13 +117,13 @@ fn check_method_call(cx: &LateContext<'_>, call: &hir::Expr<'_>, expr: &hir::Exp
116117
match_trait_method(cx, call, &paths::FUTURES_IO_ASYNCREADEXT)
117118
|| match_trait_method(cx, call, &paths::TOKIO_IO_ASYNCREADEXT)
118119
} else {
119-
match_trait_method(cx, call, &paths::IO_READ)
120+
is_trait_method(cx, call, sym::IoRead)
120121
};
121122
let write_trait = if is_await {
122123
match_trait_method(cx, call, &paths::FUTURES_IO_ASYNCWRITEEXT)
123124
|| match_trait_method(cx, call, &paths::TOKIO_IO_ASYNCWRITEEXT)
124125
} else {
125-
match_trait_method(cx, call, &paths::IO_WRITE)
126+
is_trait_method(cx, call, sym::IoWrite)
126127
};
127128

128129
match (read_trait, write_trait, symbol, is_await) {

clippy_lints/src/useless_conversion.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use clippy_utils::ty::{is_type_diagnostic_item, same_type_and_consts};
55
use clippy_utils::{get_parent_expr, is_trait_method, match_def_path, paths};
66
use if_chain::if_chain;
77
use rustc_errors::Applicability;
8-
use rustc_hir::{Expr, ExprKind, HirId, MatchSource};
8+
use rustc_hir::{Expr, ExprKind, HirId, LangItem, MatchSource};
99
use rustc_lint::{LateContext, LateLintPass};
1010
use rustc_middle::ty;
1111
use rustc_session::{declare_tool_lint, impl_lint_pass};
@@ -154,7 +154,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
154154
}
155155

156156
if_chain! {
157-
if match_def_path(cx, def_id, &paths::FROM_FROM);
157+
if cx.tcx.lang_items().require(LangItem::FromFrom).ok() == Some(def_id);
158158
if same_type_and_consts(a, b);
159159

160160
then {

0 commit comments

Comments
 (0)