From 828ddbe414d77d61292a72ffb9ade85cd6e72cda Mon Sep 17 00:00:00 2001 From: Elliot Bobrow Date: Wed, 29 Dec 2021 08:52:40 -0800 Subject: [PATCH] fix [`redundant_closure`] fp with `Arc` --- clippy_lints/src/eta_reduction.rs | 5 +++++ tests/ui/eta.fixed | 11 +++++++++++ tests/ui/eta.rs | 11 +++++++++++ 3 files changed, 27 insertions(+) diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index 5a4b4247104..b22515a3907 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -1,6 +1,7 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::higher::VecArgs; use clippy_utils::source::snippet_opt; +use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::usage::local_used_after_expr; use clippy_utils::{get_enclosing_loop_or_closure, higher, path_to_local, path_to_local_id}; use if_chain::if_chain; @@ -12,6 +13,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{self, ClosureKind, Ty, TypeFoldable}; use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::symbol::sym; declare_clippy_lint! { /// ### What it does @@ -113,6 +115,9 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction { // A type param function ref like `T::f` is not 'static, however // it is if cast like `T::f as fn()`. This seems like a rustc bug. if !substs.types().any(|t| matches!(t.kind(), ty::Param(_))); + let callee_ty_unadjusted = cx.typeck_results().expr_ty(callee).peel_refs(); + if !is_type_diagnostic_item(cx, callee_ty_unadjusted, sym::Arc); + if !is_type_diagnostic_item(cx, callee_ty_unadjusted, sym::Rc); then { span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure", |diag| { if let Some(mut snippet) = snippet_opt(cx, callee.span) { diff --git a/tests/ui/eta.fixed b/tests/ui/eta.fixed index 1de79667f55..f938f710688 100644 --- a/tests/ui/eta.fixed +++ b/tests/ui/eta.fixed @@ -248,3 +248,14 @@ mod type_param_bound { take(X::fun as fn()); } } + +// #8073 Don't replace closure with `Arc` or `Rc` +fn arc_fp() { + let rc = std::rc::Rc::new(|| 7); + let arc = std::sync::Arc::new(|n| n + 1); + let ref_arc = &std::sync::Arc::new(|_| 5); + + true.then(|| rc()); + (0..5).map(|n| arc(n)); + Some(4).map(|n| ref_arc(n)); +} diff --git a/tests/ui/eta.rs b/tests/ui/eta.rs index 86abd347baa..075bbc74922 100644 --- a/tests/ui/eta.rs +++ b/tests/ui/eta.rs @@ -248,3 +248,14 @@ mod type_param_bound { take(X::fun as fn()); } } + +// #8073 Don't replace closure with `Arc` or `Rc` +fn arc_fp() { + let rc = std::rc::Rc::new(|| 7); + let arc = std::sync::Arc::new(|n| n + 1); + let ref_arc = &std::sync::Arc::new(|_| 5); + + true.then(|| rc()); + (0..5).map(|n| arc(n)); + Some(4).map(|n| ref_arc(n)); +}