]>
Commit | Line | Data |
---|---|---|
ea8adc8c XL |
1 | # Functions |
2 | ||
0bf4aa26 XL |
3 | > **<sup>Syntax</sup>**\ |
4 | > _Function_ :\ | |
5 | > _FunctionQualifiers_ `fn` [IDENTIFIER] [_Generics_]<sup>?</sup>\ | |
6 | > `(` _FunctionParameters_<sup>?</sup> `)`\ | |
7 | > _FunctionReturnType_<sup>?</sup> [_WhereClause_]<sup>?</sup>\ | |
8 | > [_BlockExpression_] | |
9 | > | |
10 | > _FunctionQualifiers_ :\ | |
11 | > `const`<sup>?</sup> `unsafe`<sup>?</sup> (`extern` _Abi_<sup>?</sup>)<sup>?</sup> | |
12 | > | |
13 | > _Abi_ :\ | |
14 | > [STRING_LITERAL] | [RAW_STRING_LITERAL] | |
15 | > | |
16 | > _FunctionParameters_ :\ | |
17 | > _FunctionParam_ (`,` _FunctionParam_)<sup>\*</sup> `,`<sup>?</sup> | |
18 | > | |
19 | > _FunctionParam_ :\ | |
20 | > [_Pattern_] `:` [_Type_] | |
21 | > | |
22 | > _FunctionReturnType_ :\ | |
23 | > `->` [_Type_] | |
24 | ||
ea8adc8c XL |
25 | A _function_ consists of a [block], along with a name and a set of parameters. |
26 | Other than a name, all these are optional. Functions are declared with the | |
27 | keyword `fn`. Functions may declare a set of *input* [*variables*][variables] | |
28 | as parameters, through which the caller passes arguments into the function, and | |
29 | the *output* [*type*][type] of the value the function will return to its caller | |
30 | on completion. | |
31 | ||
ea8adc8c | 32 | When referred to, a _function_ yields a first-class *value* of the |
0531ce1d | 33 | corresponding zero-sized [*function item type*], which |
ea8adc8c XL |
34 | when called evaluates to a direct call to the function. |
35 | ||
ea8adc8c XL |
36 | For example, this is a simple function: |
37 | ```rust | |
38 | fn answer_to_life_the_universe_and_everything() -> i32 { | |
39 | return 42; | |
40 | } | |
41 | ``` | |
42 | ||
0bf4aa26 | 43 | As with `let` bindings, function arguments are irrefutable [patterns], so any |
ea8adc8c XL |
44 | pattern that is valid in a let binding is also valid as an argument: |
45 | ||
46 | ```rust | |
47 | fn first((value, _): (i32, i32)) -> i32 { value } | |
48 | ``` | |
49 | ||
50 | The block of a function is conceptually wrapped in a block that binds the | |
51 | argument patterns and then `return`s the value of the function's block. This | |
52 | means that the tail expression of the block, if evaluated, ends up being | |
53 | returned to the caller. As usual, an explicit return expression within | |
54 | the body of the function will short-cut that implicit return, if reached. | |
55 | ||
56 | For example, the function above behaves as if it was written as: | |
57 | ||
58 | ```rust,ignore | |
59 | // argument_0 is the actual first argument passed from the caller | |
60 | let (value, _) = argument_0; | |
61 | return { | |
62 | value | |
63 | }; | |
64 | ``` | |
65 | ||
66 | ## Generic functions | |
67 | ||
68 | A _generic function_ allows one or more _parameterized types_ to appear in its | |
69 | signature. Each type parameter must be explicitly declared in an | |
70 | angle-bracket-enclosed and comma-separated list, following the function name. | |
71 | ||
72 | ```rust | |
73 | // foo is generic over A and B | |
74 | ||
75 | fn foo<A, B>(x: A, y: B) { | |
76 | # } | |
77 | ``` | |
78 | ||
79 | Inside the function signature and body, the name of the type parameter can be | |
83c7162d | 80 | used as a type name. [Trait] bounds can be specified for type |
ea8adc8c XL |
81 | parameters to allow methods with that trait to be called on values of that |
82 | type. This is specified using the `where` syntax: | |
83 | ||
84 | ```rust | |
85 | # use std::fmt::Debug; | |
86 | fn foo<T>(x: T) where T: Debug { | |
87 | # } | |
88 | ``` | |
89 | ||
90 | When a generic function is referenced, its type is instantiated based on the | |
91 | context of the reference. For example, calling the `foo` function here: | |
92 | ||
93 | ```rust | |
94 | use std::fmt::Debug; | |
95 | ||
96 | fn foo<T>(x: &[T]) where T: Debug { | |
97 | // details elided | |
98 | } | |
99 | ||
100 | foo(&[1, 2]); | |
101 | ``` | |
102 | ||
103 | will instantiate type parameter `T` with `i32`. | |
104 | ||
105 | The type parameters can also be explicitly supplied in a trailing [path] | |
106 | component after the function name. This might be necessary if there is not | |
107 | sufficient context to determine the type parameters. For example, | |
108 | `mem::size_of::<u32>() == 4`. | |
109 | ||
ea8adc8c XL |
110 | ## Extern functions |
111 | ||
112 | Extern functions are part of Rust's foreign function interface, providing the | |
2c00a5a8 | 113 | opposite functionality to [external blocks]. Whereas external |
ea8adc8c XL |
114 | blocks allow Rust code to call foreign code, extern functions with bodies |
115 | defined in Rust code _can be called by foreign code_. They are defined in the | |
116 | same way as any other Rust function, except that they have the `extern` | |
0bf4aa26 | 117 | qualifier. |
ea8adc8c XL |
118 | |
119 | ```rust | |
120 | // Declares an extern fn, the ABI defaults to "C" | |
121 | extern fn new_i32() -> i32 { 0 } | |
122 | ||
123 | // Declares an extern fn with "stdcall" ABI | |
124 | # #[cfg(target_arch = "x86_64")] | |
125 | extern "stdcall" fn new_i32_stdcall() -> i32 { 0 } | |
126 | ``` | |
127 | ||
128 | Unlike normal functions, extern fns have type `extern "ABI" fn()`. This is the | |
129 | same type as the functions declared in an extern block. | |
130 | ||
131 | ```rust | |
132 | # extern fn new_i32() -> i32 { 0 } | |
133 | let fptr: extern "C" fn() -> i32 = new_i32; | |
134 | ``` | |
135 | ||
2c00a5a8 XL |
136 | As non-Rust calling conventions do not support unwinding, unwinding past the end |
137 | of an extern function will cause the process to abort. In LLVM, this is | |
138 | implemented by executing an illegal instruction. | |
139 | ||
0bf4aa26 XL |
140 | ## Const functions |
141 | ||
142 | Functions qualified with the `const` keyword are const functions. _Const | |
9fa01778 | 143 | functions_ can be called from within [const context]s. When called from a const |
0bf4aa26 XL |
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. | |
148 | ||
149 | If a const function is called outside a [const context], it is indistinguishable | |
150 | from any other function. You can freely do anything with a const function that | |
151 | you can do with a regular function. | |
152 | ||
9fa01778 | 153 | Const functions have various restrictions to make sure that they can be |
0bf4aa26 XL |
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 | |
13cf67c4 | 159 | slightly) different results. It is advisable to not make array lengths and enum |
0bf4aa26 XL |
160 | discriminants depend on floating point computations. |
161 | ||
162 | Exhaustive list of permitted structures in const functions: | |
163 | ||
164 | > **Note**: this list is more restrictive than what you can write in | |
165 | > regular constants | |
166 | ||
167 | * Type parameters where the parameters only have any [trait bounds] | |
168 | of the following kind: | |
169 | * lifetimes | |
170 | * `Sized` or [`?Sized`] | |
171 | ||
172 | This means that `<T: 'a + ?Sized>`, `<T: 'b + Sized>` and `<T>` | |
173 | are all permitted. | |
174 | ||
175 | This rule also applies to type parameters of impl blocks that | |
176 | contain const methods | |
177 | ||
178 | * Arithmetic and comparison operators on integers | |
179 | * All boolean operators except for `&&` and `||` which are banned since | |
180 | they are short-circuiting. | |
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) | |
186 | * `&` and `*` (only dereferencing of references, not raw pointers) | |
187 | * Casts except for raw pointer to integer casts | |
9fa01778 XL |
188 | * `unsafe` blocks and `const unsafe fn` are allowed, but the body/block may only do |
189 | the following unsafe operations: | |
190 | * calls to const unsafe functions | |
0bf4aa26 | 191 | |
b7449926 | 192 | ## Attributes on functions |
8faf50e0 | 193 | |
b7449926 XL |
194 | [Outer attributes][attributes] are allowed on functions. [Inner |
195 | attributes][attributes] are allowed directly after the `{` inside its [block]. | |
8faf50e0 | 196 | |
0bf4aa26 | 197 | This example shows an inner attribute on a function. The function will only be |
b7449926 | 198 | available while running tests. |
8faf50e0 XL |
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 | ||
b7449926 XL |
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 | |
0bf4aa26 XL |
212 | attributes], and [the optimization hint attributes]. Functions also accept |
213 | attributes macros. | |
214 | ||
215 | [IDENTIFIER]: identifiers.html | |
216 | [RAW_STRING_LITERAL]: tokens.html#raw-string-literals | |
217 | [STRING_LITERAL]: tokens.html#string-literals | |
218 | [_BlockExpression_]: expressions/block-expr.html | |
219 | [_Generics_]: items/generics.html | |
220 | [_InnerAttribute_]: attributes.html | |
221 | [_Pattern_]: patterns.html | |
222 | [_Statement_]: statements.html | |
13cf67c4 | 223 | [_Type_]: types.html#type-expressions |
0bf4aa26 | 224 | [_WhereClause_]: items/generics.html#where-clauses |
9fa01778 | 225 | [const context]: const_eval.html#const-context |
0531ce1d | 226 | [external blocks]: items/external-blocks.html |
83c7162d XL |
227 | [path]: paths.html |
228 | [block]: expressions/block-expr.html | |
229 | [variables]: variables.html | |
13cf67c4 XL |
230 | [type]: types.html#type-expressions |
231 | [*function item type*]: types/function-item.html | |
83c7162d | 232 | [Trait]: items/traits.html |
8faf50e0 | 233 | [attributes]: attributes.html |
b7449926 XL |
234 | [`cfg`]: conditional-compilation.html |
235 | [the lint check attributes]: attributes.html#lint-check-attributes | |
236 | [the procedural macro attributes]: procedural-macros.html | |
237 | [the testing attributes]: attributes.html#testing | |
238 | [the optimization hint attributes]: attributes.html#optimization-hints | |
239 | [`deprecated`]: attributes.html#deprecation | |
240 | [`doc`]: attributes.html#documentation | |
0bf4aa26 XL |
241 | [`must_use`]: attributes.html#must_use |
242 | [patterns]: patterns.html | |
243 | [`?Sized`]: trait-bounds.html#sized | |
244 | [trait bounds]: trait-bounds.html |