Skip to content

Commit d39911d

Browse files
Merge pull request #447 from Havvy/const-function
Const function
2 parents 2331d91 + 4e9fba7 commit d39911d

File tree

7 files changed

+67
-67
lines changed

7 files changed

+67
-67
lines changed

src/const_eval.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,15 @@ to be ran.
3838
* [Grouped] expressions.
3939
* [Cast] expressions, except pointer to address and
4040
function pointer to address casts.
41-
* calls of const functions and const methods
41+
* Calls of const functions and const methods
4242

4343
## Const context
4444

4545
A _const context_ is one of the following:
4646

47-
* [array type length expressions]
48-
* repeat expression length expessions
49-
* the initializer of
47+
* [Array type length expressions]
48+
* Repeat expression length expessions
49+
* The initializer of
5050
* [constants]
5151
* [statics]
5252
* [enum discriminants]

src/expressions/array-expr.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ order they are written.
1515

1616
Alternatively there can be exactly two expressions inside the brackets,
1717
separated by a semi-colon. The expression after the `;` must be a have type
18-
`usize` and be a [constant expression](expressions.html#constant-expressions),
18+
`usize` and be a [constant expression],
1919
such as a [literal](tokens.html#literals) or a [constant
2020
item](items/constant-items.html). `[a; b]` creates an array containing `b`
2121
copies of the value of `a`. If the expression after the semi-colon has a value

src/items/associated-items.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ let _: f64 = f64::from_i32(42);
8080
### Methods
8181

8282
> _Method_ :\
83-
> &nbsp;&nbsp; [_FunctionFront_] `fn` [IDENTIFIER]&nbsp;[_Generics_]<sup>?</sup>\
83+
> &nbsp;&nbsp; [_FunctionQualifiers_] `fn` [IDENTIFIER]&nbsp;[_Generics_]<sup>?</sup>\
8484
> &nbsp;&nbsp; &nbsp;&nbsp; `(` _SelfParam_ (`,` [_FunctionParam_])<sup>\*</sup> `,`<sup>?</sup> `)`\
8585
> &nbsp;&nbsp; &nbsp;&nbsp; [_FunctionReturnType_]<sup>?</sup> [_WhereClause_]<sup>?</sup>\
8686
> &nbsp;&nbsp; &nbsp;&nbsp; [_BlockExpression_]
@@ -287,8 +287,8 @@ fn main() {
287287
```
288288

289289
[_BlockExpression_]: expressions/block-expr.html
290-
[_FunctionFront_]: items/functions.html
291290
[_FunctionParam_]: items/functions.html
291+
[_FunctionQualifiers_]: items/functions.html
292292
[_FunctionReturnType_]: items/functions.html
293293
[_Generics_]: items/generics.html
294294
[_Lifetime_]: trait-bounds.html

src/items/enumerations.md

+5-4
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ then the discriminant can be directly chosen and accessed.
6868

6969
These enumerations can be cast to integer types with the `as` operator by a
7070
[numeric cast]. The enumeration can optionally specify which integer each
71-
discriminant gets by following the variant name with `=` and then an integer
72-
literal. If the first variant in the declaration is unspecified, then it is set
73-
to zero. For every unspecified discriminant, it is set to one higher than the
74-
previous variant in the declaration.
71+
discriminant gets by following the variant name with `=` followed by a [constant
72+
expression]. If the first variant in the declaration is unspecified, then it is
73+
set to zero. For every other unspecified discriminant, it is set to one higher
74+
than the previous variant in the declaration.
7575

7676
```rust
7777
enum Foo {
@@ -141,6 +141,7 @@ enum ZeroVariants {}
141141
[`mem::discriminant`]: ../std/mem/fn.discriminant.html
142142
[numeric cast]: expressions/operator-expr.html#semantics
143143
[`repr` attribute]: attributes.html#ffi-attributes
144+
[constant expression]: const_eval.html#constant-expressions
144145
[default representation]: type-layout.html#the-default-representation
145146
[primitive representation]: type-layout.html#primitive-representations
146147
[`C` representation]: type-layout.html#the-c-representation

src/items/functions.md

+50-51
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
> **<sup>Syntax</sup>**\
44
> _Function_ :\
5-
> &nbsp;&nbsp; _FunctionFront_ `fn` [IDENTIFIER]&nbsp;[_Generics_]<sup>?</sup>\
5+
> &nbsp;&nbsp; _FunctionQualifiers_ `fn` [IDENTIFIER]&nbsp;[_Generics_]<sup>?</sup>\
66
> &nbsp;&nbsp; &nbsp;&nbsp; `(` _FunctionParameters_<sup>?</sup> `)`\
77
> &nbsp;&nbsp; &nbsp;&nbsp; _FunctionReturnType_<sup>?</sup> [_WhereClause_]<sup>?</sup>\
88
> &nbsp;&nbsp; &nbsp;&nbsp; [_BlockExpression_]
99
>
10-
> _FunctionFront_ :\
10+
> _FunctionQualifiers_ :\
1111
> &nbsp;&nbsp; `const`<sup>?</sup> `unsafe`<sup>?</sup> (`extern` _Abi_<sup>?</sup>)<sup>?</sup>
1212
>
1313
> _Abi_ :\
@@ -114,7 +114,7 @@ opposite functionality to [external blocks]. Whereas external
114114
blocks allow Rust code to call foreign code, extern functions with bodies
115115
defined in Rust code _can be called by foreign code_. They are defined in the
116116
same way as any other Rust function, except that they have the `extern`
117-
modifier.
117+
qualifier.
118118

119119
```rust
120120
// Declares an extern fn, the ABI defaults to "C"
@@ -137,58 +137,34 @@ As non-Rust calling conventions do not support unwinding, unwinding past the end
137137
of an extern function will cause the process to abort. In LLVM, this is
138138
implemented by executing an illegal instruction.
139139

140-
## Attributes on functions
141-
142-
[Outer attributes][attributes] are allowed on functions. [Inner
143-
attributes][attributes] are allowed directly after the `{` inside its [block].
144-
145-
This example shows an inner attribute on a function. The function will only be
146-
available while running tests.
147-
148-
```
149-
fn test_only() {
150-
#![test]
151-
}
152-
```
153-
154-
> Note: Except for lints, it is idiomatic to only use outer attributes on
155-
> function items.
156-
157-
The attributes that have meaning on a function are [`cfg`], [`deprecated`],
158-
[`doc`], `export_name`, `link_section`, `no_mangle`, [the lint check
159-
attributes], [`must_use`], [the procedural macro attributes], [the testing
160-
attributes], and [the optimization hint
161-
attributes].
162-
163140
## Const functions
164141

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.
142+
Functions qualified with the `const` keyword are const functions. _Const
143+
funcions_ can be called from within [const contexts]. When called from a const
144+
context, the function is interpreted by the compiler at compile time. The
145+
interpretation happens in the environment of the compilation target and not the
146+
host. So `usize` is `32` bits if you are compiling against a `32` bit system,
147+
irrelevant of whether you are building on a `64` bit or a `32` bit system.
171148

172-
If a const function is called outside a "const context", it is indistinguishable
149+
If a const function is called outside a [const context], it is indistinguishable
173150
from any other function. You can freely do anything with a const function that
174151
you can do with a regular function.
175152

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.
153+
Const functions have various restrictions to makes sure that they can't be
154+
evaluated at compile-time. It is, for example, not possible to write a random
155+
number generator as a const function. Calling a const function at compile-time
156+
will always yield the same result as calling it at runtime, even when called
157+
multiple times. There's one exception to this rule: if you are doing complex
158+
floating point operations in extreme situations, then you might get (very
159+
slightly) different results. It is adviseable to not make array lengths and enum
160+
discriminants depend on floating point computations.
185161

186162
Exhaustive list of permitted structures in const functions:
187163

188164
> **Note**: this list is more restrictive than what you can write in
189165
> regular constants
190166
191-
* type parameters where the parameters only have any [trait bounds]
167+
* Type parameters where the parameters only have any [trait bounds]
192168
of the following kind:
193169
* lifetimes
194170
* `Sized` or [`?Sized`]
@@ -199,20 +175,43 @@ Exhaustive list of permitted structures in const functions:
199175
This rule also applies to type parameters of impl blocks that
200176
contain const methods
201177

202-
* arithmetic and comparison operators on integers
203-
* all boolean operators except for `&&` and `||` which are banned since
178+
* Arithmetic and comparison operators on integers
179+
* All boolean operators except for `&&` and `||` which are banned since
204180
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)
181+
* Any kind of aggregate constructor (array, `struct`, `enum`, tuple, ...)
182+
* Calls to other *safe* const functions (whether by function call or method call)
183+
* Index expressions on arrays and slices
184+
* Field accesses on structs and tuples
185+
* Reading from constants (but not statics, not even taking a reference to a static)
210186
* `&` and `*` (only dereferencing of references, not raw pointers)
211-
* casts except for raw pointer to integer casts
187+
* Casts except for raw pointer to integer casts
212188
* `const unsafe fn` is allowed, but the body must consist of safe operations
213189
only and you won't be able to call the `const unsafe fn` from within another
214190
const function even if you use `unsafe`
215191

192+
## Attributes on functions
193+
194+
[Outer attributes][attributes] are allowed on functions. [Inner
195+
attributes][attributes] are allowed directly after the `{` inside its [block].
196+
197+
This example shows an inner attribute on a function. The function will only be
198+
available while running tests.
199+
200+
```
201+
fn test_only() {
202+
#![test]
203+
}
204+
```
205+
206+
> Note: Except for lints, it is idiomatic to only use outer attributes on
207+
> function items.
208+
209+
The attributes that have meaning on a function are [`cfg`], [`deprecated`],
210+
[`doc`], `export_name`, `link_section`, `no_mangle`, [the lint check
211+
attributes], [`must_use`], [the procedural macro attributes], [the testing
212+
attributes], and [the optimization hint
213+
attributes].
214+
216215
[IDENTIFIER]: identifiers.html
217216
[RAW_STRING_LITERAL]: tokens.html#raw-string-literals
218217
[STRING_LITERAL]: tokens.html#string-literals

src/items/traits.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818
> &nbsp;&nbsp; &nbsp;&nbsp; _TraitMethodDecl_ ( `;` | [_BlockExpression_] )
1919
>
2020
> _TraitFunctionDecl_ :\
21-
> &nbsp;&nbsp; [_FunctionFront_] `fn` [IDENTIFIER]&nbsp;[_Generics_]<sup>?</sup>\
21+
> &nbsp;&nbsp; [_FunctionQualifiers_] `fn` [IDENTIFIER]&nbsp;[_Generics_]<sup>?</sup>\
2222
> &nbsp;&nbsp; &nbsp;&nbsp; `(` _TraitFunctionParameters_<sup>?</sup> `)`\
2323
> &nbsp;&nbsp; &nbsp;&nbsp; [_FunctionReturnType_]<sup>?</sup> [_WhereClause_]<sup>?</sup>
2424
>
2525
> _TraitMethodDecl_ :\
26-
> &nbsp;&nbsp; [_FunctionFront_] `fn` [IDENTIFIER]&nbsp;[_Generics_]<sup>?</sup>\
26+
> &nbsp;&nbsp; [_FunctionQualifiers_] `fn` [IDENTIFIER]&nbsp;[_Generics_]<sup>?</sup>\
2727
> &nbsp;&nbsp; &nbsp;&nbsp; `(` [_SelfParam_] (`,` _TraitFunctionParam_)<sup>\*</sup> `,`<sup>?</sup> `)`\
2828
> &nbsp;&nbsp; &nbsp;&nbsp; [_FunctionReturnType_]<sup>?</sup> [_WhereClause_]<sup>?</sup>
2929
>
@@ -201,8 +201,8 @@ trait T {
201201
[WildcardPattern]: patterns.html#wildcard-pattern
202202
[_BlockExpression_]: expressions/block-expr.html
203203
[_Expression_]: expressions.html
204-
[_FunctionFront_]: items/functions.html
205204
[_FunctionParam_]: items/functions.html
205+
[_FunctionQualifiers_]: items/functions.html
206206
[_FunctionReturnType_]: items/functions.html
207207
[_Generics_]: items/generics.html
208208
[_OuterAttribute_]: attributes.html

src/types.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ All function items implement [`Fn`], [`FnMut`], [`FnOnce`], [`Copy`],
431431

432432
> **<sup>Syntax</sup>**\
433433
> _BareFunctionType_ :\
434-
> &nbsp;&nbsp; [_ForLifetimes_]<sup>?</sup> [_FunctionFront_] `fn`\
434+
> &nbsp;&nbsp; [_ForLifetimes_]<sup>?</sup> [_FunctionQualifiers_] `fn`\
435435
> &nbsp;&nbsp; &nbsp;&nbsp; `(` _FunctionParametersMaybeNamedVariadic_<sup>?</sup> `)` _BareFunctionReturnType_<sup>?</sup>
436436
>
437437
> _BareFunctionReturnType_:\
@@ -862,8 +862,8 @@ impl Printable for String {
862862
[_BareFunctionType_]: #function-pointer-types
863863
[_Expression_]: expressions.html
864864
[_ForLifetimes_]: items/generics.html#where-clauses
865-
[_FunctionFront_]: items/functions.html
866865
[_FunctionParametersMaybeNamed_]: items/functions.html
866+
[_FunctionQualifiers_]: items/functions.html
867867
[_ImplTraitTypeOneBound_]: #impl-trait
868868
[_ImplTraitType_]: #impl-trait
869869
[_InferredType_]: #inferred-type

0 commit comments

Comments
 (0)