diff options
| author | bors <bors@rust-lang.org> | 2024-01-26 05:38:39 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-01-26 05:38:39 +0000 |
| commit | ed74c22f33da446eb91d2069b3fdc8e3d93bff16 (patch) | |
| tree | 30d10af9c09b0adc285fb6214babfb3063d89d53 | |
| parent | 66c29b973b3b10278bd39f4e26b08522a379c2c9 (diff) | |
| parent | fd3e966bdded5d556d01f1db5c3d6a78539661f8 (diff) | |
| download | rust-ed74c22f33da446eb91d2069b3fdc8e3d93bff16.tar.gz rust-ed74c22f33da446eb91d2069b3fdc8e3d93bff16.zip | |
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]`
| -rw-r--r-- | clippy_lints/src/eta_reduction.rs | 14 | ||||
| -rw-r--r-- | tests/ui/eta.fixed | 17 | ||||
| -rw-r--r-- | tests/ui/eta.rs | 17 | ||||
| -rw-r--r-- | tests/ui/eta.stderr | 2 |
4 files changed, 46 insertions, 4 deletions
diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index 450cee4007c..1ea5b789805 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -21,8 +21,8 @@ use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _; declare_clippy_lint! { /// ### What it does /// Checks for closures which just call another function where - /// the function can be called directly. `unsafe` functions or calls where types - /// get adjusted are ignored. + /// the function can be called directly. `unsafe` functions, calls where types + /// get adjusted or where the callee is marked `#[track_caller]` are ignored. /// /// ### Why is this bad? /// Needlessly creating a closure adds code for no benefit @@ -136,7 +136,14 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction { .map_or(callee_ty, |a| a.target.peel_refs()); let sig = match callee_ty_adjusted.kind() { - ty::FnDef(def, _) => cx.tcx.fn_sig(def).skip_binder().skip_binder(), + ty::FnDef(def, _) => { + // Rewriting `x(|| f())` to `x(f)` where f is marked `#[track_caller]` moves the `Location` + if cx.tcx.has_attr(*def, sym::track_caller) { + return; + } + + cx.tcx.fn_sig(def).skip_binder().skip_binder() + }, ty::FnPtr(sig) => sig.skip_binder(), ty::Closure(_, subs) => cx .tcx @@ -186,6 +193,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction { }, ExprKind::MethodCall(path, self_, args, _) if check_inputs(typeck, body.params, Some(self_), args) => { if let Some(method_def_id) = typeck.type_dependent_def_id(body.value.hir_id) + && !cx.tcx.has_attr(method_def_id, sym::track_caller) && check_sig(cx, closure, cx.tcx.fn_sig(method_def_id).skip_binder().skip_binder()) { span_lint_and_then( diff --git a/tests/ui/eta.fixed b/tests/ui/eta.fixed index 32c7499bf73..3aeb4dae30b 100644 --- a/tests/ui/eta.fixed +++ b/tests/ui/eta.fixed @@ -346,6 +346,23 @@ fn angle_brackets_and_args() { dyn_opt.map(<dyn TestTrait>::method_on_dyn); } +// https://github.com/rust-lang/rust-clippy/issues/12199 +fn track_caller_fp() { + struct S; + impl S { + #[track_caller] + fn add_location(self) {} + } + + #[track_caller] + fn add_location() {} + + fn foo(_: fn()) {} + fn foo2(_: fn(S)) {} + foo(|| add_location()); + foo2(|s| s.add_location()); +} + fn _late_bound_to_early_bound_regions() { struct Foo<'a>(&'a u32); impl<'a> Foo<'a> { diff --git a/tests/ui/eta.rs b/tests/ui/eta.rs index 25b7431ba8c..b9b3303b371 100644 --- a/tests/ui/eta.rs +++ b/tests/ui/eta.rs @@ -346,6 +346,23 @@ fn angle_brackets_and_args() { dyn_opt.map(|d| d.method_on_dyn()); } +// https://github.com/rust-lang/rust-clippy/issues/12199 +fn track_caller_fp() { + struct S; + impl S { + #[track_caller] + fn add_location(self) {} + } + + #[track_caller] + fn add_location() {} + + fn foo(_: fn()) {} + fn foo2(_: fn(S)) {} + foo(|| add_location()); + foo2(|s| s.add_location()); +} + fn _late_bound_to_early_bound_regions() { struct Foo<'a>(&'a u32); impl<'a> Foo<'a> { diff --git a/tests/ui/eta.stderr b/tests/ui/eta.stderr index 951e4ac749c..7c4d2d7093e 100644 --- a/tests/ui/eta.stderr +++ b/tests/ui/eta.stderr @@ -161,7 +161,7 @@ LL | dyn_opt.map(|d| d.method_on_dyn()); | ^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<dyn TestTrait>::method_on_dyn` error: redundant closure - --> $DIR/eta.rs:389:19 + --> $DIR/eta.rs:406:19 | LL | let _ = f(&0, |x, y| f2(x, y)); | ^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `f2` |
