]> git.proxmox.com Git - rustc.git/blob - src/doc/reference/src/expressions.md
New upstream version 1.27.1+dfsg1
[rustc.git] / src / doc / reference / src / expressions.md
1 # Expressions
2
3 > **<sup>Syntax</sup>**
4 > _Expression_ :
5 > &nbsp;&nbsp; &nbsp;&nbsp; [_LiteralExpression_]
6 > &nbsp;&nbsp; | [_PathExpression_]
7 > &nbsp;&nbsp; | [_BlockExpression_]
8 > &nbsp;&nbsp; | [_OperatorExpression_]
9 > &nbsp;&nbsp; | [_GroupedExpression_]
10 > &nbsp;&nbsp; | [_ArrayExpression_]
11 > &nbsp;&nbsp; | [_IndexExpression_]
12 > &nbsp;&nbsp; | [_TupleExpression_]
13 > &nbsp;&nbsp; | [_TupleIndexingExpression_]
14 > &nbsp;&nbsp; | [_StructExpression_]
15 > &nbsp;&nbsp; | [_EnumerationVariantExpression_]
16 > &nbsp;&nbsp; | [_CallExpression_]
17 > &nbsp;&nbsp; | [_MethodCallExpression_]
18 > &nbsp;&nbsp; | [_FieldExpression_]
19 > &nbsp;&nbsp; | [_ClosureExpression_]
20 > &nbsp;&nbsp; | [_LoopExpression_]
21 > &nbsp;&nbsp; | [_ContinueExpression_]
22 > &nbsp;&nbsp; | [_BreakExpression_]
23 > &nbsp;&nbsp; | [_RangeExpression_]
24 > &nbsp;&nbsp; | [_IfExpression_]
25 > &nbsp;&nbsp; | [_IfLetExpression_]
26 > &nbsp;&nbsp; | [_MatchExpression_]
27 > &nbsp;&nbsp; | [_ReturnExpression_]
28
29 An expression may have two roles: it always produces a *value*, and it may have
30 *effects* (otherwise known as "side effects"). An expression *evaluates to* a
31 value, and has effects during *evaluation*. Many expressions contain
32 sub-expressions (operands). The meaning of each kind of expression dictates
33 several things:
34
35 * Whether or not to evaluate the sub-expressions when evaluating the expression
36 * The order in which to evaluate the sub-expressions
37 * How to combine the sub-expressions' values to obtain the value of the
38 expression
39
40 In this way, the structure of expressions dictates the structure of execution.
41 Blocks are just another kind of expression, so blocks, statements, expressions,
42 and blocks again can recursively nest inside each other to an arbitrary depth.
43
44 ## Expression precedence
45
46 The precedence of Rust operators and expressions is ordered as follows, going
47 from strong to weak. Binary Operators at the same precedence level are grouped
48 in the order given by their associativity.
49
50 | Operator/Expression | Associativity |
51 |-----------------------------|---------------------|
52 | Paths | |
53 | Method calls | |
54 | Field expressions | left to right |
55 | Function calls, array indexing | |
56 | `?` | |
57 | Unary `-` `*` `!` `&` `&mut` | |
58 | `as` | left to right |
59 | `*` `/` `%` | left to right |
60 | `+` `-` | left to right |
61 | `<<` `>>` | left to right |
62 | `&` | left to right |
63 | `^` | left to right |
64 | <code>&#124;</code> | left to right |
65 | `==` `!=` `<` `>` `<=` `>=` | Require parentheses |
66 | `&&` | left to right |
67 | <code>&#124;&#124;</code> | left to right |
68 | `..` `..=` | Require parentheses |
69 | `=` `+=` `-=` `*=` `/=` `%=` <br> `&=` <code>&#124;=</code> `^=` `<<=` `>>=` | right to left |
70 | `return` `break` closures | |
71
72 ## Place Expressions and Value Expressions
73
74 Expressions are divided into two main categories: place expressions and
75 value expressions. Likewise within each expression, sub-expressions may occur
76 in either place context or value context. The evaluation of an expression
77 depends both on its own category and the context it occurs within.
78
79 A *place expression* is an expression that represents a memory location. These
80 expressions are [paths] which refer to local variables, [static variables],
81 [dereferences]&nbsp;(`*expr`), [array indexing] expressions (`expr[expr]`),
82 [field] references (`expr.f`) and parenthesized place expressions. All other
83 expressions are value expressions.
84
85 A *value expression* is an expression that represents an actual value.
86
87 The left operand of an [assignment][assign] or [compound assignment] expression
88 is a place expression context, as is the single operand of a unary [borrow], and
89 the operand of any [implicit borrow]. The discriminant or subject of a
90 [match expression][match] and right side of a [let statement] is also a place
91 expression context. All other expression contexts are value expression contexts.
92
93 > Note: Historically, place expressions were called *lvalues* and value
94 > expressions were called *rvalues*.
95
96 ### Moved and copied types
97
98 When a place expression is evaluated in a value expression context, or is bound
99 by value in a pattern, it denotes the value held _in_ that memory location. If
100 the type of that value implements [`Copy`], then the value will be copied. In
101 the remaining situations if that type is [`Sized`], then it may be possible to
102 move the value. Only the following place expressions may be moved out of:
103
104 * [Variables] which are not currently borrowed.
105 * [Temporary values](#temporary-lifetimes).
106 * [Fields][field] of a place expression which can be moved out of and
107 doesn't implement [`Drop`].
108 * The result of [dereferencing] an expression with type [`Box<T>`] and that can
109 also be moved out of.
110
111 Moving out of a place expression that evaluates to a local variable, the
112 location is deinitialized and cannot be read from again until it is
113 reinitialized. In all other cases, trying to use a place expression in a value
114 expression context is an error.
115
116 ### Mutability
117
118 For a place expression to be [assigned][assign] to, mutably [borrowed][borrow],
119 [implicitly mutably borrowed], or bound to a pattern containing `ref mut` it
120 must be _mutable_. We call these *mutable place expressions*. In contrast,
121 other place expressions are called *immutable place expressions*.
122
123 The following expressions can be mutable place expression contexts:
124
125 * Mutable [variables], which are not currently borrowed.
126 * [Mutable `static` items].
127 * [Temporary values].
128 * [Fields][field], this evaluates the subexpression in a mutable place
129 expression context.
130 * [Dereferences] of a `*mut T` pointer.
131 * Dereference of a variable, or field of a variable, with type `&mut T`. Note:
132 This is an exception to the requirement of the next rule.
133 * Dereferences of a type that implements `DerefMut`, this then requires that
134 the value being dereferenced is evaluated is a mutable place expression context.
135 * [Array indexing] of a type that implements `DerefMut`, this
136 then evaluates the value being indexed, but not the index, in mutable place
137 expression context.
138
139 ### Temporary lifetimes
140
141 When using a value expression in most place expression contexts, a temporary
142 unnamed memory location is created initialized to that value and the expression
143 evaluates to that location instead, except if promoted to `'static`. Promotion
144 of a value expression to a `'static` slot occurs when the expression could be
145 written in a constant, borrowed, and dereferencing that borrow where the
146 expression was the originally written, without changing the runtime behavior.
147 That is, the promoted expression can be evaluated at compile-time and the
148 resulting value does not contain [interior mutability] or [destructors] (these
149 properties are determined based on the value where possible, e.g. `&None`
150 always has the type `&'static Option<_>`, as it contains nothing disallowed).
151 Otherwise, the lifetime of temporary values is typically
152
153 - the innermost enclosing statement; the tail expression of a block is
154 considered part of the statement that encloses the block, or
155 - the condition expression or the loop conditional expression if the
156 temporary is created in the condition expression of an `if` or in the loop
157 conditional expression of a `while` expression.
158
159 When a temporary value expression is being created that is assigned into a
160 [`let` declaration][let], however, the temporary is created with the lifetime of
161 the enclosing block instead, as using the enclosing [`let` declaration][let]
162 would be a guaranteed error (since a pointer to the temporary
163 would be stored into a variable, but the temporary would be freed before the
164 variable could be used). The compiler uses simple syntactic rules to decide
165 which values are being assigned into a `let` binding, and therefore deserve a
166 longer temporary lifetime.
167
168 Here are some examples:
169
170 - `let x = foo(&temp())`. The expression `temp()` is a value expression. As it
171 is being borrowed, a temporary is created which will be freed after
172 the innermost enclosing statement; in this case, the `let` declaration.
173 - `let x = temp().foo()`. This is the same as the previous example,
174 except that the value of `temp()` is being borrowed via autoref on a
175 method-call. Here we are assuming that `foo()` is an `&self` method
176 defined in some trait, say `Foo`. In other words, the expression
177 `temp().foo()` is equivalent to `Foo::foo(&temp())`.
178 - `let x = if foo(&temp()) {bar()} else {baz()};`. The expression `temp()` is
179 a value expression. As the temporary is created in the condition expression
180 of an `if`, it will be freed at the end of the condition expression;
181 in this example before the call to `bar` or `baz` is made.
182 - `let x = if temp().must_run_bar {bar()} else {baz()};`.
183 Here we assume the type of `temp()` is a struct with a boolean field
184 `must_run_bar`. As the previous example, the temporary corresponding to
185 `temp()` will be freed at the end of the condition expression.
186 - `while foo(&temp()) {bar();}`. The temporary containing the return value from
187 the call to `temp()` is created in the loop conditional expression. Hence it
188 will be freed at the end of the loop conditional expression; in this example
189 before the call to `bar` if the loop body is executed.
190 - `let x = &temp()`. Here, the same temporary is being assigned into
191 `x`, rather than being passed as a parameter, and hence the
192 temporary's lifetime is considered to be the enclosing block.
193 - `let x = SomeStruct { foo: &temp() }`. As in the previous case, the
194 temporary is assigned into a struct which is then assigned into a
195 binding, and hence it is given the lifetime of the enclosing block.
196 - `let x = [ &temp() ]`. As in the previous case, the
197 temporary is assigned into an array which is then assigned into a
198 binding, and hence it is given the lifetime of the enclosing block.
199 - `let ref x = temp()`. In this case, the temporary is created using a ref
200 binding, but the result is the same: the lifetime is extended to the enclosing
201 block.
202
203 ### Implicit Borrows
204
205 Certain expressions will treat an expression as a place expression by implicitly
206 borrowing it. For example, it is possible to compare two unsized [slices] for
207 equality directly, because the `==` operator implicitly borrows it's operands:
208
209 ```rust
210 # let c = [1, 2, 3];
211 # let d = vec![1, 2, 3];
212 let a: &[i32];
213 let b: &[i32];
214 # a = &c;
215 # b = &d;
216 // ...
217 *a == *b;
218 // Equivalent form:
219 ::std::cmp::PartialEq::eq(&*a, &*b);
220 ```
221
222 Implicit borrows may be taken in the following expressions:
223
224 * Left operand in [method-call] expressions.
225 * Left operand in [field] expressions.
226 * Left operand in [call expressions].
227 * Left operand in [array indexing] expressions.
228 * Operand of the [dereference operator] \(`*`).
229 * Operands of [comparison].
230 * Left operands of the [compound assignment].
231
232 ## Constant expressions
233
234 Certain types of expressions can be evaluated at compile time. These are called
235 _constant expressions_. Certain places, such as in
236 [constants](items/constant-items.html) and [statics](items/static-items.html),
237 require a constant expression, and are always evaluated at compile time. In
238 other places, such as in [`let` statements](statements.html#let-statements),
239 constant expressions may be evaluated at compile time. If errors, such as out
240 of bounds [array indexing] or [overflow] occurs,
241 then it is a compiler error if the value must be evaluated at compile time,
242 otherwise it is just a warning, but the code will most likely panic when run.
243
244 The following expressions are constant expressions, so long as any operands are
245 also constant expressions and do not cause any [`Drop::drop`][destructors] calls
246 to be ran.
247
248 * [Literals].
249 * [Paths] to [functions](items/functions.html) and constants.
250 Recursively defining constants is not allowed.
251 * [Tuple expressions].
252 * [Array expressions].
253 * [Struct] expressions.
254 * [Enum variant] expressions.
255 * [Block expressions], including `unsafe` blocks, which only contain items and
256 possibly a constant tail expression.
257 * [Field] expressions.
258 * Index expressions, [array indexing] or [slice] with a `usize`.
259 * [Range expressions].
260 * [Closure expressions] which don't capture variables from the environment.
261 * Built in [negation], [arithmetic, logical], [comparison] or [lazy boolean]
262 operators used on integer and floating point types, `bool` and `char`.
263 * Shared [borrow]s, except if applied to a type with [interior mutability].
264 * The [dereference operator].
265 * [Grouped] expressions.
266 * [Cast] expressions, except pointer to address and
267 function pointer to address casts.
268
269 ## Overloading Traits
270
271 Many of the following operators and expressions can also be overloaded for
272 other types using traits in `std::ops` or `std::cmp`. These traits also
273 exist in `core::ops` and `core::cmp` with the same names.
274
275 [block expressions]: expressions/block-expr.html
276 [call expressions]: expressions/call-expr.html
277 [closure expressions]: expressions/closure-expr.html
278 [enum variant]: expressions/enum-variant-expr.html
279 [field]: expressions/field-expr.html
280 [grouped]: expressions/grouped-expr.html
281 [literals]: expressions/literal-expr.html
282 [match]: expressions/match-expr.html
283 [method-call]: expressions/method-call-expr.html
284 [paths]: expressions/path-expr.html
285 [range expressions]: expressions/range-expr.html
286 [struct]: expressions/struct-expr.html
287 [tuple expressions]: expressions/tuple-expr.html
288
289 [array expressions]: expressions/array-expr.html
290 [array indexing]: expressions/array-expr.html#array-and-slice-indexing-expressions
291
292 [arithmetic, logical]: expressions/operator-expr.html#arithmetic-and-logical-binary-operators
293 [assign]: expressions/operator-expr.html#assignment-expressions
294 [borrow]: expressions/operator-expr.html#borrow-operators
295 [cast]: expressions/operator-expr.html#type-cast-expressions
296 [comparison]: expressions/operator-expr.html#comparison-operators
297 [compound assignment]: expressions/operator-expr.html#compound-assignment-expressions
298 [dereferences]: expressions/operator-expr.html#the-dereference-operator
299 [dereferencing]: expressions/operator-expr.html#the-dereference-operator
300 [dereference operator]: expressions/operator-expr.html#the-dereference-operator
301 [lazy boolean]: expressions/operator-expr.html#lazy-boolean-operators
302 [negation]: expressions/operator-expr.html#negation-operators
303 [overflow]: expressions/operator-expr.html#overflow
304
305 [destructors]: destructors.html
306 [interior mutability]: interior-mutability.html
307 [`Box<T>`]: ../std/boxed/struct.Box.html
308 [`Copy`]: special-types-and-traits.html#copy
309 [`Drop`]: special-types-and-traits.html#drop
310 [`Sized`]: special-types-and-traits.html#sized
311 [implicit borrow]: #implicit-borrows
312 [implicitly mutably borrowed]: #implicit-borrows
313 [let]: statements.html#let-statements
314 [let statement]: statements.html#let-statements
315 [Mutable `static` items]: items/static-items.html#mutable-statics
316 [slice]: types.html#array-and-slice-types
317 [static variables]: items/static-items.html
318 [Temporary values]: #temporary-lifetimes
319 [Variables]: variables.html
320
321 [_ArrayExpression_]: expressions/array-expr.html
322 [_BlockExpression_]: expressions/block-expr.html
323 [_BreakExpression_]: expressions/loop-expr.html#break-expressions
324 [_CallExpression_]: expressions/call-expr.html
325 [_ClosureExpression_]: expressions/closure-expr.html
326 [_ContinueExpression_]: expressions/loop-expr.html#continue-expressions
327 [_EnumerationVariantExpression_]: expressions/enum-variant-expr.html
328 [_FieldExpression_]: expressions/field-expr.html
329 [_GroupedExpression_]: expressions/grouped-expr.html
330 [_IfExpression_]: expressions/if-expr.html#if-expressions
331 [_IfLetExpression_]: expressions/if-expr.html#if-let-expressions
332 [_IndexExpression_]: expressions/array-expr.html#array-and-slice-indexing-expressions
333 [_LiteralExpression_]: expressions/literal-expr.html
334 [_LoopExpression_]: expressions/loop-expr.html
335 [_MatchExpression_]: expressions/match-expr.html
336 [_MethodCallExpression_]: expressions/method-call-expr.html
337 [_OperatorExpression_]: expressions/operator-expr.html
338 [_PathExpression_]: expressions/path-expr.html
339 [_RangeExpression_]: expressions/range-expr.html
340 [_ReturnExpression_]: expressions/return-expr.html
341 [_StructExpression_]: expressions/struct-expr.html
342 [_TupleExpression_]: expressions/tuple-expr.html
343 [_TupleIndexingExpression_]: expressions/tuple-expr.html#tuple-indexing-expressions