Summary

If the constant

定数
evaluator encounters erronous code during the evaluation
評価
of an expression
that is not part of a true constant
定数
evaluation
評価
context
文脈、背景
a warning must be emitted and the expression
needs to be translated normally.

Definition
定義
of constant
定数
evaluation
評価
context
文脈、背景

There are exactly

正確に
five places where an expression
needs to be constant.
定数

  • the initializer of a constant
    定数
    const foo: ty = EXPR or static foo: ty = EXPR
  • the size of an array
    配列
    [T; EXPR]
  • the length of a repeat expression
    [VAL; LEN_EXPR]
  • C-Like enum variant discriminant values
  • patterns

In the future the body of const fn might also be interpreted

解釈する
as a constant
定数
evaluation
評価
context.
文脈、背景

Any other expression

might still be constant
定数
evaluated,
評価する(される)
but it could just as well be compiled normally and executed
実行(する)
at runtime.

Motivation

Expressions

are const-evaluated even when they are not in a const environment.
環境

For example

#![allow(unused)] fn main() { fn blub<T>(t: T) -> T { t } let x = 5 << blub(42); }

will not cause

起こす
a compiler error currently, while 5 << 42 will. If the constant
定数
evaluator gets smart enough, it will be able to const evaluate the blub function. This would be a breaking change, since the code would not compile anymore. (this occurred
起こる
in https://github.com/rust-lang/rust/pull/26848).

Detailed design
設計(する)

The PRs https://github.com/rust-lang/rust/pull/26848 and https://github.com/rust-lang/rust/pull/25570 will be setting

セットする、集合
a precedent for warning about such situations (WIP, not pushed yet).

When the constant

定数
evaluator fails while evaluating
評価する(される)
a normal expression,
a warning will be emitted and normal translation needs to be resumed.

Drawbacks

None, if we don't do anything, the const evaluator cannot get much smarter.

Alternatives
代わりのもの、選択肢

allow breaking changes

Let the compiler error on things that will unconditionally panic at runtime.

insert
挿入する
an unconditional panic instead of generating
生成する
regular
普通の、正規の
code

GNAT (an Ada compiler) does this already:

procedure Hello is Var: Integer range 15 .. 20 := 21; begin null; end Hello;

The anonymous

無名
subtype Integer range 15 .. 20 only accepts
受け付ける、受理する
values in [15, 20]. This knowledge is used by GNAT to emit the following warning during compilation:

warning: value not in range of subtype of "Standard.Integer" defined at line 2 warning: "Constraint_Error" will be raised at run time

I don't have a GNAT with -emit-llvm handy, but here's the asm with -O0:

.cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl $2, %esi movl $.LC0, %edi movl $0, %eax call __gnat_rcheck_CE_Range_Check

Unresolved questions

Const-eval the body of const fn that are never used in a constant
定数
environment
環境

Currently a const fn that is called

呼び出し
in non-const code is treated
取り扱う
just like a normal function.

In case there is a statically known erroneous

誤った、間違いの
situation in the body of the function, the compiler should raise an error, even if the function is never called.
呼び出し

The same applies

適用する
to unused associated constants.
定数