1
1
# Constant evaluation
2
+ r[ const-eval]
2
3
4
+ r[ const-eval.general]
3
5
Constant evaluation is the process of computing the result of
4
6
[ expressions] during compilation. Only a subset of all expressions
5
7
can be evaluated at compile-time.
6
8
7
9
## Constant expressions
8
10
11
+ r[ const-eval.const-expr]
12
+
13
+ r[ const-eval.const-expr.general]
9
14
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
+ compile time.
16
+
17
+ r[ const-eval.const-expr.const-context]
18
+ In [ const contexts] ( #const-context ) , these are the only allowed
19
+ expressions, and are always evaluated at compile time.
20
+
21
+ r[ const-eval.const-expr.runtime-context]
22
+ In other places, such as [ let statements] , constant expressions * may* be, but are not guaranteed to be, evaluated at compile time.
23
+
24
+ r[ const-eval.const-expr.error]
25
+ Behaviors such as out of bounds [ array indexing] or [ overflow] are compiler errors if the value
15
26
must be evaluated at compile time (i.e. in const contexts). Otherwise, these
16
27
behaviors are warnings, but will likely panic at run-time.
17
28
29
+
30
+ r[ const-eval.const-expr.list]
18
31
The following expressions are constant expressions, so long as any operands are
19
32
also constant expressions and do not cause any [ ` Drop::drop ` ] [ destructors ] calls
20
33
to be run.
21
34
35
+ r[ const-eval.const-expr.literal]
22
36
* [ Literals] .
37
+
38
+ r[ const-eval.const-expr.parameter]
23
39
* [ Const parameters] .
40
+
41
+ r[ const-eval.const-expr.path-item]
24
42
* [ Paths] to [ functions] and [ constants] .
25
43
Recursively defining constants is not allowed.
44
+
45
+ r[ const-eval.const-expr.path-static]
26
46
* Paths to [ statics] . These are only allowed within the initializer of a static.
47
+
48
+ r[ const-eval.const-expr.tuple]
27
49
* [ Tuple expressions] .
50
+
51
+ r[ const-eval.const-expr.array]
28
52
* [ Array expressions] .
53
+
54
+ r[ const-eval.const-expr.constructor]
29
55
* [ Struct] expressions.
56
+
57
+ r[ const-eval.const-expr.block]
30
58
* [ Block expressions] , including ` unsafe ` and ` const ` blocks.
31
59
* [ let statements] and thus irrefutable [ patterns] , including mutable bindings
32
60
* [ assignment expressions]
33
61
* [ compound assignment expressions]
34
62
* [ expression statements]
63
+
64
+ r[ const-eval.const-expr.field]
35
65
* [ Field] expressions.
66
+
67
+ r[ const-eval.const-expr.index]
36
68
* Index expressions, [ array indexing] or [ slice] with a ` usize ` .
69
+
70
+ r[ const-eval.const-expr.range]
37
71
* [ Range expressions] .
72
+
73
+ r[ const-eval.const-expr.closure]
38
74
* [ Closure expressions] which don't capture variables from the environment.
75
+
76
+ r[ const-eval.const-expr.builtin-arith-logic]
39
77
* Built-in [ negation] , [ arithmetic] , [ logical] , [ comparison] or [ lazy boolean]
40
78
operators used on integer and floating point types, ` bool ` , and ` char ` .
79
+
80
+ r[ const-eval.const-expr.shared-ref]
41
81
* Shared [ borrow] s, except if applied to a type with [ interior mutability] .
82
+
83
+ r[ const-eval.const-expr.deref]
42
84
* The [ dereference operator] except for raw pointers.
85
+
86
+ r[ const-eval.const-expr.group]
43
87
* [ Grouped] expressions.
88
+
89
+ r[ const-eval.const-expr.cast]
44
90
* [ Cast] expressions, except
45
91
* pointer to address casts and
46
92
* function pointer to address casts.
93
+
94
+ r[ const-eval.const-expr.const-fn]
47
95
* Calls of [ const functions] and const methods.
96
+
97
+ r[ const-eval.const-expr.loop]
48
98
* [ loop] , [ while] and [ ` while let ` ] expressions.
99
+
100
+ r[ const-eval.const-expr.if-match]
49
101
* [ if] , [ ` if let ` ] and [ match] expressions.
50
102
51
103
## Const context
52
104
105
+ r[ const-eval.const-context]
106
+
107
+
108
+ r[ const-eval.const-context.general]
53
109
A _ const context_ is one of the following:
54
110
111
+ r[ const-eval.const-context.array-length]
55
112
* [ Array type length expressions]
113
+
114
+ r[ const-eval.const-context.repeat-length]
56
115
* [ Array repeat length expressions] [ array expressions ]
116
+
117
+ r[ const-eval.const-context.init]
57
118
* The initializer of
58
119
* [ constants]
59
120
* [ statics]
60
121
* [ enum discriminants]
122
+
123
+ r[ const-eval.const-context.generic]
61
124
* A [ const generic argument]
125
+
126
+ r[ const-eval.const-context.block]
62
127
* A [ const block]
63
128
64
129
## Const Functions
65
130
66
- A _ const fn_ is a function that one is permitted to call from a const context. Declaring a function
131
+ r[ const-eval.const-fn]
132
+
133
+ r[ const-eval.const-fn.general]
134
+ A _ const fn_ is a function that one is permitted to call from a const context.
135
+
136
+ r[ const-eval.const-fn.usage]
137
+ Declaring a function
67
138
` const ` has no effect on any existing uses, it only restricts the types that arguments and the
68
139
return type may use, as well as prevent various expressions from being used within it. You can freely
69
140
do anything with a const function that you can do with a regular function.
70
141
142
+ r[ const-eval.const-fn.const-context]
71
143
When called from a const context, the function is interpreted by the
72
144
compiler at compile time. The interpretation happens in the
73
145
environment of the compilation target and not the host. So ` usize ` is
74
146
` 32 ` bits if you are compiling against a ` 32 ` bit system, irrelevant
75
147
of whether you are building on a ` 64 ` bit or a ` 32 ` bit system.
76
148
149
+ r[ const-eval.const-fn.restriction]
77
150
Const functions have various restrictions to make sure that they can be
78
151
evaluated at compile-time. It is, for example, not possible to write a random
79
152
number generator as a const function. Calling a const function at compile-time
@@ -83,13 +156,14 @@ floating point operations in extreme situations, then you might get (very
83
156
slightly) different results. It is advisable to not make array lengths and enum
84
157
discriminants depend on floating point computations.
85
158
86
-
159
+ r [ const-expr.const-fn.expr-allowed ]
87
160
Notable features that are allowed in const contexts but not in const functions include:
88
161
89
162
* floating point operations
90
163
* floating point values are treated just like generic parameters without trait bounds beyond
91
164
` Copy ` . So you cannot do anything with them but copy/move them around.
92
165
166
+ r[ const-expr.const-fn.fn-allowed]
93
167
Conversely, the following are possible in a const function, but not in a const context:
94
168
95
169
* Use of generic type and lifetime parameters.
0 commit comments