Static rustc_lint_defs::builtin::CONST_ITEM_MUTATION
source · pub static CONST_ITEM_MUTATION: &LintExpand 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 a
third-party crate, such as
lazy_staticoronce_cell. - If you are using the [nightly channel], consider the new
lazymodule in the standard library.
- 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
atomictype. - 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
staticis a low-level primitive, requiring unsafe. Typically This should be avoided in preference of something higher-level like one of the above.
- Simple data types can be directly defined and mutated with an