]> git.proxmox.com Git - rustc.git/blame - src/doc/reference/src/const_eval.md
New upstream version 1.51.0+dfsg1
[rustc.git] / src / doc / reference / src / const_eval.md
CommitLineData
0bf4aa26
XL
1# Constant evaluation
2
3Constant evaluation is the process of computing the result of
4[expressions] during compilation. Only a subset of all expressions
5can be evaluated at compile-time.
6
7## Constant expressions
8
9fa01778
XL
9Certain forms of expressions, called constant expressions, can be evaluated at
10compile time. In [const contexts](#const-context), these are the only allowed
11expressions, and are always evaluated at compile time. In other places, such as
532ac7d7 12[let statements], constant expressions *may*
9fa01778
XL
13be, but are not guaranteed to be, evaluated at compile time. Behaviors such as
14out of bounds [array indexing] or [overflow] are compiler errors if the value
15must be evaluated at compile time (i.e. in const contexts). Otherwise, these
16behaviors are warnings, but will likely panic at run-time.
0bf4aa26
XL
17
18The following expressions are constant expressions, so long as any operands are
19also constant expressions and do not cause any [`Drop::drop`][destructors] calls
48663c56 20to 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
55A _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
66A _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
68return type may use, as well as prevent various expressions from being used within it. You can freely do anything with a const function that
69you can do with a regular function.
70
71When called from a const context, the function is interpreted by the
72compiler at compile time. The interpretation happens in the
73environment of the compilation target and not the host. So `usize` is
74`32` bits if you are compiling against a `32` bit system, irrelevant
75of whether you are building on a `64` bit or a `32` bit system.
76
77Const functions have various restrictions to make sure that they can be
78evaluated at compile-time. It is, for example, not possible to write a random
79number generator as a const function. Calling a const function at compile-time
80will always yield the same result as calling it at runtime, even when called
81multiple times. There's one exception to this rule: if you are doing complex
82floating point operations in extreme situations, then you might get (very
83slightly) different results. It is advisable to not make array lengths and enum
84discriminants depend on floating point computations.
85
3dfed10e
XL
86
87Notable 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
98Conversely, 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