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",