fix [redundant_closure] fp with Arc

This commit is contained in:
Elliot Bobrow 2021-12-29 08:52:40 -08:00
parent c1cd64b9c6
commit 828ddbe414
3 changed files with 27 additions and 0 deletions

View file

@ -1,6 +1,7 @@
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
use clippy_utils::higher::VecArgs; use clippy_utils::higher::VecArgs;
use clippy_utils::source::snippet_opt; 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::usage::local_used_after_expr;
use clippy_utils::{get_enclosing_loop_or_closure, higher, path_to_local, path_to_local_id}; use clippy_utils::{get_enclosing_loop_or_closure, higher, path_to_local, path_to_local_id};
use if_chain::if_chain; 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::subst::Subst;
use rustc_middle::ty::{self, ClosureKind, Ty, TypeFoldable}; use rustc_middle::ty::{self, ClosureKind, Ty, TypeFoldable};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::sym;
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### 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 // 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. // 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(_))); 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 { then {
span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure", |diag| { span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure", |diag| {
if let Some(mut snippet) = snippet_opt(cx, callee.span) { if let Some(mut snippet) = snippet_opt(cx, callee.span) {

View file

@ -248,3 +248,14 @@ mod type_param_bound {
take(X::fun as fn()); take(X::fun as fn());
} }
} }
// #8073 Don't replace closure with `Arc<F>` or `Rc<F>`
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));
}

View file

@ -248,3 +248,14 @@ mod type_param_bound {
take(X::fun as fn()); take(X::fun as fn());
} }
} }
// #8073 Don't replace closure with `Arc<F>` or `Rc<F>`
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));
}