Skip to content

Commit f718984

Browse files
committed
Auto merge of rust-lang#8953 - DevAccentor:slow_vector_initialization, r=Manishearth
add vec.capacity() to [`slow_vec_initialization`] detection fix rust-lang#8800 for example ```rust let mut vec1 = Vec::with_capacity(len); vec1.resize(vec1.capacity(), 0); let mut vec2 = Vec::with_capacity(len); vec2.extend(repeat(0).take(vec2.capacity())); ``` will trigger the lint --- changelog: add `vec.capacity()` to [`slow_vec_initialization`] detection
2 parents 2cc5211 + 5a70d88 commit f718984

File tree

3 files changed

+49
-24
lines changed

3 files changed

+49
-24
lines changed

clippy_lints/src/slow_vector_initialization.rs

+21-18
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ declare_clippy_lint! {
2626
/// let mut vec1 = Vec::with_capacity(len);
2727
/// vec1.resize(len, 0);
2828
///
29+
/// let mut vec1 = Vec::with_capacity(len);
30+
/// vec1.resize(vec1.capacity(), 0);
31+
///
2932
/// let mut vec2 = Vec::with_capacity(len);
3033
/// vec2.extend(repeat(0).take(len));
3134
/// ```
@@ -211,23 +214,20 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
211214

212215
/// Checks if the given expression is resizing a vector with 0
213216
fn search_slow_resize_filling(&mut self, expr: &'tcx Expr<'_>) {
214-
if_chain! {
215-
if self.initialization_found;
216-
if let ExprKind::MethodCall(path, [self_arg, len_arg, fill_arg], _) = expr.kind;
217-
if path_to_local_id(self_arg, self.vec_alloc.local_id);
218-
if path.ident.name == sym!(resize);
219-
217+
if self.initialization_found
218+
&& let ExprKind::MethodCall(path, [self_arg, len_arg, fill_arg], _) = expr.kind
219+
&& path_to_local_id(self_arg, self.vec_alloc.local_id)
220+
&& path.ident.name == sym!(resize)
220221
// Check that is filled with 0
221-
if let ExprKind::Lit(ref lit) = fill_arg.kind;
222-
if let LitKind::Int(0, _) = lit.node;
223-
224-
// Check that len expression is equals to `with_capacity` expression
225-
if SpanlessEq::new(self.cx).eq_expr(len_arg, self.vec_alloc.len_expr);
226-
227-
then {
228-
self.slow_expression = Some(InitializationType::Resize(expr));
222+
&& let ExprKind::Lit(ref lit) = fill_arg.kind
223+
&& let LitKind::Int(0, _) = lit.node {
224+
// Check that len expression is equals to `with_capacity` expression
225+
if SpanlessEq::new(self.cx).eq_expr(len_arg, self.vec_alloc.len_expr) {
226+
self.slow_expression = Some(InitializationType::Resize(expr));
227+
} else if let ExprKind::MethodCall(path, _, _) = len_arg.kind && path.ident.as_str() == "capacity" {
228+
self.slow_expression = Some(InitializationType::Resize(expr));
229+
}
229230
}
230-
}
231231
}
232232

233233
/// Returns `true` if give expression is `repeat(0).take(...)`
@@ -240,12 +240,15 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
240240
if let Some(repeat_expr) = take_args.get(0);
241241
if self.is_repeat_zero(repeat_expr);
242242

243-
// Check that len expression is equals to `with_capacity` expression
244243
if let Some(len_arg) = take_args.get(1);
245-
if SpanlessEq::new(self.cx).eq_expr(len_arg, self.vec_alloc.len_expr);
246244

247245
then {
248-
return true;
246+
// Check that len expression is equals to `with_capacity` expression
247+
if SpanlessEq::new(self.cx).eq_expr(len_arg, self.vec_alloc.len_expr) {
248+
return true;
249+
} else if let ExprKind::MethodCall(path, _, _) = len_arg.kind && path.ident.as_str() == "capacity" {
250+
return true;
251+
}
249252
}
250253
}
251254

tests/ui/slow_vector_initialization.rs

+6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ fn extend_vector() {
1919
// Extend with mismatching expression should not be warned
2020
let mut vec3 = Vec::with_capacity(24322);
2121
vec3.extend(repeat(0).take(2));
22+
23+
let mut vec4 = Vec::with_capacity(len);
24+
vec4.extend(repeat(0).take(vec4.capacity()));
2225
}
2326

2427
fn mixed_extend_resize_vector() {
@@ -48,6 +51,9 @@ fn resize_vector() {
4851
let mut vec3 = Vec::with_capacity(len - 10);
4952
vec3.resize(len - 10, 0);
5053

54+
let mut vec4 = Vec::with_capacity(len);
55+
vec4.resize(vec4.capacity(), 0);
56+
5157
// Reinitialization should be warned
5258
vec1 = Vec::with_capacity(10);
5359
vec1.resize(10, 0);

tests/ui/slow_vector_initialization.stderr

+22-6
Original file line numberDiff line numberDiff line change
@@ -17,44 +17,60 @@ LL | vec2.extend(repeat(0).take(len - 10));
1717
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1818

1919
error: slow zero-filling initialization
20-
--> $DIR/slow_vector_initialization.rs:31:5
20+
--> $DIR/slow_vector_initialization.rs:24:5
21+
|
22+
LL | let mut vec4 = Vec::with_capacity(len);
23+
| ----------------------- help: consider replace allocation with: `vec![0; len]`
24+
LL | vec4.extend(repeat(0).take(vec4.capacity()));
25+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
26+
27+
error: slow zero-filling initialization
28+
--> $DIR/slow_vector_initialization.rs:34:5
2129
|
2230
LL | let mut resized_vec = Vec::with_capacity(30);
2331
| ---------------------- help: consider replace allocation with: `vec![0; 30]`
2432
LL | resized_vec.resize(30, 0);
2533
| ^^^^^^^^^^^^^^^^^^^^^^^^^
2634

2735
error: slow zero-filling initialization
28-
--> $DIR/slow_vector_initialization.rs:34:5
36+
--> $DIR/slow_vector_initialization.rs:37:5
2937
|
3038
LL | let mut extend_vec = Vec::with_capacity(30);
3139
| ---------------------- help: consider replace allocation with: `vec![0; 30]`
3240
LL | extend_vec.extend(repeat(0).take(30));
3341
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3442

3543
error: slow zero-filling initialization
36-
--> $DIR/slow_vector_initialization.rs:41:5
44+
--> $DIR/slow_vector_initialization.rs:44:5
3745
|
3846
LL | let mut vec1 = Vec::with_capacity(len);
3947
| ----------------------- help: consider replace allocation with: `vec![0; len]`
4048
LL | vec1.resize(len, 0);
4149
| ^^^^^^^^^^^^^^^^^^^
4250

4351
error: slow zero-filling initialization
44-
--> $DIR/slow_vector_initialization.rs:49:5
52+
--> $DIR/slow_vector_initialization.rs:52:5
4553
|
4654
LL | let mut vec3 = Vec::with_capacity(len - 10);
4755
| ---------------------------- help: consider replace allocation with: `vec![0; len - 10]`
4856
LL | vec3.resize(len - 10, 0);
4957
| ^^^^^^^^^^^^^^^^^^^^^^^^
5058

5159
error: slow zero-filling initialization
52-
--> $DIR/slow_vector_initialization.rs:53:5
60+
--> $DIR/slow_vector_initialization.rs:55:5
61+
|
62+
LL | let mut vec4 = Vec::with_capacity(len);
63+
| ----------------------- help: consider replace allocation with: `vec![0; len]`
64+
LL | vec4.resize(vec4.capacity(), 0);
65+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66+
67+
error: slow zero-filling initialization
68+
--> $DIR/slow_vector_initialization.rs:59:5
5369
|
5470
LL | vec1 = Vec::with_capacity(10);
5571
| ---------------------- help: consider replace allocation with: `vec![0; 10]`
5672
LL | vec1.resize(10, 0);
5773
| ^^^^^^^^^^^^^^^^^^
5874

59-
error: aborting due to 7 previous errors
75+
error: aborting due to 9 previous errors
6076

0 commit comments

Comments
 (0)