8
8
>   ;  ;   ;  ; [ _ BlockExpression_ ]
9
9
>
10
10
> _ FunctionFront_ :\
11
- >   ;  ; ` unsafe ` <sup >?</sup > (` extern ` _ Abi_ <sup >?</sup >)<sup >?</sup >
11
+ >   ;  ; ` const ` < sup >?</ sup > ` unsafe ` <sup >?</sup > (` extern ` _ Abi_ <sup >?</sup >)<sup >?</sup >
12
12
>
13
13
> _ Abi_ :\
14
14
>   ;  ; [ STRING_LITERAL] | [ RAW_STRING_LITERAL]
@@ -160,6 +160,59 @@ attributes], [`must_use`], [the procedural macro attributes], [the testing
160
160
attributes] , and [ the optimization hint
161
161
attributes] .
162
162
163
+ ## Const functions
164
+
165
+ Functions can be ` const ` , meaning they can be called from within
166
+ [ const contexts] . When called from a const context, the function is interpreted
167
+ by the compiler at compile time. The interpretation happens in the environment
168
+ of the compilation target and not the host. So ` usize ` is ` 32 ` bits if you are
169
+ compiling against a ` 32 ` bit system, irrelevant of whether you are building on
170
+ a ` 64 ` bit or a ` 32 ` bit system.
171
+
172
+ If a const function is called outside a "const context", it is indistinguishable
173
+ from any other function. You can freely do anything with a const function that
174
+ you can do with a regular function.
175
+
176
+ const functions have various restrictions to makes sure that you cannot define a
177
+ const function that can't be evaluated at compile-time. It is, for example, not
178
+ possible to write a random number generator as a const function. Calling a
179
+ const function at compile-time will always yield the same result as calling it at
180
+ runtime, even when called multiple times. There's one exception to this rule:
181
+ if you are doing complex floating point operations in extreme situations,
182
+ then you might get (very slightly) different results.
183
+ It is adviseable to not make array lengths and enum discriminants depend
184
+ on floating point computations.
185
+
186
+ Exhaustive list of permitted structures in const functions:
187
+
188
+ > ** Note** : this list is more restrictive than what you can write in
189
+ > regular constants
190
+
191
+ * type parameters where the parameters only have any [ trait bounds]
192
+ of the following kind:
193
+ * lifetimes
194
+ * ` Sized ` or [ ` ?Sized ` ]
195
+
196
+ This means that ` <T: 'a + ?Sized> ` , ` <T: 'b + Sized> ` and ` <T> `
197
+ are all permitted.
198
+
199
+ This rule also applies to type parameters of impl blocks that
200
+ contain const methods
201
+
202
+ * arithmetic and comparison operators on integers
203
+ * all boolean operators except for ` && ` and ` || ` which are banned since
204
+ they are short-circuiting.
205
+ * any kind of aggregate constructor (array, ` struct ` , ` enum ` , tuple, ...)
206
+ * calls to other * safe* const functions (whether by function call or method call)
207
+ * index expressions on arrays and slices
208
+ * field accesses on structs and tuples
209
+ * reading from constants (but not statics, not even taking a reference to a static)
210
+ * ` & ` and ` * ` (only dereferencing of references, not raw pointers)
211
+ * casts except for raw pointer to integer casts
212
+ * ` const unsafe fn ` is allowed, but the body must consist of safe operations
213
+ only and you won't be able to call the ` const unsafe fn ` from within another
214
+ const function even if you use ` unsafe `
215
+
163
216
[ IDENTIFIER ] : identifiers.html
164
217
[ RAW_STRING_LITERAL ] : tokens.html#raw-string-literals
165
218
[ STRING_LITERAL ] : tokens.html#string-literals
@@ -170,6 +223,7 @@ attributes].
170
223
[ _Statement_ ] : statements.html
171
224
[ _Type_ ] : types.html
172
225
[ _WhereClause_ ] : items/generics.html#where-clauses
226
+ [ const contexts ] : const_eval.html
173
227
[ external blocks ] : items/external-blocks.html
174
228
[ path ] : paths.html
175
229
[ block ] : expressions/block-expr.html
@@ -187,3 +241,5 @@ attributes].
187
241
[ `doc` ] : attributes.html#documentation
188
242
[ `must_use` ] : attributes.html#must_use
189
243
[ patterns ] : patterns.html
244
+ [ `?Sized` ] : trait-bounds.html#sized
245
+ [ trait bounds ] : trait-bounds.html
0 commit comments