11use clippy_config:: msrvs:: { self , Msrv } ;
22use clippy_utils:: diagnostics:: span_lint_and_then;
3- use clippy_utils:: mir:: { enclosing_mir , expr_local , local_assignments , used_exactly_once , PossibleBorrowerMap } ;
3+ use clippy_utils:: mir:: PossibleBorrowerMap ;
44use clippy_utils:: source:: snippet_with_context;
55use clippy_utils:: ty:: { implements_trait, is_copy} ;
66use clippy_utils:: { expr_use_ctxt, peel_n_hir_expr_refs, DefinedTy , ExprUseNode } ;
@@ -11,7 +11,6 @@ use rustc_hir::{Body, Expr, ExprKind, Mutability, Path, QPath};
1111use rustc_index:: bit_set:: BitSet ;
1212use rustc_infer:: infer:: TyCtxtInferExt ;
1313use rustc_lint:: { LateContext , LateLintPass } ;
14- use rustc_middle:: mir:: { Rvalue , StatementKind } ;
1514use rustc_middle:: ty:: {
1615 self , ClauseKind , EarlyBinder , FnSig , GenericArg , GenericArgKind , List , ParamTy , ProjectionPredicate , Ty ,
1716} ;
@@ -106,7 +105,6 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowsForGenericArgs<'tcx> {
106105 }
107106 && let count = needless_borrow_count (
108107 cx,
109- & mut self . possible_borrowers ,
110108 fn_id,
111109 cx. typeck_results ( ) . node_args ( hir_id) ,
112110 i,
@@ -155,11 +153,9 @@ fn path_has_args(p: &QPath<'_>) -> bool {
155153/// The following constraints will be checked:
156154/// * The borrowed expression meets all the generic type's constraints.
157155/// * The generic type appears only once in the functions signature.
158- /// * The borrowed value will not be moved if it is used later in the function.
159- #[ expect( clippy:: too_many_arguments) ]
156+ /// * The borrowed value is Copy itself OR not a variable (created by a function call)
160157fn needless_borrow_count < ' tcx > (
161158 cx : & LateContext < ' tcx > ,
162- possible_borrowers : & mut Vec < ( LocalDefId , PossibleBorrowerMap < ' tcx , ' tcx > ) > ,
163159 fn_id : DefId ,
164160 callee_args : & ' tcx List < GenericArg < ' tcx > > ,
165161 arg_index : usize ,
@@ -234,9 +230,9 @@ fn needless_borrow_count<'tcx>(
234230
235231 let referent_ty = cx. typeck_results ( ) . expr_ty ( referent) ;
236232
237- if !is_copy ( cx, referent_ty)
238- && ( referent_ty . has_significant_drop ( cx . tcx , cx . param_env )
239- || ! referent_used_exactly_once ( cx , possible_borrowers , reference ) )
233+ if ( !is_copy ( cx, referent_ty) && !referent_ty . is_ref ( ) )
234+ && let ExprKind :: AddrOf ( _ , _ , inner ) = reference . kind
235+ && ! matches ! ( inner . kind , ExprKind :: Call ( .. ) | ExprKind :: MethodCall ( .. ) )
240236 {
241237 return false ;
242238 }
@@ -339,37 +335,6 @@ fn is_mixed_projection_predicate<'tcx>(
339335 }
340336}
341337
342- fn referent_used_exactly_once < ' tcx > (
343- cx : & LateContext < ' tcx > ,
344- possible_borrowers : & mut Vec < ( LocalDefId , PossibleBorrowerMap < ' tcx , ' tcx > ) > ,
345- reference : & Expr < ' tcx > ,
346- ) -> bool {
347- if let Some ( mir) = enclosing_mir ( cx. tcx , reference. hir_id )
348- && let Some ( local) = expr_local ( cx. tcx , reference)
349- && let [ location] = * local_assignments ( mir, local) . as_slice ( )
350- && let block_data = & mir. basic_blocks [ location. block ]
351- && let Some ( statement) = block_data. statements . get ( location. statement_index )
352- && let StatementKind :: Assign ( box ( _, Rvalue :: Ref ( _, _, place) ) ) = statement. kind
353- && !place. is_indirect_first_projection ( )
354- {
355- let body_owner_local_def_id = cx. tcx . hir ( ) . enclosing_body_owner ( reference. hir_id ) ;
356- if possible_borrowers
357- . last ( )
358- . map_or ( true , |& ( local_def_id, _) | local_def_id != body_owner_local_def_id)
359- {
360- possible_borrowers. push ( ( body_owner_local_def_id, PossibleBorrowerMap :: new ( cx, mir) ) ) ;
361- }
362- let possible_borrower = & mut possible_borrowers. last_mut ( ) . unwrap ( ) . 1 ;
363- // If `only_borrowers` were used here, the `copyable_iterator::warn` test would fail. The reason is
364- // that `PossibleBorrowerVisitor::visit_terminator` considers `place.local` a possible borrower of
365- // itself. See the comment in that method for an explanation as to why.
366- possible_borrower. bounded_borrowers ( & [ local] , & [ local, place. local ] , place. local , location)
367- && used_exactly_once ( mir, place. local ) . unwrap_or ( false )
368- } else {
369- false
370- }
371- }
372-
373338// Iteratively replaces `param_ty` with `new_ty` in `args`, and similarly for each resulting
374339// projected type that is a type parameter. Returns `false` if replacing the types would have an
375340// effect on the function signature beyond substituting `new_ty` for `param_ty`.
0 commit comments