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]`
This commit is contained in:
commit
ed74c22f33
@ -21,8 +21,8 @@ use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
|
|||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
/// ### What it does
|
/// ### What it does
|
||||||
/// Checks for closures which just call another function where
|
/// Checks for closures which just call another function where
|
||||||
/// the function can be called directly. `unsafe` functions or calls where types
|
/// the function can be called directly. `unsafe` functions, calls where types
|
||||||
/// get adjusted are ignored.
|
/// get adjusted or where the callee is marked `#[track_caller]` are ignored.
|
||||||
///
|
///
|
||||||
/// ### Why is this bad?
|
/// ### Why is this bad?
|
||||||
/// Needlessly creating a closure adds code for no benefit
|
/// 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());
|
.map_or(callee_ty, |a| a.target.peel_refs());
|
||||||
|
|
||||||
let sig = match callee_ty_adjusted.kind() {
|
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::FnPtr(sig) => sig.skip_binder(),
|
||||||
ty::Closure(_, subs) => cx
|
ty::Closure(_, subs) => cx
|
||||||
.tcx
|
.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) => {
|
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)
|
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())
|
&& check_sig(cx, closure, cx.tcx.fn_sig(method_def_id).skip_binder().skip_binder())
|
||||||
{
|
{
|
||||||
span_lint_and_then(
|
span_lint_and_then(
|
||||||
|
@ -346,6 +346,23 @@ fn angle_brackets_and_args() {
|
|||||||
dyn_opt.map(<dyn TestTrait>::method_on_dyn);
|
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() {
|
fn _late_bound_to_early_bound_regions() {
|
||||||
struct Foo<'a>(&'a u32);
|
struct Foo<'a>(&'a u32);
|
||||||
impl<'a> Foo<'a> {
|
impl<'a> Foo<'a> {
|
||||||
|
@ -346,6 +346,23 @@ fn angle_brackets_and_args() {
|
|||||||
dyn_opt.map(|d| d.method_on_dyn());
|
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() {
|
fn _late_bound_to_early_bound_regions() {
|
||||||
struct Foo<'a>(&'a u32);
|
struct Foo<'a>(&'a u32);
|
||||||
impl<'a> Foo<'a> {
|
impl<'a> Foo<'a> {
|
||||||
|
@ -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`
|
| ^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<dyn TestTrait>::method_on_dyn`
|
||||||
|
|
||||||
error: redundant closure
|
error: redundant closure
|
||||||
--> $DIR/eta.rs:389:19
|
--> $DIR/eta.rs:406:19
|
||||||
|
|
|
|
||||||
LL | let _ = f(&0, |x, y| f2(x, y));
|
LL | let _ = f(&0, |x, y| f2(x, y));
|
||||||
| ^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `f2`
|
| ^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `f2`
|
||||||
|
Loading…
x
Reference in New Issue
Block a user