summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/src/docs/declare_interior_mutable_const.txt
blob: 2801b5ccff8028aaa4dc0c8899e28bf01915d3ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
### What it does
Checks for declaration of `const` items which is interior
mutable (e.g., contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.).

### Why is this bad?
Consts are copied everywhere they are referenced, i.e.,
every time you refer to the const a fresh instance of the `Cell` or `Mutex`
or `AtomicXxxx` will be created, which defeats the whole purpose of using
these types in the first place.

The `const` should better be replaced by a `static` item if a global
variable is wanted, or replaced by a `const fn` if a constructor is wanted.

### Known problems
A "non-constant" const item is a legacy way to supply an
initialized value to downstream `static` items (e.g., the
`std::sync::ONCE_INIT` constant). In this case the use of `const` is legit,
and this lint should be suppressed.

Even though the lint avoids triggering on a constant whose type has enums that have variants
with interior mutability, and its value uses non interior mutable variants (see
[#3962](https://github.com/rust-lang/rust-clippy/issues/3962) and
[#3825](https://github.com/rust-lang/rust-clippy/issues/3825) for examples);
it complains about associated constants without default values only based on its types;
which might not be preferable.
There're other enums plus associated constants cases that the lint cannot handle.

Types that have underlying or potential interior mutability trigger the lint whether
the interior mutable field is used or not. See issues
[#5812](https://github.com/rust-lang/rust-clippy/issues/5812) and

### Example
```
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};

const CONST_ATOM: AtomicUsize = AtomicUsize::new(12);
CONST_ATOM.store(6, SeqCst); // the content of the atomic is unchanged
assert_eq!(CONST_ATOM.load(SeqCst), 12); // because the CONST_ATOM in these lines are distinct
```

Use instead:
```
static STATIC_ATOM: AtomicUsize = AtomicUsize::new(15);
STATIC_ATOM.store(9, SeqCst);
assert_eq!(STATIC_ATOM.load(SeqCst), 9); // use a `static` item to refer to the same instance
```