Skip to content

Commit 8ac9916

Browse files
authored
Merge pull request #1152 from oli-obk/wrong_self_conv_fn_level
enable changing wrong_self_convention's lint level at the function level
2 parents 4b8f6a0 + 49f276e commit 8ac9916

File tree

2 files changed

+55
-54
lines changed

2 files changed

+55
-54
lines changed

clippy_lints/src/methods.rs

Lines changed: 52 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -538,68 +538,66 @@ impl LateLintPass for Pass {
538538
}
539539
}
540540

541-
fn check_item(&mut self, cx: &LateContext, item: &hir::Item) {
542-
if in_external_macro(cx, item.span) {
541+
fn check_impl_item(&mut self, cx: &LateContext, implitem: &hir::ImplItem) {
542+
if in_external_macro(cx, implitem.span) {
543543
return;
544544
}
545+
let name = implitem.name;
546+
let parent = cx.tcx.map.get_parent(implitem.id);
547+
let item = cx.tcx.map.expect_item(parent);
548+
if_let_chain! {[
549+
let hir::ImplItemKind::Method(ref sig, _) = implitem.node,
550+
let Some(explicit_self) = sig.decl.inputs.get(0).and_then(hir::Arg::to_self),
551+
let hir::ItemImpl(_, _, _, None, _, _) = item.node,
552+
], {
553+
// check missing trait implementations
554+
for &(method_name, n_args, self_kind, out_type, trait_name) in &TRAIT_METHODS {
555+
if name.as_str() == method_name &&
556+
sig.decl.inputs.len() == n_args &&
557+
out_type.matches(&sig.decl.output) &&
558+
self_kind.matches(&explicit_self, false) {
559+
span_lint(cx, SHOULD_IMPLEMENT_TRAIT, implitem.span, &format!(
560+
"defining a method called `{}` on this type; consider implementing \
561+
the `{}` trait or choosing a less ambiguous name", name, trait_name));
562+
}
563+
}
545564

546-
if let hir::ItemImpl(_, _, _, None, _, ref items) = item.node {
547-
for implitem in items {
548-
let name = implitem.name;
565+
// check conventions w.r.t. conversion method names and predicates
566+
let ty = cx.tcx.lookup_item_type(cx.tcx.map.local_def_id(item.id)).ty;
567+
let is_copy = is_copy(cx, ty, item.id);
568+
for &(ref conv, self_kinds) in &CONVENTIONS {
549569
if_let_chain! {[
550-
let hir::ImplItemKind::Method(ref sig, _) = implitem.node,
570+
conv.check(&name.as_str()),
551571
let Some(explicit_self) = sig.decl.inputs.get(0).and_then(hir::Arg::to_self),
572+
!self_kinds.iter().any(|k| k.matches(&explicit_self, is_copy)),
552573
], {
553-
// check missing trait implementations
554-
for &(method_name, n_args, self_kind, out_type, trait_name) in &TRAIT_METHODS {
555-
if name.as_str() == method_name &&
556-
sig.decl.inputs.len() == n_args &&
557-
out_type.matches(&sig.decl.output) &&
558-
self_kind.matches(&explicit_self, false) {
559-
span_lint(cx, SHOULD_IMPLEMENT_TRAIT, implitem.span, &format!(
560-
"defining a method called `{}` on this type; consider implementing \
561-
the `{}` trait or choosing a less ambiguous name", name, trait_name));
562-
}
563-
}
564-
565-
// check conventions w.r.t. conversion method names and predicates
566-
let ty = cx.tcx.lookup_item_type(cx.tcx.map.local_def_id(item.id)).ty;
567-
let is_copy = is_copy(cx, ty, item.id);
568-
for &(ref conv, self_kinds) in &CONVENTIONS {
569-
if_let_chain! {[
570-
conv.check(&name.as_str()),
571-
let Some(explicit_self) = sig.decl.inputs.get(0).and_then(hir::Arg::to_self),
572-
!self_kinds.iter().any(|k| k.matches(&explicit_self, is_copy)),
573-
], {
574-
let lint = if item.vis == hir::Visibility::Public {
575-
WRONG_PUB_SELF_CONVENTION
576-
} else {
577-
WRONG_SELF_CONVENTION
578-
};
579-
span_lint(cx,
580-
lint,
581-
explicit_self.span,
582-
&format!("methods called `{}` usually take {}; consider choosing a less \
583-
ambiguous name",
584-
conv,
585-
&self_kinds.iter()
586-
.map(|k| k.description())
587-
.collect::<Vec<_>>()
588-
.join(" or ")));
589-
}}
590-
}
591-
592-
let ret_ty = return_ty(cx, implitem.id);
593-
if &name.as_str() == &"new" &&
594-
!ret_ty.map_or(false, |ret_ty| ret_ty.walk().any(|t| same_tys(cx, t, ty, implitem.id))) {
595-
span_lint(cx,
596-
NEW_RET_NO_SELF,
597-
explicit_self.span,
598-
"methods called `new` usually return `Self`");
599-
}
574+
let lint = if item.vis == hir::Visibility::Public {
575+
WRONG_PUB_SELF_CONVENTION
576+
} else {
577+
WRONG_SELF_CONVENTION
578+
};
579+
span_lint(cx,
580+
lint,
581+
explicit_self.span,
582+
&format!("methods called `{}` usually take {}; consider choosing a less \
583+
ambiguous name",
584+
conv,
585+
&self_kinds.iter()
586+
.map(|k| k.description())
587+
.collect::<Vec<_>>()
588+
.join(" or ")));
600589
}}
601590
}
602-
}
591+
592+
let ret_ty = return_ty(cx, implitem.id);
593+
if &name.as_str() == &"new" &&
594+
!ret_ty.map_or(false, |ret_ty| ret_ty.walk().any(|t| same_tys(cx, t, ty, implitem.id))) {
595+
span_lint(cx,
596+
NEW_RET_NO_SELF,
597+
explicit_self.span,
598+
"methods called `new` usually return `Self`");
599+
}
600+
}}
603601
}
604602
}
605603

tests/compile-fail/wrong_self_convention.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ impl Foo {
2323
pub fn is_i64(self) {}
2424
pub fn to_i64(self) {}
2525
pub fn from_i64(self) {} //~ERROR: methods called `from_*` usually take no self
26+
// check whether the lint can be allowed at the function level
27+
#[allow(wrong_self_convention)]
28+
pub fn from_cake(self) {}
2629

2730
}
2831

0 commit comments

Comments
 (0)