# \[pre-RFC\] \[idea\] Detecting const evaluation

**URL:** <https://internals.rust-lang.org/t/pre-rfc-idea-detecting-const-evaluation/11286>\
**Category:** language design\
**Created:** [November 13, 2019, 6:58pm UTC](https://internals.rust-lang.org/t/pre-rfc-idea-detecting-const-evaluation/11286 "2019-11-13T18:58:58Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![CodeSandwich](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/codesandwich/32/3479_2.png) [@CodeSandwich](https://internals.rust-lang.org/u/CodeSandwich)\
**Post date:** [November 13, 2019, 6:58pm UTC](https://internals.rust-lang.org/t/pre-rfc-idea-detecting-const-evaluation/11286/1 "2019-11-13T18:58:58Z")

</div>

I think it could be useful to add support for `#[cfg(const_eval)]`, which would enable code only during const evaluation. Possible uses:

- cleaning up some APIs for runtime while retaining APIs for const evaluation by annotating whole functions
- panicking easily during const evaluation and pushing hard during runtime by annotating blocks of code
- using faster or better algorithms on runtime, that require using non-const functions by annotating blocks of code

Would it be useful? Is it realistically possible to implement? Is it worth writing an RFC?

---

<div class="post-metadata">

**Author:** ![RustyYato](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rustyyato/32/13627_2.png) [@RustyYato](https://internals.rust-lang.org/u/RustyYato)\
**Post date:** [November 13, 2019, 7:00pm UTC](https://internals.rust-lang.org/t/pre-rfc-idea-detecting-const-evaluation/11286/2 "2019-11-13T19:00:24Z")

</div>

This is a great idea! This is similar to C++'s `if constexpr(...) { ... }`

---

<div class="post-metadata">

**Author:** ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)\
**Post date:** [November 13, 2019, 7:11pm UTC](https://internals.rust-lang.org/t/pre-rfc-idea-detecting-const-evaluation/11286/3 "2019-11-13T19:11:24Z")

</div>

I'm hesitant about the idea of allowing constant evaluation to run different code than runtime evaluation; one of the major advantages of `const fn` is running the same code in both contexts.

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [November 13, 2019, 9:12pm UTC](https://internals.rust-lang.org/t/pre-rfc-idea-detecting-const-evaluation/11286/4 "2019-11-13T21:12:58Z")

</div>

In fact, IIRC, it's actually required for soundness that `const fn` always behave the same given the same inputs, whether it's at compile time or at runtime.

On top of this, APIs being available at `const`-evaluation time but not runtime is asking for confusion. Sure, maybe there's a "better" option available for runtime, especially during the transition time until Everything Is Const and Miri Is Unleashed. But why would you ever want it to be an error to inline usages of `const C = make_thing();`?

---

<div class="post-metadata">

**Author:** ![RustyYato](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rustyyato/32/13627_2.png) [@RustyYato](https://internals.rust-lang.org/u/RustyYato)\
**Post date:** [November 13, 2019, 9:53pm UTC](https://internals.rust-lang.org/t/pre-rfc-idea-detecting-const-evaluation/11286/5 "2019-11-13T21:53:44Z")

</div>

I don't think that we will ever make everything const, for example SIMD or other intrinsics that are specialized for optimizations likely won't be made const because that would bloat the compiler too much.

> [@CAD97](#):
>
> In fact, IIRC, it's actually required for soundness that `const fn` always behave the same given the same inputs, whether it's at compile time or at runtime.

I don't think that it is required for soundness that they behave the same at both runtime and compile time. Just that at compile time, they must be deterministic.

* * *

I view this in the same way as trait specialization, the specialization should do the same thing, but it may do it in a different (more efficient) way. Unsafe code is not allowed to assume this, but safe code can.

---

<div class="post-metadata">

**Author:** ![Ixrec](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ixrec/32/6754_2.png) [@Ixrec](https://internals.rust-lang.org/u/Ixrec)\
**Post date:** [November 13, 2019, 10:31pm UTC](https://internals.rust-lang.org/t/pre-rfc-idea-detecting-const-evaluation/11286/6 "2019-11-13T22:31:00Z")

</div>

Oh this is definitely being discussed elsewhere, link time!

> <https://github.com/rust-lang/rust/pull/64683>
>
> Right now, users often need to pick between writing code in a \`const fn\` friendl…y way that can be executed at compile-time, or run-time performance (e.g. code that uses \`core::arch\` intrinsics, inline assembly, etc.). See https://github.com/rust-rfcs/const-eval/issues/7.
> 
> The unsafe \`core::intrinsic::is\_const\_eval\` returns \`true\` if it is evaluated at compile-time and \`false\` otherwise, allowing users to write different code for the different execution contexts of \`const fn\`s.
>  
> There is a PR for this in miri upstream: https://github.com/rust-lang/miri/pull/959

> <https://github.com/rust-lang/const-eval/issues/7>
>
> There are multiple thousand intrinsics for various platforms which users might w…ant to use to speed up their code. It is unrealistic to implement all of these (although a certain subgroup like https://github.com/rust-lang-nursery/stdsimd/blob/05c2f61c384e2097a3a4c648344114fc4ac983be/coresimd/simd\_llvm.rs seem to be manageable.
> 
> @rkruppe and @gnzlbg mentioned (with discomfort) a way to "runtime" detect whether we're in const eval or runtime (which would get completely optimized during codegen). While this would be trivial to implement, it seems very unfortunate to have to resolve to this.
> There's precedent in c++ for such an escape hatch.
> 
> I am not very happy that we even need that many intrinsics outside the libstd and don't quite understand why these can't be optimizations that "just happen". Requiring users to "fix" optimizer deficiencies by giving them multiple thousand ways to gain a few cycles seems suboptimal.
> 
> It's perfectly fine not to support calling e.g. an interrupt register fiddling intrinsic at compile-time (there's no use for doing that, or it could be a noop in many cases). But when/if performance intrinsics are sprinkled onto code used by many users and there's an algorithm that works both at compile-time and runtime and could be optimized, it seems very unfortunate to scrap compile-time evaluability.

My impression from the C++ and Rust discussions so far is that, while this should of course be a niche power user feature, it's basically inevitable that someone will need this as soon as your language offers any form of CTFE plus any target-specific optimization features (SIMD, inline asm, all the other intrinsics), simply because making CTFE emulate all of that target-specific behavior would be even worse than providing `is_const_eval`.

* * *

Tangential nitpick:

> [@RustyYato](#):
>
> This is similar to C++'s `if constexpr(...) { ... }`

That's actually a very different feature. [`std::is_constant_evaluated`](https://en.cppreference.com/w/cpp/types/is_constant_evaluated) is the C++20 feature for distinguishing compile-time from run-time. `if constexpr` is about compiling different code depending on some compile-time value. I believe you can combine them, but most of their use cases don't involve the other.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [February 11, 2020, 10:31pm UTC](https://internals.rust-lang.org/t/pre-rfc-idea-detecting-const-evaluation/11286/7 "2020-02-11T22:31:08Z")

</div>

Closed on February 11, 2020, 10:31pm UTC

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
