Clippy lints / Correctness
Clippy lint · Correctness · checked with Clippy 0.1.99
clippy::uninit_vec: Checks for set_len() call that creates Vec with uninitialized elements. This is commonly caused by calling set_len() right after allocating or reserving a buffer with new(), default(), with_capacity(), or reserve()
What it meansChecks for set_len() call that creates Vec with uninitialized elements. This is commonly caused by calling set_len() right after allocating or reserving a buffer with new(), default(), with_capacity(), or reserve(). It is in the correctness group and denied by default (the build fails).
Does it matter?
It creates a Vec with uninitialized data, which leads to undefined behavior with most safe operations. Notably, uninitialized Vec<u8> must not be used with generic Read. Moreover, calling set_len() on a Vec created with new() or default() creates out-of-bound values that lead to heap memory corruption when used.
Code that is almost certainly wrong. Denied by default: the build fails until you fix it or allow it.
How to fix it
Clippy does not fix this one automatically. Change the code by hand:
Flagged
let mut vec: Vec<u8> = Vec::with_capacity(1000);
unsafe { vec.set_len(1000); }
reader.read(&mut vec); // undefined behavior!
Turn it off, or on
Allow it where it does not fit your code, as narrowly as you can:
On one item
#[allow(clippy::uninit_vec)]
fn my_function() { /* ... */ }Whole crate (Cargo.toml)
[lints.clippy]
uninit_vec = "allow"One run
cargo clippy -- -A clippy::uninit-vecThe [lints] table needs Rust 1.74 or newer. In a workspace, put it under [workspace.lints.clippy] and add [lints] workspace = true to each member.
Clippy's own documentation
What it does
Checks for set_len() call that creates Vec with uninitialized elements.
This is commonly caused by calling set_len() right after allocating or
reserving a buffer with new(), default(), with_capacity(), or reserve().
Why is this bad?
It creates a Vec with uninitialized data, which leads to
undefined behavior with most safe operations. Notably, uninitialized
Vec<u8> must not be used with generic Read.
Moreover, calling set_len() on a Vec created with new() or default()
creates out-of-bound values that lead to heap memory corruption when used.
Known Problems
This lint only checks directly adjacent statements.
Example
let mut vec: Vec<u8> = Vec::with_capacity(1000);
unsafe { vec.set_len(1000); }
reader.read(&mut vec); // undefined behavior!
How to fix?
- Use an initialized buffer:
let mut vec: Vec<u8> = vec![0; 1000]; reader.read(&mut vec); - Wrap the content in
MaybeUninit:let mut vec: Vec<MaybeUninit<T>> = Vec::with_capacity(1000); vec.set_len(1000); // `MaybeUninit` can be uninitialized - If you are on 1.60.0 or later,
Vec::spare_capacity_mut()is available:let mut vec: Vec<u8> = Vec::with_capacity(1000); let remaining = vec.spare_capacity_mut(); // `&mut [MaybeUninit<u8>]` // perform initialization with `remaining` vec.set_len(...); // Safe to call `set_len()` on initialized part
From the Clippy lint list (0.1.99), part of the Rust project, MIT or Apache-2.0. Official entry.
Related lints
- transmute_null_to_fntransmuting a known null pointer into a function pointer
- transmuting_nulltransmuting a known null pointer into a reference
- uninit_assumed_initthis call for this type may be undefined behavior
- unit_cmpChecks for comparisons to unit
- unit_hashDetects ().hash(_)
- unit_return_expecting_ordthis closure returns the unit type which also implements Ord
All 847 Clippy lints · Rust compiler errors · Cargo.toml checker
Up next
Related lintclippy::transmute_null_to_fntransmuting a known null pointer into a function pointerRead it next →Did this answer your question?