Skip to content

Commit 946dbb6

Browse files
committed
Lint only the first statment/expression after alloc
Instead of searching for all the successive expressions after a vector allocation, check only the first expression. This is done to minimize the amount of false positives of the lint.
1 parent 10e712d commit 946dbb6

File tree

3 files changed

+48
-18
lines changed

3 files changed

+48
-18
lines changed

clippy_lints/src/slow_vector_initialization.rs

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// option. This file may not be copied, modified, or distributed
88
// except according to those terms.
99

10-
use crate::rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
10+
use crate::rustc::hir::intravisit::{walk_expr, walk_stmt, walk_block, NestedVisitorMap, Visitor};
1111
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass, Lint};
1212
use crate::rustc::{declare_tool_lint, lint_array};
1313
use crate::rustc::hir::*;
@@ -353,20 +353,41 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
353353
}
354354

355355
impl<'a, 'tcx> Visitor<'tcx> for VectorInitializationVisitor<'a, 'tcx> {
356-
fn visit_expr(&mut self, expr: &'tcx Expr) {
357-
// Stop the search if we already found a slow zero-filling initialization
358-
if self.slow_expression.is_some() {
359-
return
356+
fn visit_stmt(&mut self, stmt: &'tcx Stmt) {
357+
if self.initialization_found {
358+
match stmt.node {
359+
StmtKind::Expr(ref expr, _) |
360+
StmtKind::Semi(ref expr, _) => {
361+
self.search_slow_extend_filling(expr);
362+
self.search_slow_resize_filling(expr);
363+
self.search_unsafe_set_len(expr);
364+
},
365+
_ => (),
366+
}
367+
368+
self.initialization_found = false;
369+
} else {
370+
walk_stmt(self, stmt);
371+
}
372+
}
373+
374+
fn visit_block(&mut self, block: &'tcx Block) {
375+
if self.initialization_found {
376+
if let Some(ref s) = block.stmts.get(0) {
377+
self.visit_stmt( s)
378+
}
379+
380+
self.initialization_found = false;
381+
} else {
382+
walk_block(self, block);
360383
}
384+
}
361385

386+
fn visit_expr(&mut self, expr: &'tcx Expr) {
362387
// Skip all the expressions previous to the vector initialization
363388
if self.vec_alloc.allocation_expr.id == expr.id {
364389
self.initialization_found = true;
365390
}
366-
367-
self.search_slow_extend_filling(expr);
368-
self.search_slow_resize_filling(expr);
369-
self.search_unsafe_set_len(expr);
370391

371392
walk_expr(self, expr);
372393
}

tests/ui/slow_vector_initialization.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@ fn extend_vector() {
3434
fn mixed_extend_resize_vector() {
3535
// Mismatching len
3636
let mut mismatching_len = Vec::with_capacity(30);
37+
mismatching_len.extend(repeat(0).take(40));
3738

3839
// Slow initialization
3940
let mut resized_vec = Vec::with_capacity(30);
40-
let mut extend_vec = Vec::with_capacity(30);
41-
4241
resized_vec.resize(30, 0);
43-
mismatching_len.extend(repeat(0).take(40));
42+
43+
let mut extend_vec = Vec::with_capacity(30);
4444
extend_vec.extend(repeat(0).take(30));
4545
}
4646

@@ -70,3 +70,14 @@ fn unsafe_vector() {
7070
unsafe_vec.set_len(200);
7171
}
7272
}
73+
74+
fn do_stuff(vec: &mut Vec<u8>) {
75+
76+
}
77+
78+
fn extend_vector_with_manipulations_between() {
79+
let len = 300;
80+
let mut vec1:Vec<u8> = Vec::with_capacity(len);
81+
do_stuff(&mut vec1);
82+
vec1.extend(repeat(0).take(len));
83+
}

tests/ui/slow_vector_initialization.stderr

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,18 @@ error: slow zero-filling initialization
1717
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1818

1919
error: slow zero-filling initialization
20-
--> $DIR/slow_vector_initialization.rs:42:5
20+
--> $DIR/slow_vector_initialization.rs:41:5
2121
|
22-
39 | let mut resized_vec = Vec::with_capacity(30);
22+
40 | let mut resized_vec = Vec::with_capacity(30);
2323
| ---------------------- help: consider replace allocation with: `vec![0; 30]`
24-
...
25-
42 | resized_vec.resize(30, 0);
24+
41 | resized_vec.resize(30, 0);
2625
| ^^^^^^^^^^^^^^^^^^^^^^^^^
2726

2827
error: slow zero-filling initialization
2928
--> $DIR/slow_vector_initialization.rs:44:5
3029
|
31-
40 | let mut extend_vec = Vec::with_capacity(30);
30+
43 | let mut extend_vec = Vec::with_capacity(30);
3231
| ---------------------- help: consider replace allocation with: `vec![0; 30]`
33-
...
3432
44 | extend_vec.extend(repeat(0).take(30));
3533
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3634

0 commit comments

Comments
 (0)