1 use clippy_utils
::diagnostics
::span_lint
;
2 use clippy_utils
::return_ty
;
3 use clippy_utils
::ty
::{contains_adt_constructor, contains_ty}
;
4 use rustc_hir
::{Impl, ImplItem, ImplItemKind, ItemKind, Node}
;
5 use rustc_lint
::{LateContext, LateLintPass}
;
6 use rustc_session
::{declare_lint_pass, declare_tool_lint}
;
10 /// Warns when constructors have the same name as their types.
12 /// ### Why is this bad?
13 /// Repeating the name of the type is redundant.
20 /// pub fn foo() -> Foo {
30 /// pub fn new() -> Foo {
35 #[clippy::version = "1.55.0"]
36 pub SELF_NAMED_CONSTRUCTORS
,
38 "method should not have the same name as the type it is implemented for"
41 declare_lint_pass
!(SelfNamedConstructors
=> [SELF_NAMED_CONSTRUCTORS
]);
43 impl<'tcx
> LateLintPass
<'tcx
> for SelfNamedConstructors
{
44 fn check_impl_item(&mut self, cx
: &LateContext
<'tcx
>, impl_item
: &'tcx ImplItem
<'_
>) {
45 match impl_item
.kind
{
46 ImplItemKind
::Fn(ref sig
, _
) => {
47 if sig
.decl
.implicit_self
.has_implicit_self() {
54 let parent
= cx
.tcx
.hir().get_parent_item(impl_item
.hir_id());
55 let item
= cx
.tcx
.hir().expect_item(parent
);
56 let self_ty
= cx
.tcx
.type_of(item
.def_id
);
57 let ret_ty
= return_ty(cx
, impl_item
.hir_id());
59 // Do not check trait impls
60 if matches
!(item
.kind
, ItemKind
::Impl(Impl { of_trait: Some(_), .. }
)) {
64 // Ensure method is constructor-like
65 if let Some(self_adt
) = self_ty
.ty_adt_def() {
66 if !contains_adt_constructor(ret_ty
, self_adt
) {
69 } else if !contains_ty(ret_ty
, self_ty
) {
74 if let Some(self_def
) = self_ty
.ty_adt_def();
75 if let Some(self_local_did
) = self_def
.did().as_local();
76 let self_id
= cx
.tcx
.hir().local_def_id_to_hir_id(self_local_did
);
77 if let Some(Node
::Item(x
)) = cx
.tcx
.hir().find(self_id
);
78 let type_name
= x
.ident
.name
.as_str().to_lowercase();
79 if impl_item
.ident
.name
.as_str() == type_name
|| impl_item
.ident
.name
.as_str().replace('_'
, "") == type_name
;
84 SELF_NAMED_CONSTRUCTORS
,
86 &format
!("constructor `{}` has the same name as the type", impl_item
.ident
.name
),