Skip to content

Commit

Permalink
avoid linting on #[track_caller] functions in redundant_closure
Browse files Browse the repository at this point in the history
  • Loading branch information
y21 committed Jan 25, 2024
1 parent 66c29b9 commit 298f4a5
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 4 deletions.
14 changes: 11 additions & 3 deletions clippy_lints/src/eta_reduction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 `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
Expand Down Expand Up @@ -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(
Expand Down
17 changes: 17 additions & 0 deletions tests/ui/eta.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down
17 changes: 17 additions & 0 deletions tests/ui/eta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/eta.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down

0 comments on commit 298f4a5

Please sign in to comment.