Why can consts not refer to statics?

I have been hitting this limitation recently and wanted to understand it. I have read the issue below, but I still don't understand the reasoning.

The example of a problem is given in the first comment:

static FOO: AtomicUsize = AtomicUsize::new(42);

// hides the static behind a regular reference
const BAR: &AtomicUsize = &FOO;
const fn bar() -> usize {
    BAR.swap(99, Ordering::Relaxed)
}

This seems like it should be perfectly correct, because the const just holds an address to FOO (which is static), so it would be no different then calling swap on FOO directly. What am I missing here?

There was a previous discussion on this in the forum, but no one seemed to know the reason. The best guess is because constant expansion happens before static's receive an address, so that seems like a purely mechanical limitation. But the Github issue seems to suggest that it is more fundamental then that.

2 Likes

const fn are meant to produce, well, constant (and deterministic) results.

Const functions have various restrictions to make sure that they can be evaluated at compile-time. It is, for example, not possible to write a random number generator as a const function. Calling a const function at compile-time will always yield the same result as calling it at runtime, even when called multiple times.

bar produces different results depending on when it is called. Also for example, a program containing

// Potentially in different modules etc
const A: usize = bar();
const B: usize = bar();

the values of A and B will vary depending on which the compiler evaluates first. (Or perhaps the same if only one module gets recompiled, say.)

1 Like

Oh I see the issue. swap is not a const function. But that seems completely unrelated to consts referencing statics. Calling that inside bar would be disallowed even without statics.