Skip to content

Commit 15226f9

Browse files
committed
Auto merge of rust-lang#10166 - sulami:master, r=giraffate
unused_self: Don't trigger if the method body contains todo!() If the author is using todo!(), presumably they intend to use self at some point later, so we don't have a good basis to recommend factoring out to an associated function. Fixes rust-lang#10117. --- changelog: Enhancement: [`unused_self`]: No longer lints, if the method body contains a `todo!()` call [rust-lang#10166](rust-lang/rust-clippy#10166) <!-- changelog_checked -->
2 parents 41b2a3d + e443604 commit 15226f9

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

clippy_lints/src/unused_self.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
use clippy_utils::diagnostics::span_lint_and_help;
2+
use clippy_utils::macros::root_macro_call_first_node;
23
use clippy_utils::visitors::is_local_used;
34
use if_chain::if_chain;
4-
use rustc_hir::{Impl, ImplItem, ImplItemKind, ItemKind};
5+
use rustc_hir::{Body, Impl, ImplItem, ImplItemKind, ItemKind};
56
use rustc_lint::{LateContext, LateLintPass};
67
use rustc_session::{declare_tool_lint, impl_lint_pass};
8+
use std::ops::ControlFlow;
79

810
declare_clippy_lint! {
911
/// ### What it does
@@ -57,6 +59,20 @@ impl<'tcx> LateLintPass<'tcx> for UnusedSelf {
5759
let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id;
5860
let parent_item = cx.tcx.hir().expect_item(parent);
5961
let assoc_item = cx.tcx.associated_item(impl_item.owner_id);
62+
let contains_todo = |cx, body: &'_ Body<'_>| -> bool {
63+
clippy_utils::visitors::for_each_expr(body.value, |e| {
64+
if let Some(macro_call) = root_macro_call_first_node(cx, e) {
65+
if cx.tcx.item_name(macro_call.def_id).as_str() == "todo" {
66+
ControlFlow::Break(())
67+
} else {
68+
ControlFlow::Continue(())
69+
}
70+
} else {
71+
ControlFlow::Continue(())
72+
}
73+
})
74+
.is_some()
75+
};
6076
if_chain! {
6177
if let ItemKind::Impl(Impl { of_trait: None, .. }) = parent_item.kind;
6278
if assoc_item.fn_has_self_parameter;
@@ -65,6 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedSelf {
6581
let body = cx.tcx.hir().body(*body_id);
6682
if let [self_param, ..] = body.params;
6783
if !is_local_used(cx, body, self_param.pat.hir_id);
84+
if !contains_todo(cx, body);
6885
then {
6986
span_lint_and_help(
7087
cx,

tests/ui/unused_self.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,16 @@ mod unused_self_allow {
6060
// shouldn't trigger for public methods
6161
pub fn unused_self_move(self) {}
6262
}
63+
64+
pub struct E;
65+
66+
impl E {
67+
// shouldn't trigger if body contains todo!()
68+
pub fn unused_self_todo(self) {
69+
let x = 42;
70+
todo!()
71+
}
72+
}
6373
}
6474

6575
pub use unused_self_allow::D;

0 commit comments

Comments
 (0)