It appears that by moving the LazyCell to a global const, it stops working as expected, and instead recalls the initializer on every access.
My motivation for using LazyCell is to have the cell be a global to avoid repeating an expensive initailization call, and I don't think there is an easy way to accomplish that without making it const.
A const isn't a global variable. It behaves more like the compiler is just copy-pasting the const's value everywhere that it gets used. So your two LazyCell::force(&FOO) lines both create a new copy of FOO.
If you want a global variable, you need to use static. You'll probably need to switch your LazyCell to a LazyLock (or provide some sort of other synchronization on the LazyCell, but just using LazyLock is easiest) in that case.
Did you read the compiler warning? It is explained quite well:
warning: mutation of an interior mutable `const` item with call to `force`
--> src/lib.rs:6:5
|
6 | LazyCell::force(&FOO);
| ^^^^^^^^^^^^^^^^^---^
| |
| `FOO` is a interior mutable `const` item of type `LazyCell<()>`
|
= note: each usage of a `const` item creates a new temporary
= note: only the temporaries and never the original `const FOO` 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 `FOO`, consider making it a `static` item instead
|
4 - const FOO: LazyCell<()> = LazyCell::new(|| eprintln!("init_FOO"));
4 + static FOO: LazyCell<()> = LazyCell::new(|| eprintln!("init_FOO"));
|