]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/src/docs/uninit_vec.txt
Rollup merge of #101118 - devnexen:fs_getmode_bsd, r=Mark-Simulacrum
[rust.git] / src / tools / clippy / src / docs / uninit_vec.txt
1 ### What it does
2 Checks for `set_len()` call that creates `Vec` with uninitialized elements.
3 This is commonly caused by calling `set_len()` right after allocating or
4 reserving a buffer with `new()`, `default()`, `with_capacity()`, or `reserve()`.
5
6 ### Why is this bad?
7 It creates a `Vec` with uninitialized data, which leads to
8 undefined behavior with most safe operations. Notably, uninitialized
9 `Vec<u8>` must not be used with generic `Read`.
10
11 Moreover, calling `set_len()` on a `Vec` created with `new()` or `default()`
12 creates out-of-bound values that lead to heap memory corruption when used.
13
14 ### Known Problems
15 This lint only checks directly adjacent statements.
16
17 ### Example
18 ```
19 let mut vec: Vec<u8> = Vec::with_capacity(1000);
20 unsafe { vec.set_len(1000); }
21 reader.read(&mut vec); // undefined behavior!
22 ```
23
24 ### How to fix?
25 1. Use an initialized buffer:
26    ```rust,ignore
27    let mut vec: Vec<u8> = vec![0; 1000];
28    reader.read(&mut vec);
29    ```
30 2. Wrap the content in `MaybeUninit`:
31    ```rust,ignore
32    let mut vec: Vec<MaybeUninit<T>> = Vec::with_capacity(1000);
33    vec.set_len(1000);  // `MaybeUninit` can be uninitialized
34    ```
35 3. If you are on 1.60.0 or later, `Vec::spare_capacity_mut()` is available:
36    ```rust,ignore
37    let mut vec: Vec<u8> = Vec::with_capacity(1000);
38    let remaining = vec.spare_capacity_mut();  // `&mut [MaybeUninit<u8>]`
39    // perform initialization with `remaining`
40    vec.set_len(...);  // Safe to call `set_len()` on initialized part
41    ```