# Static rustc_lint_defs::builtin::CONST_ITEM_MUTATION

source ·

    pub static CONST_ITEM_MUTATION: &Lint

Expand description

The `const_item_mutation` lint detects attempts to mutate a `const` item.

#### §Example

    const FOO: [i32; 1] = [0];

    fn main() {
        FOO[0] = 1;
        // This will print "[0]".
        println!("{:?}", FOO);
    }

{{produces}}

#### §Explanation

Trying to directly mutate a `const` item is almost always a mistake. What is happening in the example above is that a temporary copy of the `const` is mutated, but the original `const` is not. Each time you refer to the `const` by name (such as `FOO` in the example above), a separate copy of the value is inlined at that location.

This lint checks for writing directly to a field (`FOO.field = some_value`) or array entry (`FOO[0] = val`), or taking a mutable reference to the const item (`&mut FOO`), including through an autoderef (`FOO.some_mut_self_method()`).

There are various alternatives depending on what you are trying to accomplish:

- First, always reconsider using mutable globals, as they can be difficult to use correctly, and can make the code more difficult to use or understand.
- If you are trying to perform a one-time initialization of a global:
  - If the value can be computed at compile-time, consider using const-compatible values (see Constant Evaluation).
  - For more complex single-initialization cases, consider using `std::sync::LazyLock`.
- If you truly need a mutable global, consider using a `static`, which has a variety of options:
  - Simple data types can be directly defined and mutated with an `atomic` type.
  - More complex types can be placed in a synchronization primitive like a `Mutex`, which can be initialized with one of the options listed above.
  - A mutable `static` is a low-level primitive, requiring unsafe. Typically This should be avoided in preference of something higher-level like one of the above.