mirror of
https://github.com/rust-lang/rust.git
synced 2025-11-23 07:27:37 +00:00
Warn against calls which mutate an interior mutable `const`-item
## `const_item_interior_mutations`
~~`interior_mutable_const_item_mutations`~~
~~`suspicious_mutation_of_interior_mutable_consts`~~
*warn-by-default*
The `const_item_interior_mutations` lint checks for calls which mutates an interior mutable const-item.
### Example
```rust
use std::sync::Once;
const INIT: Once = Once::new(); // using `INIT` will always create a temporary and
// never modify it-self on use, should be a `static`
// instead for shared use
fn init() {
INIT.call_once(|| {
println!("Once::call_once first call");
});
}
```
```text
warning: mutation of an interior mutable `const` item with call to `call_once`
--> a.rs:11:5
|
11 | INIT.call_once(|| {
| ^---
| |
| _____`INIT` is a interior mutable `const` item of type `std::sync::Once`
| |
12 | | println!("Once::call_once first call");
13 | | });
| |______^
|
= note: each usage of a `const` item creates a new temporary
= note: only the temporaries and never the original `const INIT` will be modified
= help: for more details on interior mutability see <https://doc.rust-lang.org/reference/interior-mutability.html>
= note: `#[warn(const_item_interior_mutations)]` on by default
help: for a shared instance of `INIT`, consider making it a `static` item instead
|
6 - const INIT: Once = Once::new(); // using `INIT` will always create a temporary and
6 + static INIT: Once = Once::new(); // using `INIT` will always create a temporary and
|
```
### Explanation
Calling a method which mutates an interior mutable type has no effect as const-item are essentially inlined wherever they are used, meaning that they are copied directly into the relevant context when used rendering modification through interior mutability ineffective across usage of that const-item.
The current implementation of this lint only warns on significant `std` and `core` interior mutable types, like `Once`, `AtomicI32`, ... this is done out of prudence and may be extended in the future.
----
This PR is an targeted alternative to rust-lang/rust#132146. It avoids false-positives by adding an internal-only attribute `#[rustc_should_not_be_called_on_const_items]` on methods and functions that mutates an interior mutale type through a shared reference (mutable refrences are already linted by the `const_item_mutation` lint).
It should also be noted that this is NOT an uplift of the more general [`clippy::borrow_interior_mutable_const`](https://rust-lang.github.io/rust-clippy/master/index.html#/borrow_interior_mutable_const) lint, which is a much more general lint regarding borrow of interior mutable types, but has false-positives that are completly avoided by this lint.
A simple [GitHub Search](https://github.com/search?q=lang%3Arust+%2F%28%3F-i%29const+%5Ba-zA-Z0-9_%5D*%3A+Once%2F&type=code) reveals many instance where the user probably wanted to use a `static`-item instead.
----
````@rustbot```` labels +I-lang-nominated +T-lang
cc ````@traviscross````
r? compiler
Fixes [IRLO - Forbidding creation of constant mutexes, etc](https://internals.rust-lang.org/t/forbidding-creation-of-constant-mutexes-etc/19005)
Fixes https://github.com/rust-lang/rust/issues/132028
Fixes https://github.com/rust-lang/rust/issues/40543