Update vec_init_then_push docs

This commit is contained in:
Jason Newcomb 2022-04-24 09:46:17 -04:00
parent 948af01633
commit f1574cc131
3 changed files with 45 additions and 6 deletions

View file

@ -18,6 +18,13 @@ declare_clippy_lint! {
/// ### What it does
/// Checks for calls to `push` immediately after creating a new `Vec`.
///
/// If the `Vec` is created using `with_capacity` this will only lint if the capacity is a
/// constant and the number of pushes is greater than or equal to the initial capacity.
///
/// If the `Vec` is extended after the initial sequence of pushes and it was default initialized
/// then this will only lint after there were at least four pushes. This number may change in
/// the future.
///
/// ### Why is this bad?
/// The `vec![]` macro is both more performant and easier to read than
/// multiple `push` calls.
@ -56,7 +63,7 @@ struct VecPushSearcher {
}
impl VecPushSearcher {
fn display_err(&self, cx: &LateContext<'_>) {
let min_pushes_for_extension = match self.init {
let required_pushes_before_extension = match self.init {
_ if self.found == 0 => return,
VecInitKind::WithConstCapacity(x) if x > self.found => return,
VecInitKind::WithConstCapacity(x) => x,
@ -98,6 +105,8 @@ impl VecPushSearcher {
&& adjusted_mut == Mutability::Mut
&& !adjusted_ty.peel_refs().is_slice() =>
{
// No need to set `needs_mut` to true. The receiver will be either explicitly borrowed, or it will
// be implicitly borrowed via an adjustment. Both of these cases are already handled by this point.
return ControlFlow::Break(true);
},
ExprKind::Assign(lhs, ..) if e.hir_id == lhs.hir_id => {
@ -110,7 +119,7 @@ impl VecPushSearcher {
});
// Avoid allocating small `Vec`s when they'll be extended right after.
if res == ControlFlow::Break(true) && self.found <= min_pushes_for_extension {
if res == ControlFlow::Break(true) && self.found <= required_pushes_before_extension {
return;
}

View file

@ -29,6 +29,12 @@ fn main() {
// no lint
vec.push(1);
}
let mut vec = Vec::with_capacity(5);
vec.push(1);
vec.push(2);
vec.push(3);
vec.push(4);
}
pub fn no_lint() -> Vec<i32> {
@ -84,5 +90,17 @@ fn _cond_push_with_large_start(x: bool) -> Vec<u32> {
if x {
v.push(1);
}
v
let mut v2 = Vec::new();
v2.push(0);
v2.push(1);
v2.push(0);
v2.push(1);
v2.push(0);
v2.push(0);
v2.push(1);
v2.push(0);
v2.extend(&v);
v2
}

View file

@ -31,7 +31,7 @@ LL | | new_err.push(0);
| |____________________^ help: consider using the `vec![]` macro: `new_err = vec![..];`
error: calls to `push` immediately after creation
--> $DIR/vec_init_then_push.rs:67:5
--> $DIR/vec_init_then_push.rs:73:5
|
LL | / let mut v = Vec::new();
LL | | v.push(x);
@ -39,7 +39,7 @@ LL | | v.push(1);
| |______________^ help: consider using the `vec![]` macro: `let mut v = vec![..];`
error: calls to `push` immediately after creation
--> $DIR/vec_init_then_push.rs:75:5
--> $DIR/vec_init_then_push.rs:81:5
|
LL | / let mut v = Vec::new();
LL | | v.push(0);
@ -50,5 +50,17 @@ LL | | v.push(1);
LL | | v.push(0);
| |______________^ help: consider using the `vec![]` macro: `let mut v = vec![..];`
error: aborting due to 6 previous errors
error: calls to `push` immediately after creation
--> $DIR/vec_init_then_push.rs:94:5
|
LL | / let mut v2 = Vec::new();
LL | | v2.push(0);
LL | | v2.push(1);
LL | | v2.push(0);
... |
LL | | v2.push(1);
LL | | v2.push(0);
| |_______________^ help: consider using the `vec![]` macro: `let mut v2 = vec![..];`
error: aborting due to 7 previous errors