Skip to content

Commit ed74c22

Browse files
committedJan 26, 2024
Auto merge of #12202 - y21:issue12199, r=Jarcho
Avoid linting redundant closure when callee is marked `#[track_caller]` Fixes #12199 Not sure if there's a nicer way to detect functions marked `#[track_caller]` other than by just looking at its attributes 🤔 changelog: [`redundant_closure`]: [`redundant_closure_for_method_calls`]: avoid linting closures where the function being called is marked `#[track_caller]`
2 parents 66c29b9 + fd3e966 commit ed74c22

File tree

4 files changed

+46
-4
lines changed

4 files changed

+46
-4
lines changed
 

Diff for: ‎clippy_lints/src/eta_reduction.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
2121
declare_clippy_lint! {
2222
/// ### What it does
2323
/// Checks for closures which just call another function where
24-
/// the function can be called directly. `unsafe` functions or calls where types
25-
/// get adjusted are ignored.
24+
/// the function can be called directly. `unsafe` functions, calls where types
25+
/// get adjusted or where the callee is marked `#[track_caller]` are ignored.
2626
///
2727
/// ### Why is this bad?
2828
/// Needlessly creating a closure adds code for no benefit
@@ -136,7 +136,14 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
136136
.map_or(callee_ty, |a| a.target.peel_refs());
137137

138138
let sig = match callee_ty_adjusted.kind() {
139-
ty::FnDef(def, _) => cx.tcx.fn_sig(def).skip_binder().skip_binder(),
139+
ty::FnDef(def, _) => {
140+
// Rewriting `x(|| f())` to `x(f)` where f is marked `#[track_caller]` moves the `Location`
141+
if cx.tcx.has_attr(*def, sym::track_caller) {
142+
return;
143+
}
144+
145+
cx.tcx.fn_sig(def).skip_binder().skip_binder()
146+
},
140147
ty::FnPtr(sig) => sig.skip_binder(),
141148
ty::Closure(_, subs) => cx
142149
.tcx
@@ -186,6 +193,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
186193
},
187194
ExprKind::MethodCall(path, self_, args, _) if check_inputs(typeck, body.params, Some(self_), args) => {
188195
if let Some(method_def_id) = typeck.type_dependent_def_id(body.value.hir_id)
196+
&& !cx.tcx.has_attr(method_def_id, sym::track_caller)
189197
&& check_sig(cx, closure, cx.tcx.fn_sig(method_def_id).skip_binder().skip_binder())
190198
{
191199
span_lint_and_then(

Diff for: ‎tests/ui/eta.fixed

+17
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,23 @@ fn angle_brackets_and_args() {
346346
dyn_opt.map(<dyn TestTrait>::method_on_dyn);
347347
}
348348

349+
// https://github.com/rust-lang/rust-clippy/issues/12199
350+
fn track_caller_fp() {
351+
struct S;
352+
impl S {
353+
#[track_caller]
354+
fn add_location(self) {}
355+
}
356+
357+
#[track_caller]
358+
fn add_location() {}
359+
360+
fn foo(_: fn()) {}
361+
fn foo2(_: fn(S)) {}
362+
foo(|| add_location());
363+
foo2(|s| s.add_location());
364+
}
365+
349366
fn _late_bound_to_early_bound_regions() {
350367
struct Foo<'a>(&'a u32);
351368
impl<'a> Foo<'a> {

Diff for: ‎tests/ui/eta.rs

+17
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,23 @@ fn angle_brackets_and_args() {
346346
dyn_opt.map(|d| d.method_on_dyn());
347347
}
348348

349+
// https://github.com/rust-lang/rust-clippy/issues/12199
350+
fn track_caller_fp() {
351+
struct S;
352+
impl S {
353+
#[track_caller]
354+
fn add_location(self) {}
355+
}
356+
357+
#[track_caller]
358+
fn add_location() {}
359+
360+
fn foo(_: fn()) {}
361+
fn foo2(_: fn(S)) {}
362+
foo(|| add_location());
363+
foo2(|s| s.add_location());
364+
}
365+
349366
fn _late_bound_to_early_bound_regions() {
350367
struct Foo<'a>(&'a u32);
351368
impl<'a> Foo<'a> {

Diff for: ‎tests/ui/eta.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ LL | dyn_opt.map(|d| d.method_on_dyn());
161161
| ^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<dyn TestTrait>::method_on_dyn`
162162

163163
error: redundant closure
164-
--> $DIR/eta.rs:389:19
164+
--> $DIR/eta.rs:406:19
165165
|
166166
LL | let _ = f(&0, |x, y| f2(x, y));
167167
| ^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `f2`

0 commit comments

Comments
 (0)