1 use clippy_utils
::diagnostics
::span_lint_and_help
;
2 use clippy_utils
::is_lint_allowed
;
3 use clippy_utils
::macros
::span_is_local
;
4 use rustc_hir
::def_id
::DefIdMap
;
5 use rustc_hir
::{Impl, Item, ItemKind}
;
6 use rustc_lint
::{LateContext, LateLintPass}
;
7 use rustc_middle
::ty
::AssocItem
;
8 use rustc_session
::{declare_lint_pass, declare_tool_lint}
;
10 declare_clippy_lint
! {
12 /// Checks if a provided method is used implicitly by a trait
13 /// implementation. A usage example would be a wrapper where every method
14 /// should perform some operation before delegating to the inner type's
17 /// This lint should typically be enabled on a specific trait `impl` item
18 /// rather than globally.
20 /// ### Why is this bad?
21 /// Indicates that a method is missing.
32 /// #[warn(clippy::missing_trait_methods)]
33 /// impl Trait for Type {
34 /// fn required() { /* ... */ }
46 /// #[warn(clippy::missing_trait_methods)]
47 /// impl Trait for Type {
48 /// fn required() { /* ... */ }
50 /// fn provided() { /* ... */ }
53 #[clippy::version = "1.66.0"]
54 pub MISSING_TRAIT_METHODS
,
56 "trait implementation uses default provided method"
58 declare_lint_pass
!(MissingTraitMethods
=> [MISSING_TRAIT_METHODS
]);
60 impl<'tcx
> LateLintPass
<'tcx
> for MissingTraitMethods
{
61 fn check_item(&mut self, cx
: &LateContext
<'tcx
>, item
: &'tcx Item
<'tcx
>) {
62 if !is_lint_allowed(cx
, MISSING_TRAIT_METHODS
, item
.hir_id())
63 && span_is_local(item
.span
)
64 && let ItemKind
::Impl(Impl
{
66 of_trait
: Some(trait_ref
),
69 && let Some(trait_id
) = trait_ref
.trait_def_id()
71 let mut provided
: DefIdMap
<&AssocItem
> = cx
73 .provided_trait_methods(trait_id
)
74 .map(|assoc
| (assoc
.def_id
, assoc
))
77 for impl_item
in *items
{
78 if let Some(def_id
) = impl_item
.trait_item_def_id
{
79 provided
.remove(&def_id
);
83 for assoc
in provided
.values() {
84 let source_map
= cx
.tcx
.sess
.source_map();
85 let definition_span
= source_map
.guess_head_span(cx
.tcx
.def_span(assoc
.def_id
));
89 MISSING_TRAIT_METHODS
,
90 source_map
.guess_head_span(item
.span
),
91 &format
!("missing trait method provided by default: `{}`", assoc
.name
),
92 Some(definition_span
),
93 "implement the method",