In Rust, const
functions are quite limited in what code can be put inside them, e.g. for
loops aren't allowed, nor are any non-const
function calls. I understand that there are issues with heap allocations in const
functions, but why is it that for example the below code isn't valid:
fn add(a: u8, b: u8) -> u8 {
a + b
}
const A: u8 = add(1, 2);
This would be valid if add
was declared as a const
function.
- Why can't the Rust compiler detect that this is valid?
- Why are
const
functions necessary at all? - Why aren't even
for
loops allowed inside them (even though whileloop
s are)?
Constant functions are declared
const
to tell the compiler that this function is allowed to be called from aconst
context. Const-eval is done in a tool calledmiri
. Miri is not capable of evaluating all expressions, and soconst
functions are pretty limited. There is a tracking issue of extensions that have been accepted and there is active work going on to make them const-compatible.While technically possible, the Rust team decided against it. The primary reason being semantic versioning issues. Changing the body of a function, without changing the signature, could make that function no longer const-compatible and break uses in a const-context.
const fn
is a contract, and breaking that contract is an explicit breaking change.As to why
for
loops aren't allowed, they technically are. The only problem is that theIterator::next
method is notconst
, meaning that not some iterators may perform operations that are not const-evaluatable. Until a language construct that allows trait methods to be marked asconst
, or the ability to putconst
bounds, you will have to stick to regularloop
s.