@@ -6,7 +6,7 @@ use clippy_utils::visitors::for_each_expr;
66use clippy_utils:: { SpanlessEq , get_enclosing_block, match_def_path, paths} ;
77use core:: ops:: ControlFlow ;
88use rustc_errors:: Applicability ;
9- use rustc_hir:: { Block , Expr , ExprKind , PathSegment } ;
9+ use rustc_hir:: { Block , Expr , ExprKind } ;
1010use rustc_lint:: { LateContext , LateLintPass } ;
1111use rustc_session:: impl_lint_pass;
1212use rustc_span:: sym;
@@ -56,11 +56,11 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryReserve {
5656 return ;
5757 }
5858
59- if let ExprKind :: MethodCall ( PathSegment { ident : method, .. } , struct_calling_on , args_a , _) = expr. kind
60- && method. name . as_str ( ) == "reserve"
61- && acceptable_type ( cx, struct_calling_on )
59+ if let ExprKind :: MethodCall ( method, receiver , [ arg ] , _) = expr. kind
60+ && method. ident . name . as_str ( ) == "reserve"
61+ && acceptable_type ( cx, receiver )
6262 && let Some ( block) = get_enclosing_block ( cx, expr. hir_id )
63- && let Some ( next_stmt_span) = check_extend_method ( cx, block, struct_calling_on , & args_a [ 0 ] )
63+ && let Some ( next_stmt_span) = check_extend_method ( cx, block, receiver , arg )
6464 && !next_stmt_span. from_expansion ( )
6565 {
6666 let stmt_span = cx
@@ -91,50 +91,36 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryReserve {
9191}
9292
9393fn acceptable_type ( cx : & LateContext < ' _ > , struct_calling_on : & Expr < ' _ > ) -> bool {
94- if let Some ( did) = adt_def_id ( cx. typeck_results ( ) . expr_ty_adjusted ( struct_calling_on) ) {
95- matches ! ( cx. tcx. get_diagnostic_name( did) , Some ( sym:: Vec | sym:: VecDeque ) )
96- } else {
97- false
98- }
94+ adt_def_id ( cx. typeck_results ( ) . expr_ty_adjusted ( struct_calling_on) )
95+ . is_some_and ( |did| matches ! ( cx. tcx. get_diagnostic_name( did) , Some ( sym:: Vec | sym:: VecDeque ) ) )
9996}
10097
10198#[ must_use]
10299fn check_extend_method < ' tcx > (
103100 cx : & LateContext < ' tcx > ,
104101 block : & ' tcx Block < ' tcx > ,
105102 struct_expr : & Expr < ' tcx > ,
106- args_a : & Expr < ' tcx > ,
103+ arg : & Expr < ' tcx > ,
107104) -> Option < rustc_span:: Span > {
108105 let mut found_reserve = false ;
109- let mut read_found = false ;
110- let mut spanless_eq = SpanlessEq :: new ( cx) ;
106+ let mut spanless_eq = SpanlessEq :: new ( cx) . deny_side_effects ( ) ;
111107
112- let _ : Option < ! > = for_each_expr ( cx, block, |expr : & Expr < ' tcx > | {
108+ for_each_expr ( cx, block, |expr : & Expr < ' tcx > | {
113109 if !found_reserve {
114- if expr. hir_id == args_a. hir_id {
115- found_reserve = true ;
116- }
110+ found_reserve = expr. hir_id == arg. hir_id ;
117111 return ControlFlow :: Continue ( ( ) ) ;
118112 }
119113
120- if let ExprKind :: MethodCall ( _ , struct_calling_on, _, _) = expr. kind
114+ if let ExprKind :: MethodCall ( _method , struct_calling_on, _, _) = expr. kind
121115 && let Some ( expr_def_id) = cx. typeck_results ( ) . type_dependent_def_id ( expr. hir_id )
122- && let ExprKind :: MethodCall (
123- PathSegment {
124- ident : method_call_a, ..
125- } ,
126- ..,
127- ) = args_a. kind
128- && method_call_a. name == sym:: len
116+ && let ExprKind :: MethodCall ( len_method, ..) = arg. kind
117+ && len_method. ident . name == sym:: len
129118 && match_def_path ( cx, expr_def_id, & paths:: ITER_EXTEND )
130119 && acceptable_type ( cx, struct_calling_on)
131120 && spanless_eq. eq_expr ( struct_calling_on, struct_expr)
132121 {
133- read_found = true ;
122+ return ControlFlow :: Break ( block . span ) ;
134123 }
135- let _: bool = !read_found;
136124 ControlFlow :: Continue ( ( ) )
137- } ) ;
138-
139- if read_found { Some ( block. span ) } else { None }
125+ } )
140126}
0 commit comments