avoid linting on #[track_caller] functions in redundant_closure

This commit is contained in:
y21 2024-01-26 00:23:13 +01:00
parent 66c29b973b
commit fd3e966bdd
4 changed files with 46 additions and 4 deletions

View File

@ -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(

View File

@ -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> {

View File

@ -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> {

View File

@ -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`