]> git.proxmox.com Git - rustc.git/blob - src/doc/reference/src/const_eval.md
New upstream version 1.48.0~beta.8+dfsg1
[rustc.git] / src / doc / reference / src / const_eval.md
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
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
12 [let statements], constant expressions *may*
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.
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
20 to be run.
21
22 * [Literals].
23 * [Paths] to [functions] and [constants].
24 Recursively defining constants is not allowed.
25 * Paths to [statics]. These are only allowed within the initializer of a static.
26 * [Tuple expressions].
27 * [Array expressions].
28 * [Struct] expressions.
29 * [Enum variant] expressions.
30 * [Block expressions], including `unsafe` blocks.
31 * [let statements] and thus irrefutable [patterns], including mutable bindings
32 * [assignment expressions]
33 * [compound assignment expressions]
34 * [expression statements]
35 * [Field] expressions.
36 * Index expressions, [array indexing] or [slice] with a `usize`.
37 * [Range expressions].
38 * [Closure expressions] which don't capture variables from the environment.
39 * Built-in [negation], [arithmetic], [logical], [comparison] or [lazy boolean]
40 operators used on integer and floating point types, `bool`, and `char`.
41 * Shared [borrow]s, except if applied to a type with [interior mutability].
42 * The [dereference operator] except for raw pointers.
43 * [Grouped] expressions.
44 * [Cast] expressions, except
45 * pointer to address casts,
46 * function pointer to address casts, and
47 * unsizing casts to trait objects.
48 * Calls of [const functions] and const methods.
49 * [loop], [while] and [`while let`] expressions.
50 * [if], [`if let`] and [match] expressions.
51
52 ## Const context
53
54 A _const context_ is one of the following:
55
56 * [Array type length expressions]
57 * [Array repeat length expressions][array expressions]
58 * The initializer of
59 * [constants]
60 * [statics]
61 * [enum discriminants]
62
63 ## Const Functions
64
65 A _const fn_ is a function that one is permitted to call from a const context. Declaring a function
66 `const` has no effect on any existing uses, it only restricts the types that arguments and the
67 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
68 you can do with a regular function.
69
70 When called from a const context, the function is interpreted by the
71 compiler at compile time. The interpretation happens in the
72 environment of the compilation target and not the host. So `usize` is
73 `32` bits if you are compiling against a `32` bit system, irrelevant
74 of whether you are building on a `64` bit or a `32` bit system.
75
76 Const functions have various restrictions to make sure that they can be
77 evaluated at compile-time. It is, for example, not possible to write a random
78 number generator as a const function. Calling a const function at compile-time
79 will always yield the same result as calling it at runtime, even when called
80 multiple times. There's one exception to this rule: if you are doing complex
81 floating point operations in extreme situations, then you might get (very
82 slightly) different results. It is advisable to not make array lengths and enum
83 discriminants depend on floating point computations.
84
85
86 Notable features that const contexts have, but const fn haven't are:
87
88 * floating point operations
89 * floating point values are treated just like generic parameters without trait bounds beyond
90 `Copy`. So you cannot do anything with them but copy/move them around.
91 * `dyn Trait` types
92 * generic bounds on generic parameters beyond `Sized`
93 * comparing raw pointers
94 * union field access
95 * [`transmute`] invocations.
96
97 Conversely, the following are possible in a const function, but not in a const context:
98
99 * Use of generic parameters.
100
101 [arithmetic]: expressions/operator-expr.md#arithmetic-and-logical-binary-operators
102 [array expressions]: expressions/array-expr.md
103 [array indexing]: expressions/array-expr.md#array-and-slice-indexing-expressions
104 [array indexing]: expressions/array-expr.md#array-and-slice-indexing-expressions
105 [array type length expressions]: types/array.md
106 [assignment expressions]: expressions/operator-expr.md#assignment-expressions
107 [compound assignment expressions]: expressions/operator-expr.md#compound-assignment-expressions
108 [block expressions]: expressions/block-expr.md
109 [borrow]: expressions/operator-expr.md#borrow-operators
110 [cast]: expressions/operator-expr.md#type-cast-expressions
111 [closure expressions]: expressions/closure-expr.md
112 [comparison]: expressions/operator-expr.md#comparison-operators
113 [const functions]: items/functions.md#const-functions
114 [constants]: items/constant-items.md
115 [dereference operator]: expressions/operator-expr.md#the-dereference-operator
116 [destructors]: destructors.md
117 [enum discriminants]: items/enumerations.md#custom-discriminant-values-for-fieldless-enumerations
118 [enum variant]: expressions/enum-variant-expr.md
119 [expression statements]: statements.md#expression-statements
120 [expressions]: expressions.md
121 [field]: expressions/field-expr.md
122 [functions]: items/functions.md
123 [grouped]: expressions/grouped-expr.md
124 [interior mutability]: interior-mutability.md
125 [if]: expressions/if-expr.md#if-expressions
126 [`if let`]: expressions/if-expr.md#if-let-expressions
127 [lazy boolean]: expressions/operator-expr.md#lazy-boolean-operators
128 [let statements]: statements.md#let-statements
129 [literals]: expressions/literal-expr.md
130 [logical]: expressions/operator-expr.md#arithmetic-and-logical-binary-operators
131 [loop]: expressions/loop-expr.md#infinite-loops
132 [match]: expressions/match-expr.md
133 [negation]: expressions/operator-expr.md#negation-operators
134 [overflow]: expressions/operator-expr.md#overflow
135 [paths]: expressions/path-expr.md
136 [patterns]: patterns.md
137 [range expressions]: expressions/range-expr.md
138 [slice]: types/slice.md
139 [statics]: items/static-items.md
140 [struct]: expressions/struct-expr.md
141 [tuple expressions]: expressions/tuple-expr.md
142 [`transmute`]: ../std/mem/fn.transmute.html
143 [while]: expressions/loop-expr.md#predicate-loops
144 [`while let`]: expressions/loop-expr.md#predicate-pattern-loops