]> git.proxmox.com Git - rustc.git/blame - src/doc/edition-guide/src/rust-next/const-fn.md
New upstream version 1.53.0+dfsg1
[rustc.git] / src / doc / edition-guide / src / rust-next / const-fn.md
CommitLineData
f035d41b
XL
1# `const fn`
2
3Initially added: ![Minimum Rust version: 1.31](https://img.shields.io/badge/Minimum%20Rust%20Version-1.31-brightgreen.svg)
4
5Expanded in many releases, see each aspect below for more details.
6
7A `const fn` allows you to execute code in a "const context." For example:
8
29967ef6 9```rust
f035d41b
XL
10const fn five() -> i32 {
11 5
12}
13
14const FIVE: i32 = five();
15```
16
17You cannot execute arbitrary code; the reasons why boil down to "you can
18destroy the type system." The details are a bit too much to put here, but the
19core idea is that `const fn` started off allowing the absolutely minimal
20subset of the language, and has slowly added more abilities over time.
21Therefore, while you can create a `const fn` in Rust 1.31, you cannot do much
22with it. This is why we didn't add `const fn` to the Rust 2018 section; it
23truly didn't become useful until after the release of the 2018 edition. This
24means that if you read this document top to bottom, the earlier versions may
25describe restrictions that are relaxed in later versions.
26
27Additionally, this has allowed more and more of the standard library to be
28made `const`, we won't put all of those changes here, but you should know
29that it is becoming more `const` over time.
30
31## Arithmetic and comparison operators on integers
32
33![Minimum Rust version: 1.31](https://img.shields.io/badge/Minimum%20Rust%20Version-1.31-brightgreen.svg)
34
35You can do arithmetic on integer literals:
36
29967ef6 37```rust
f035d41b
XL
38const fn foo() -> i32 {
39 5 + 6
40}
41```
42
43## Many boolean operators
44
45![Minimum Rust version: 1.31](https://img.shields.io/badge/Minimum%20Rust%20Version-1.31-brightgreen.svg)
46
47You can use boolean operators other than `&&` and `||`, because they short-circut evaluation:
48
29967ef6 49```rust
f035d41b
XL
50const fn mask(val: u8) -> u8 {
51 let mask = 0x0f;
52
53 mask & val
54}
55```
56
57## Constructing arrays, structs, enums, and tuples
58
59![Minimum Rust version: 1.31](https://img.shields.io/badge/Minimum%20Rust%20Version-1.31-brightgreen.svg)
60
61You can create arrays, structs, enums, and tuples:
62
29967ef6 63```rust
f035d41b
XL
64struct Point {
65 x: i32,
66 y: i32,
67}
68
69enum Error {
70 Incorrect,
71 FileNotFound,
72}
73
74const fn foo() {
75 let array = [1, 2, 3];
76
77 let point = Point {
78 x: 5,
79 y: 10,
80 };
81
82 let error = Error::FileNotFound;
83
84 let tuple = (1, 2, 3);
85}
86```
87
88## Calls to other const fns
89
90![Minimum Rust version: 1.31](https://img.shields.io/badge/Minimum%20Rust%20Version-1.31-brightgreen.svg)
91
92You can call `const fn` from a `const fn`:
93
94
29967ef6 95```rust
f035d41b
XL
96const fn foo() -> i32 {
97 5
98}
99
100const fn bar() -> i32 {
101 foo()
102}
103```
104
105## Index expressions on arrays and slices
106
107![Minimum Rust version: 1.31](https://img.shields.io/badge/Minimum%20Rust%20Version-1.31-brightgreen.svg)
108
109You can index into an array or slice:
110
29967ef6 111```rust
f035d41b
XL
112const fn foo() -> i32 {
113 let array = [1, 2, 3];
114
115 array[1]
116}
117```
118
119## Field accesses on structs and tuples
120
121![Minimum Rust version: 1.31](https://img.shields.io/badge/Minimum%20Rust%20Version-1.31-brightgreen.svg)
122
123You can access parts of a struct or tuple:
124
29967ef6 125```rust
f035d41b
XL
126struct Point {
127 x: i32,
128 y: i32,
129}
130
131const fn foo() {
132 let point = Point {
133 x: 5,
134 y: 10,
135 };
136
137 let tuple = (1, 2, 3);
138
139 point.x;
140 tuple.0;
141}
142```
143
144## Reading from constants
145
146![Minimum Rust version: 1.31](https://img.shields.io/badge/Minimum%20Rust%20Version-1.31-brightgreen.svg)
147
148You can read from a constant:
149
29967ef6 150```rust
f035d41b
XL
151const FOO: i32 = 5;
152
153const fn foo() -> i32 {
154 FOO
155}
156```
157
158Note that this is *only* `const`, not `static`.
159
160## & and * of references
161
162![Minimum Rust version: 1.31](https://img.shields.io/badge/Minimum%20Rust%20Version-1.31-brightgreen.svg)
163
164You can create and de-reference references:
165
29967ef6 166```rust
f035d41b
XL
167const fn foo(r: &i32) {
168 *r;
169
170 &5;
171}
172```
173
174## Casts, except for raw pointer to integer casts
175
176![Minimum Rust version: 1.31](https://img.shields.io/badge/Minimum%20Rust%20Version-1.31-brightgreen.svg)
177
178You may cast things, except for raw pointers may not be casted to an integer:
179
29967ef6 180```rust
f035d41b
XL
181const fn foo() {
182 let x: usize = 5;
183
184 x as i32;
185}
186```
187
188## Irrefutable destructuring patterns
189
190![Minimum Rust version: 1.33](https://img.shields.io/badge/Minimum%20Rust%20Version-1.33-brightgreen.svg)
191
192You can use irrefutable patterns that destructure values. For example:
193
29967ef6 194```rust
f035d41b
XL
195const fn foo((x, y): (u8, u8)) {
196 // ...
197}
198```
199
200Here, `foo` destructures the tuple into `x` and `y`. `if let` is another
201place that uses irrefutable patterns.
202
203## `let` bindings
204
205![Minimum Rust version: 1.33](https://img.shields.io/badge/Minimum%20Rust%20Version-1.33-brightgreen.svg)
206
207You can use both mutable and immutable `let` bindings:
208
29967ef6 209```rust
f035d41b
XL
210const fn foo() {
211 let x = 5;
212 let mut y = 10;
213}
214```
215
216## Assignment
217
218![Minimum Rust version: 1.33](https://img.shields.io/badge/Minimum%20Rust%20Version-1.33-brightgreen.svg)
219
220You can use assignment and assignment operators:
221
29967ef6 222```rust
f035d41b
XL
223const fn foo() {
224 let mut x = 5;
225 x = 10;
226}
227```
228
229## Calling `unsafe fn`
230
231![Minimum Rust version: 1.33](https://img.shields.io/badge/Minimum%20Rust%20Version-1.33-brightgreen.svg)
232
1b1a35ee 233You can call an `unsafe fn` inside a `const fn`:
f035d41b 234
29967ef6 235```rust
f035d41b
XL
236const unsafe fn foo() -> i32 { 5 }
237
238const fn bar() -> i32 {
239 unsafe { foo() }
240}
1b1a35ee 241```