rust-lang / rust-lang/rust-clippy

`clippy::vec_init_then_push` can't be ignored

Open
#15,066 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-bug I-false-positive
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

Summary

I'm trying to come up with a configuration array that takes objects that are of a given type. The items in this global list can vary depending on compilation settings. As a result, I'm constructing the values in a LazyLock.

The items that are added to the vec depend on feature flags. As a result, I can't construct a vec![] as it suggests. Additionally, I can't seem to be able to turn them off in the obvious way.

Lint Name

vec_init_then_push

Reproducer

I tried this code:

#![allow(unexpected_cfgs)]
use std::sync::RwLock;
use std::sync::LazyLock;

trait ExampleTrait: Send + Sync {
    fn value(&self) -> u32;
}

struct Object {
    val: u32,
}

impl ExampleTrait for Object {
    fn value(&self) -> u32 {
        self.val
    }
}

fn init_object(val: u32) -> Object {
    Object { val }
}

static OBJECTS: LazyLock<RwLock<Vec<Box<dyn ExampleTrait>>>> = LazyLock::new(|| {
    #[allow(clippy::vec_init_then_push)]
    let mut v: Vec<Box<dyn ExampleTrait>> = vec![];
    
    #[allow(clippy::vec_init_then_push)]
    v.push(Box::new(init_object(1)));

    #[cfg(feature = "other-feature")]
    #[allow(clippy::vec_init_then_push)]
    v.push(Box::new(init_object(2)));
    
    RwLock::new(v)
});

fn main() {
    let test_list = &*OBJECTS.read().unwrap();
    for val in test_list {
        println!("Val: {}", val.value());
    }
}

I saw this happen:

warning: calls to `push` immediately after creation
  --> src/main.rs:25:5
   |
25 | /     let mut v: Vec<Box<dyn ExampleTrait>> = vec![];
26 | |     
27 | |     #[allow(clippy::vec_init_then_push)]
28 | |     v.push(Box::new(init_object(1)));
   | |_____________________________________^ help: consider using the `vec![]` macro: `let v: Vec<Box<dyn ExampleTrait>> = vec![..];`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#vec_init_then_push
   = note: `#[warn(clippy::vec_init_then_push)]` on by default

I expected to see this happen:

No output, especially since I ignored the lint immediately above.

Version
rustc 1.87.0 (17067e9ac 2025-05-09)
binary: rustc
commit-hash: 17067e9ac6d7ecb70e50f92c1944e545188d2359
commit-date: 2025-05-09
host: x86_64-unknown-linux-gnu
release: 1.87.0
LLVM version: 20.1.1
Additional Labels

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the vec_init_then_push lint implementation and reproduce the report using the linked Rust Playground example. Check how the lint selects its diagnostic span relative to the #[allow] attributes, including the cfg-gated push. Done means the shown allow attributes suppress the warning without changing the intended conditional initialization behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.