11use clippy_utils:: diagnostics:: span_lint_and_then;
22use clippy_utils:: sugg:: Sugg ;
3- use clippy_utils:: ty:: is_type_diagnostic_item;
43use clippy_utils:: {
54 get_enclosing_block, is_expr_path_def_path, is_integer_literal, is_path_diagnostic_item, path_to_local,
65 path_to_local_id, paths, SpanlessEq ,
76} ;
87use if_chain:: if_chain;
98use rustc_errors:: Applicability ;
109use rustc_hir:: intravisit:: { walk_block, walk_expr, walk_stmt, Visitor } ;
11- use rustc_hir:: { BindingAnnotation , Block , Expr , ExprKind , HirId , PatKind , QPath , Stmt , StmtKind } ;
10+ use rustc_hir:: { BindingAnnotation , Block , Expr , ExprKind , HirId , PatKind , Stmt , StmtKind } ;
1211use rustc_lint:: { LateContext , LateLintPass } ;
1312use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
1413use rustc_span:: symbol:: sym;
@@ -133,8 +132,15 @@ impl<'tcx> LateLintPass<'tcx> for SlowVectorInit {
133132}
134133
135134impl SlowVectorInit {
135+ /// Looks for `Vec::with_capacity(size)` or `Vec::new()` calls and returns the initialized size,
136+ /// if any. More specifically, it returns:
137+ /// - `Some(InitializedSize::Initialized(size))` for `Vec::with_capacity(size)`
138+ /// - `Some(InitializedSize::Uninitialized)` for `Vec::new()`
139+ /// - `None` for other, unrelated kinds of expressions
136140 fn as_vec_initializer < ' tcx > ( cx : & LateContext < ' _ > , expr : & ' tcx Expr < ' tcx > ) -> Option < InitializedSize < ' tcx > > {
137- if let Some ( len_expr) = Self :: is_vec_with_capacity ( cx, expr) {
141+ if let ExprKind :: Call ( func, [ len_expr] ) = expr. kind
142+ && is_expr_path_def_path ( cx, func, & paths:: VEC_WITH_CAPACITY )
143+ {
138144 Some ( InitializedSize :: Initialized ( len_expr) )
139145 } else if matches ! ( expr. kind, ExprKind :: Call ( func, _) if is_expr_path_def_path( cx, func, & paths:: VEC_NEW ) ) {
140146 Some ( InitializedSize :: Uninitialized )
@@ -143,22 +149,6 @@ impl SlowVectorInit {
143149 }
144150 }
145151
146- /// Checks if the given expression is `Vec::with_capacity(..)`. It will return the expression
147- /// of the first argument of `with_capacity` call if it matches or `None` if it does not.
148- fn is_vec_with_capacity < ' tcx > ( cx : & LateContext < ' _ > , expr : & Expr < ' tcx > ) -> Option < & ' tcx Expr < ' tcx > > {
149- if_chain ! {
150- if let ExprKind :: Call ( func, [ arg] ) = expr. kind;
151- if let ExprKind :: Path ( QPath :: TypeRelative ( ty, name) ) = func. kind;
152- if name. ident. as_str( ) == "with_capacity" ;
153- if is_type_diagnostic_item( cx, cx. typeck_results( ) . node_type( ty. hir_id) , sym:: Vec ) ;
154- then {
155- Some ( arg)
156- } else {
157- None
158- }
159- }
160- }
161-
162152 /// Search initialization for the given vector
163153 fn search_initialization < ' tcx > ( cx : & LateContext < ' tcx > , vec_alloc : VecAllocation < ' tcx > , parent_node : HirId ) {
164154 let enclosing_body = get_enclosing_block ( cx, parent_node) ;
0 commit comments