Do `const fn`s always be inlined?

I've searched but seems no related discussion.

No, at runtime const functions behave the same as regular functions. The only difference is during const evaluation.

How to guarantee a const fn call is const evaluated?

The only was is to use it in a place where const evaluation is the only option like inside the definition of a static or as a const generic argument.

In the future, inline const { ... } blocks will be a way to force that.

9 Likes

Will there ever be a const fn is_constant_evaluated() -> bool?

No, that would be unsound. There already is the internal function

but the safety condition is that the result must be the same in either case; it is only a way to provide better implementations for the two cases, not to change visaible behavior.

This is related to the reason why const evaluation is currently so restricted: const fns have to give the same answer no matter when they are invoked, so expanding the set of things that const fns can do requires careful consideration.

That would not be so useful, used with a regular if, because both branches would still be constrained to only contain const-evaluatable code. You’d need some sort of a "const if" (like if consteval in C++23) that would essentially monomorphize separate compiletime and runtime versions of the function.

C++ const eval

Earlier, C++20 introduced if constexpr and is_const_evaluated() which, confusingly, cannot be put together to express what one would intuitively assume, which lead to the addition of if consteval… honestly, it’s a mess.

2 Likes

Likely yes, albeit with a different interface. Currently Rust language has a restriction that const functions have to behave exactly the same way in const context and non-const context out of an abundance of caution. However, it's likely that in the future this restriction would be removed to permit floating point arithmetic in const contexts (as it's possible that floating point math would behave differently at compile time and runtime). There is a draft RFC for removing this particular restriction: rfcs/0000-relax-const-restrictions.md at relax_const_restrictions · Nilstrieb/rfcs · GitHub.

Nightly Rust has core::intrinsics::const_eval_select function which can be used to select different code paths depending on whether the code is executed in const context or at runtime. Note however this is not going to be the interface that is going to be stabilized (in particular because it's in core::intrinsics).

1 Like

I believe in C++, they do:

if (is_constant_evaluated()) {
// primitive C++ dialect and slow algorithm
} else {
// full C++ dialect and fast algorithm
}

Note that in the future, this restriction that they must behavior the same will probably be relaxed, making it possible to add a safe const_eval_select.

I am currently using { const C: SomeType = const_fn(); C } instead and it is working well.

1 Like

Probably yes, an RFC is currently under construction that would pave the way towards that.

This requirement exists out of an abundance of caution and to avoid making any lasting decisions by adding the intrinsic. If the aforementioned RFC gets passed, then the intrinsic documentation will be adjusted accordingly.

7 Likes