]>
Commit | Line | Data |
---|---|---|
0bf4aa26 XL |
1 | # Constant evaluation |
2 | ||
3 | Constant evaluation is the process of computing the result of | |
4 | [expressions] during compilation. Only a subset of all expressions | |
5 | can be evaluated at compile-time. | |
6 | ||
7 | ## Constant expressions | |
8 | ||
9fa01778 XL |
9 | Certain forms of expressions, called constant expressions, can be evaluated at |
10 | compile time. In [const contexts](#const-context), these are the only allowed | |
11 | expressions, and are always evaluated at compile time. In other places, such as | |
532ac7d7 | 12 | [let statements], constant expressions *may* |
9fa01778 XL |
13 | be, but are not guaranteed to be, evaluated at compile time. Behaviors such as |
14 | out of bounds [array indexing] or [overflow] are compiler errors if the value | |
15 | must be evaluated at compile time (i.e. in const contexts). Otherwise, these | |
16 | behaviors are warnings, but will likely panic at run-time. | |
0bf4aa26 XL |
17 | |
18 | The following expressions are constant expressions, so long as any operands are | |
19 | also constant expressions and do not cause any [`Drop::drop`][destructors] calls | |
48663c56 | 20 | to be run. |
0bf4aa26 XL |
21 | |
22 | * [Literals]. | |
5869c6ff | 23 | * [Const parameters]. |
3dfed10e | 24 | * [Paths] to [functions] and [constants]. |
0bf4aa26 | 25 | Recursively defining constants is not allowed. |
3dfed10e | 26 | * Paths to [statics]. These are only allowed within the initializer of a static. |
0bf4aa26 XL |
27 | * [Tuple expressions]. |
28 | * [Array expressions]. | |
29 | * [Struct] expressions. | |
30 | * [Enum variant] expressions. | |
532ac7d7 | 31 | * [Block expressions], including `unsafe` blocks. |
3dfed10e | 32 | * [let statements] and thus irrefutable [patterns], including mutable bindings |
532ac7d7 | 33 | * [assignment expressions] |
74b04a01 | 34 | * [compound assignment expressions] |
532ac7d7 | 35 | * [expression statements] |
0bf4aa26 XL |
36 | * [Field] expressions. |
37 | * Index expressions, [array indexing] or [slice] with a `usize`. | |
38 | * [Range expressions]. | |
39 | * [Closure expressions] which don't capture variables from the environment. | |
e1599b0c XL |
40 | * Built-in [negation], [arithmetic], [logical], [comparison] or [lazy boolean] |
41 | operators used on integer and floating point types, `bool`, and `char`. | |
0bf4aa26 | 42 | * Shared [borrow]s, except if applied to a type with [interior mutability]. |
3dfed10e | 43 | * The [dereference operator] except for raw pointers. |
0bf4aa26 | 44 | * [Grouped] expressions. |
3dfed10e XL |
45 | * [Cast] expressions, except |
46 | * pointer to address casts, | |
47 | * function pointer to address casts, and | |
48 | * unsizing casts to trait objects. | |
dc9dc135 | 49 | * Calls of [const functions] and const methods. |
3dfed10e XL |
50 | * [loop], [while] and [`while let`] expressions. |
51 | * [if], [`if let`] and [match] expressions. | |
0bf4aa26 XL |
52 | |
53 | ## Const context | |
54 | ||
55 | A _const context_ is one of the following: | |
56 | ||
57 | * [Array type length expressions] | |
3dfed10e | 58 | * [Array repeat length expressions][array expressions] |
0bf4aa26 XL |
59 | * The initializer of |
60 | * [constants] | |
61 | * [statics] | |
62 | * [enum discriminants] | |
63 | ||
3dfed10e XL |
64 | ## Const Functions |
65 | ||
66 | A _const fn_ is a function that one is permitted to call from a const context. Declaring a function | |
67 | `const` has no effect on any existing uses, it only restricts the types that arguments and the | |
1b1a35ee XL |
68 | return type may use, as well as prevent various expressions from being used within it. You can freely do anything with a const function that |
69 | you can do with a regular function. | |
70 | ||
71 | When called from a const context, the function is interpreted by the | |
72 | compiler at compile time. The interpretation happens in the | |
73 | environment of the compilation target and not the host. So `usize` is | |
74 | `32` bits if you are compiling against a `32` bit system, irrelevant | |
75 | of whether you are building on a `64` bit or a `32` bit system. | |
76 | ||
77 | Const functions have various restrictions to make sure that they can be | |
78 | evaluated at compile-time. It is, for example, not possible to write a random | |
79 | number generator as a const function. Calling a const function at compile-time | |
80 | will always yield the same result as calling it at runtime, even when called | |
81 | multiple times. There's one exception to this rule: if you are doing complex | |
82 | floating point operations in extreme situations, then you might get (very | |
83 | slightly) different results. It is advisable to not make array lengths and enum | |
84 | discriminants depend on floating point computations. | |
85 | ||
3dfed10e XL |
86 | |
87 | Notable features that const contexts have, but const fn haven't are: | |
88 | ||
89 | * floating point operations | |
90 | * floating point values are treated just like generic parameters without trait bounds beyond | |
91 | `Copy`. So you cannot do anything with them but copy/move them around. | |
92 | * `dyn Trait` types | |
93 | * generic bounds on generic parameters beyond `Sized` | |
94 | * comparing raw pointers | |
95 | * union field access | |
96 | * [`transmute`] invocations. | |
97 | ||
98 | Conversely, the following are possible in a const function, but not in a const context: | |
99 | ||
100 | * Use of generic parameters. | |
101 | ||
e1599b0c | 102 | [arithmetic]: expressions/operator-expr.md#arithmetic-and-logical-binary-operators |
416331ca XL |
103 | [array expressions]: expressions/array-expr.md |
104 | [array indexing]: expressions/array-expr.md#array-and-slice-indexing-expressions | |
105 | [array indexing]: expressions/array-expr.md#array-and-slice-indexing-expressions | |
106 | [array type length expressions]: types/array.md | |
107 | [assignment expressions]: expressions/operator-expr.md#assignment-expressions | |
74b04a01 | 108 | [compound assignment expressions]: expressions/operator-expr.md#compound-assignment-expressions |
416331ca XL |
109 | [block expressions]: expressions/block-expr.md |
110 | [borrow]: expressions/operator-expr.md#borrow-operators | |
111 | [cast]: expressions/operator-expr.md#type-cast-expressions | |
112 | [closure expressions]: expressions/closure-expr.md | |
113 | [comparison]: expressions/operator-expr.md#comparison-operators | |
114 | [const functions]: items/functions.md#const-functions | |
115 | [constants]: items/constant-items.md | |
5869c6ff | 116 | [Const parameters]: items/generics.md |
416331ca XL |
117 | [dereference operator]: expressions/operator-expr.md#the-dereference-operator |
118 | [destructors]: destructors.md | |
74b04a01 | 119 | [enum discriminants]: items/enumerations.md#custom-discriminant-values-for-fieldless-enumerations |
416331ca XL |
120 | [enum variant]: expressions/enum-variant-expr.md |
121 | [expression statements]: statements.md#expression-statements | |
122 | [expressions]: expressions.md | |
123 | [field]: expressions/field-expr.md | |
124 | [functions]: items/functions.md | |
125 | [grouped]: expressions/grouped-expr.md | |
126 | [interior mutability]: interior-mutability.md | |
3dfed10e XL |
127 | [if]: expressions/if-expr.md#if-expressions |
128 | [`if let`]: expressions/if-expr.md#if-let-expressions | |
416331ca XL |
129 | [lazy boolean]: expressions/operator-expr.md#lazy-boolean-operators |
130 | [let statements]: statements.md#let-statements | |
131 | [literals]: expressions/literal-expr.md | |
e1599b0c | 132 | [logical]: expressions/operator-expr.md#arithmetic-and-logical-binary-operators |
3dfed10e XL |
133 | [loop]: expressions/loop-expr.md#infinite-loops |
134 | [match]: expressions/match-expr.md | |
416331ca XL |
135 | [negation]: expressions/operator-expr.md#negation-operators |
136 | [overflow]: expressions/operator-expr.md#overflow | |
137 | [paths]: expressions/path-expr.md | |
138 | [patterns]: patterns.md | |
139 | [range expressions]: expressions/range-expr.md | |
140 | [slice]: types/slice.md | |
141 | [statics]: items/static-items.md | |
142 | [struct]: expressions/struct-expr.md | |
143 | [tuple expressions]: expressions/tuple-expr.md | |
3dfed10e XL |
144 | [`transmute`]: ../std/mem/fn.transmute.html |
145 | [while]: expressions/loop-expr.md#predicate-loops | |
146 | [`while let`]: expressions/loop-expr.md#predicate-pattern-loops |