Skip to content

Commit 4e7bb21

Browse files
authored
Address review comments
1 parent 41cbeb0 commit 4e7bb21

File tree

1 file changed

+50
-26
lines changed

1 file changed

+50
-26
lines changed

src/items/functions.md

Lines changed: 50 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -162,35 +162,57 @@ attributes].
162162

163163
## Const functions
164164

165-
Functions can be `const`, meaning they can be called from within array length expressions and the initializer of constants, statics and enum discriminants. When called from such a so-called "const context", the function is interpreted by the compiler at compile time. The interpretation happens in the environment of the compilation target and not the host. So `usize` is `32` bits if you are compiling against a `32` bit system, irrelevant of whether you are building on a `64` bit or a `32` bit system.
166-
167-
If a `const fn` is called outside a "const context", it is indistinguishable from any other function. You can freely do anything with a `const fn` that you can do with a regular fn.
168-
169-
`const fn`s have various restrictions to makes sure that you cannot define a `const fn` that can't be evaluated at compile-time. You will, for example, never be able to write a random number generator as a const fn. Calling a const fn at compile-time will always yield the same result as calling it at runtime, even if you call it multiple times. There's one exception to this rule: if you are doing complex floating point operations in extreme situations, then you might get (very slightly) different results. It is adviseable to not make array lengths and enum discriminants depend on floating point computations.
165+
Functions can be `const`, meaning they can be called from within array length
166+
expressions and the initializer of constants, statics and enum discriminants.
167+
When called from such a so-called "const context", the function is interpreted
168+
by the compiler at compile time. The interpretation happens in the environment
169+
of the compilation target and not the host. So `usize` is `32` bits if you are
170+
compiling against a `32` bit system, irrelevant of whether you are building on
171+
a `64` bit or a `32` bit system.
172+
173+
If a `const fn` is called outside a "const context", it is indistinguishable
174+
from any other function. You can freely do anything with a `const fn` that
175+
you can do with a regular function.
176+
177+
`const fn`s have various restrictions to makes sure that you cannot define a
178+
`const fn` that can't be evaluated at compile-time. It is, for example, not
179+
possible to write a random number generator as a const fn. Calling a
180+
const fn at compile-time will always yield the same result as calling it at
181+
runtime, even when called multiple times. There's one exception to this rule:
182+
if you are doing complex floating point operations in extreme situations,
183+
then you might get (very slightly) different results.
184+
It is adviseable to not make array lengths and enum discriminants depend
185+
on floating point computations.
170186

171187
Exhaustive list of permitted structures in `const fn`:
172188

173-
1. type parameters where the parameters only have any of the following as part of their bounds (either on `where` or directly on the parameters):
174-
1. lifetimes
175-
2. `Sized`
176-
177-
This means that `<T: 'a + ?Sized>`, `<T: 'b + Sized>` and `<T>` are all permitted.
178-
Note that `?Sized` is the absence of a constraint when bounds have been fully elaborated
179-
which includes adding implicit `Sized` bounds.
180-
This entails that permitting `Sized` + lifetimes allows the above examples.
181-
182-
This rule also applies to type parameters of items that contain `const fn`s.
183-
184-
2. arithmetic and comparison operators on integers
185-
3. all boolean operators except for `&&` and `||` which are banned since they are short-circuiting.
186-
4. any kind of aggregate constructor (array, `struct`, `enum`, tuple, ...)
187-
5. calls to other *safe* `const fn`s (methods and functions)
188-
6. index operations on arrays and slices
189-
7. field accesses on structs and tuples
190-
8. reading from constants (but not statics, not even taking a reference to a static)
191-
9. `&` and `*` (only dereferencing of references, not raw pointers)
192-
10. casts except for raw pointer to integer casts
193-
11. `const unsafe fn` is allowed, but the body must consist of safe operations only and you won't be able to call the `const unsafe fn` from within another `const fn` even if you use `unsafe`
189+
> **Note**: this list is more restrictive than what you can write in
190+
regular constants
191+
192+
* type parameters where the parameters only have any [trait bounds]
193+
of the following kind:
194+
* lifetimes
195+
* `Sized` or [`?Sized`]
196+
197+
This means that `<T: 'a + ?Sized>`, `<T: 'b + Sized>` and `<T>`
198+
are all permitted.
199+
200+
This rule also applies to type parameters of impl blocks that
201+
contain `const fn` methods
202+
203+
* arithmetic and comparison operators on integers
204+
* all boolean operators except for `&&` and `||` which are banned since
205+
they are short-circuiting.
206+
* any kind of aggregate constructor (array, `struct`, `enum`, tuple, ...)
207+
* calls to other *safe* `const fn`s (whether by function call or method call)
208+
* index expressions on arrays and slices
209+
* field accesses on structs and tuples
210+
* reading from constants (but not statics, not even taking a reference to a static)
211+
* `&` and `*` (only dereferencing of references, not raw pointers)
212+
* casts except for raw pointer to integer casts
213+
* `const unsafe fn` is allowed, but the body must consist of safe operations
214+
only and you won't be able to call the `const unsafe fn` from within another
215+
`const fn` even if you use `unsafe`
194216

195217
[IDENTIFIER]: identifiers.html
196218
[RAW_STRING_LITERAL]: tokens.html#raw-string-literals
@@ -219,3 +241,5 @@ Exhaustive list of permitted structures in `const fn`:
219241
[`doc`]: attributes.html#documentation
220242
[`must_use`]: attributes.html#must_use
221243
[patterns]: patterns.html
244+
[`?Sized`]: trait-bounds.html#sized
245+
[trait bounds]: trait-bounds.html

0 commit comments

Comments
 (0)