11use clippy_utils:: diagnostics:: { span_lint_and_sugg, span_lint_and_then} ;
22use clippy_utils:: higher:: VecArgs ;
33use clippy_utils:: source:: snippet_opt;
4- use clippy_utils:: ty:: is_type_diagnostic_item;
4+ use clippy_utils:: ty:: { implements_trait , is_type_diagnostic_item} ;
55use clippy_utils:: usage:: local_used_after_expr;
66use clippy_utils:: { higher, is_adjusted, path_to_local, path_to_local_id} ;
77use if_chain:: if_chain;
@@ -11,7 +11,7 @@ use rustc_hir::{Closure, Expr, ExprKind, Param, PatKind, Unsafety};
1111use rustc_lint:: { LateContext , LateLintPass } ;
1212use rustc_middle:: ty:: adjustment:: { Adjust , Adjustment , AutoBorrow } ;
1313use rustc_middle:: ty:: binding:: BindingMode ;
14- use rustc_middle:: ty:: { self , ClosureKind , Ty , TypeVisitable } ;
14+ use rustc_middle:: ty:: { self , Ty , TypeVisitable } ;
1515use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
1616use rustc_span:: symbol:: sym;
1717
@@ -122,15 +122,11 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
122122 then {
123123 span_lint_and_then( cx, REDUNDANT_CLOSURE , expr. span, "redundant closure" , |diag| {
124124 if let Some ( mut snippet) = snippet_opt( cx, callee. span) {
125- if_chain! {
126- if let ty:: Closure ( _, substs) = callee_ty. peel_refs( ) . kind( ) ;
127- if substs. as_closure( ) . kind( ) == ClosureKind :: FnMut ;
128- if path_to_local( callee) . map_or( false , |l| local_used_after_expr( cx, l, expr) ) ;
129-
130- then {
125+ if let Some ( fn_mut_id) = cx. tcx. lang_items( ) . fn_mut_trait( ) &&
126+ implements_trait( cx, callee_ty. peel_refs( ) , fn_mut_id, & [ ] ) &&
127+ path_to_local( callee) . map_or( false , |l| local_used_after_expr( cx, l, expr) ) {
131128 // Mutable closure is used after current expr; we cannot consume it.
132129 snippet = format!( "&mut {snippet}" ) ;
133- }
134130 }
135131 diag. span_suggestion(
136132 expr. span,
0 commit comments