]> git.proxmox.com Git - rustc.git/blame - src/doc/reference/src/expressions.md
New upstream version 1.53.0+dfsg1
[rustc.git] / src / doc / reference / src / expressions.md
CommitLineData
8bb4bdeb
XL
1# Expressions
2
8faf50e0
XL
3> **<sup>Syntax</sup>**\
4> _Expression_ :\
13cf67c4
XL
5> &nbsp;&nbsp; &nbsp;&nbsp; _ExpressionWithoutBlock_\
6> &nbsp;&nbsp; | _ExpressionWithBlock_
7>
8> _ExpressionWithoutBlock_ :\
9> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup>[†](#expression-attributes)\
10> &nbsp;&nbsp; (\
11> &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; [_LiteralExpression_]\
12> &nbsp;&nbsp; &nbsp;&nbsp; | [_PathExpression_]\
13> &nbsp;&nbsp; &nbsp;&nbsp; | [_OperatorExpression_]\
14> &nbsp;&nbsp; &nbsp;&nbsp; | [_GroupedExpression_]\
15> &nbsp;&nbsp; &nbsp;&nbsp; | [_ArrayExpression_]\
e1599b0c 16> &nbsp;&nbsp; &nbsp;&nbsp; | [_AwaitExpression_]\
13cf67c4
XL
17> &nbsp;&nbsp; &nbsp;&nbsp; | [_IndexExpression_]\
18> &nbsp;&nbsp; &nbsp;&nbsp; | [_TupleExpression_]\
19> &nbsp;&nbsp; &nbsp;&nbsp; | [_TupleIndexingExpression_]\
20> &nbsp;&nbsp; &nbsp;&nbsp; | [_StructExpression_]\
13cf67c4
XL
21> &nbsp;&nbsp; &nbsp;&nbsp; | [_CallExpression_]\
22> &nbsp;&nbsp; &nbsp;&nbsp; | [_MethodCallExpression_]\
23> &nbsp;&nbsp; &nbsp;&nbsp; | [_FieldExpression_]\
24> &nbsp;&nbsp; &nbsp;&nbsp; | [_ClosureExpression_]\
25> &nbsp;&nbsp; &nbsp;&nbsp; | [_ContinueExpression_]\
26> &nbsp;&nbsp; &nbsp;&nbsp; | [_BreakExpression_]\
27> &nbsp;&nbsp; &nbsp;&nbsp; | [_RangeExpression_]\
28> &nbsp;&nbsp; &nbsp;&nbsp; | [_ReturnExpression_]\
29> &nbsp;&nbsp; &nbsp;&nbsp; | [_MacroInvocation_]\
30> &nbsp;&nbsp; )
31>
32> _ExpressionWithBlock_ :\
33> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup>[†](#expression-attributes)\
34> &nbsp;&nbsp; (\
35> &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; [_BlockExpression_]\
e1599b0c 36> &nbsp;&nbsp; &nbsp;&nbsp; | [_AsyncBlockExpression_]\
13cf67c4
XL
37> &nbsp;&nbsp; &nbsp;&nbsp; | [_UnsafeBlockExpression_]\
38> &nbsp;&nbsp; &nbsp;&nbsp; | [_LoopExpression_]\
39> &nbsp;&nbsp; &nbsp;&nbsp; | [_IfExpression_]\
40> &nbsp;&nbsp; &nbsp;&nbsp; | [_IfLetExpression_]\
41> &nbsp;&nbsp; &nbsp;&nbsp; | [_MatchExpression_]\
42> &nbsp;&nbsp; )
0531ce1d 43
8bb4bdeb
XL
44An expression may have two roles: it always produces a *value*, and it may have
45*effects* (otherwise known as "side effects"). An expression *evaluates to* a
46value, and has effects during *evaluation*. Many expressions contain
5869c6ff
XL
47sub-expressions, called the *operands* of the expression. The meaning of each
48kind of expression dictates several things:
8bb4bdeb 49
5869c6ff
XL
50* Whether or not to evaluate the operands when evaluating the expression
51* The order in which to evaluate the operands
52* How to combine the operands' values to obtain the value of the expression
8bb4bdeb
XL
53
54In this way, the structure of expressions dictates the structure of execution.
55Blocks are just another kind of expression, so blocks, statements, expressions,
56and blocks again can recursively nest inside each other to an arbitrary depth.
57
cdc7bbd5
XL
58> **Note**: We give names to the operands of expressions so that we may discuss
59> them, but these names are not stable and may be changed.
60
abe05a73
XL
61## Expression precedence
62
63The precedence of Rust operators and expressions is ordered as follows, going
83c7162d
XL
64from strong to weak. Binary Operators at the same precedence level are grouped
65in the order given by their associativity.
abe05a73
XL
66
67| Operator/Expression | Associativity |
68|-----------------------------|---------------------|
69| Paths | |
70| Method calls | |
71| Field expressions | left to right |
72| Function calls, array indexing | |
73| `?` | |
74| Unary `-` `*` `!` `&` `&mut` | |
83c7162d 75| `as` | left to right |
abe05a73
XL
76| `*` `/` `%` | left to right |
77| `+` `-` | left to right |
78| `<<` `>>` | left to right |
79| `&` | left to right |
80| `^` | left to right |
81| <code>&#124;</code> | left to right |
82| `==` `!=` `<` `>` `<=` `>=` | Require parentheses |
83| `&&` | left to right |
84| <code>&#124;&#124;</code> | left to right |
0531ce1d 85| `..` `..=` | Require parentheses |
abe05a73
XL
86| `=` `+=` `-=` `*=` `/=` `%=` <br> `&=` <code>&#124;=</code> `^=` `<<=` `>>=` | right to left |
87| `return` `break` closures | |
88
5869c6ff
XL
89## Evaluation order of operands
90
91The following list of expressions all evaluate their operands the same way, as
92described after the list. Other expressions either don't take operands or
93evaluate them conditionally as described on their respective pages.
94
95* Dereference expression
96* Error propagation expression
97* Negation expression
98* Arithmetic and logical binary operators
99* Comparison operators
100* Type cast expression
101* Grouped expression
102* Array expression
103* Await expression
104* Index expression
105* Tuple expression
106* Tuple index expression
107* Struct expression
5869c6ff
XL
108* Call expression
109* Method call expression
110* Field expression
111* Break expression
112* Range expression
113* Return expression
114
115The operands of these expressions are evaluated prior to applying the effects of
116the expression. Expressions taking multiple operands are evaluated left to right
117as written in the source code.
118
119> **Note**: Which subexpressions are the operands of an expression is
120> determined by expression precedence as per the previous section.
121
122For example, the two `next` method calls will always be called in the same
123order:
124
125```rust
126# // Using vec instead of array to avoid references
127# // since there is no stable owned array iterator
128# // at the time this example was written.
129let mut one_two = vec![1, 2].into_iter();
130assert_eq!(
131 (1, 2),
132 (one_two.next().unwrap(), one_two.next().unwrap())
133);
134```
135
136> **Note**: Since this is applied recursively, these expressions are also
137> evaluated from innermost to outermost, ignoring siblings until there are no
138> inner subexpressions.
139
ff7c6d11 140## Place Expressions and Value Expressions
8bb4bdeb 141
ff7c6d11 142Expressions are divided into two main categories: place expressions and
cdc7bbd5 143value expressions. Likewise within each expression, operands may occur
ff7c6d11
XL
144in either place context or value context. The evaluation of an expression
145depends both on its own category and the context it occurs within.
8bb4bdeb 146
ff7c6d11
XL
147A *place expression* is an expression that represents a memory location. These
148expressions are [paths] which refer to local variables, [static variables],
532ac7d7 149[dereferences][deref] (`*expr`), [array indexing] expressions (`expr[expr]`),
ff7c6d11
XL
150[field] references (`expr.f`) and parenthesized place expressions. All other
151expressions are value expressions.
8bb4bdeb 152
ff7c6d11
XL
153A *value expression* is an expression that represents an actual value.
154
532ac7d7
XL
155The following contexts are *place expression* contexts:
156
157* The left operand of an [assignment][assign] or [compound assignment]
158 expression.
159* The operand of a unary [borrow] or [dereference][deref] operator.
160* The operand of a field expression.
161* The indexed operand of an array indexing expression.
162* The operand of any [implicit borrow].
163* The initializer of a [let statement].
164* The [scrutinee] of an [`if let`], [`match`][match], or [`while let`]
165 expression.
166* The base of a [functional update] struct expression.
ff7c6d11
XL
167
168> Note: Historically, place expressions were called *lvalues* and value
169> expressions were called *rvalues*.
8bb4bdeb 170
7cac9316 171### Moved and copied types
8bb4bdeb 172
ff7c6d11
XL
173When a place expression is evaluated in a value expression context, or is bound
174by value in a pattern, it denotes the value held _in_ that memory location. If
175the type of that value implements [`Copy`], then the value will be copied. In
176the remaining situations if that type is [`Sized`], then it may be possible to
177move the value. Only the following place expressions may be moved out of:
7cac9316 178
ff7c6d11 179* [Variables] which are not currently borrowed.
f9f354fc 180* [Temporary values](#temporaries).
ff7c6d11
XL
181* [Fields][field] of a place expression which can be moved out of and
182 doesn't implement [`Drop`].
532ac7d7
XL
183* The result of [dereferencing][deref] an expression with type [`Box<T>`] and
184 that can also be moved out of.
7cac9316 185
ff7c6d11
XL
186Moving out of a place expression that evaluates to a local variable, the
187location is deinitialized and cannot be read from again until it is
188reinitialized. In all other cases, trying to use a place expression in a value
189expression context is an error.
7cac9316
XL
190
191### Mutability
192
ff7c6d11
XL
193For a place expression to be [assigned][assign] to, mutably [borrowed][borrow],
194[implicitly mutably borrowed], or bound to a pattern containing `ref mut` it
195must be _mutable_. We call these *mutable place expressions*. In contrast,
196other place expressions are called *immutable place expressions*.
7cac9316 197
ff7c6d11 198The following expressions can be mutable place expression contexts:
7cac9316 199
ff7c6d11
XL
200* Mutable [variables], which are not currently borrowed.
201* [Mutable `static` items].
202* [Temporary values].
203* [Fields][field], this evaluates the subexpression in a mutable place
204 expression context.
532ac7d7 205* [Dereferences][deref] of a `*mut T` pointer.
7cac9316 206* Dereference of a variable, or field of a variable, with type `&mut T`. Note:
ff7c6d11 207 This is an exception to the requirement of the next rule.
7cac9316 208* Dereferences of a type that implements `DerefMut`, this then requires that
ff7c6d11 209 the value being dereferenced is evaluated is a mutable place expression context.
f035d41b 210* [Array indexing] of a type that implements `IndexMut`, this
ff7c6d11
XL
211 then evaluates the value being indexed, but not the index, in mutable place
212 expression context.
7cac9316 213
f9f354fc 214### Temporaries
7cac9316 215
ff7c6d11
XL
216When using a value expression in most place expression contexts, a temporary
217unnamed memory location is created initialized to that value and the expression
f9f354fc
XL
218evaluates to that location instead, except if [promoted] to a `static`. The
219[drop scope] of the temporary is usually the end of the enclosing statement.
8bb4bdeb 220
7cac9316 221### Implicit Borrows
8bb4bdeb 222
ff7c6d11 223Certain expressions will treat an expression as a place expression by implicitly
b7449926 224borrowing it. For example, it is possible to compare two unsized [slices][slice] for
ea8adc8c 225equality directly, because the `==` operator implicitly borrows it's operands:
7cac9316
XL
226
227```rust
228# let c = [1, 2, 3];
229# let d = vec![1, 2, 3];
230let a: &[i32];
231let b: &[i32];
232# a = &c;
233# b = &d;
234// ...
235*a == *b;
236// Equivalent form:
237::std::cmp::PartialEq::eq(&*a, &*b);
238```
239
240Implicit borrows may be taken in the following expressions:
241
ea8adc8c
XL
242* Left operand in [method-call] expressions.
243* Left operand in [field] expressions.
244* Left operand in [call expressions].
245* Left operand in [array indexing] expressions.
532ac7d7 246* Operand of the [dereference operator][deref] (`*`).
ea8adc8c
XL
247* Operands of [comparison].
248* Left operands of the [compound assignment].
7cac9316 249
7cac9316
XL
250## Overloading Traits
251
252Many of the following operators and expressions can also be overloaded for
ff7c6d11 253other types using traits in `std::ops` or `std::cmp`. These traits also
7cac9316 254exist in `core::ops` and `core::cmp` with the same names.
8bb4bdeb 255
13cf67c4
XL
256## Expression Attributes
257
258[Outer attributes][_OuterAttribute_] before an expression are allowed only in
259a few specific cases:
260
261* Before an expression used as a [statement].
262* Elements of [array expressions], [tuple expressions], [call expressions],
6a06907d 263 and tuple-style [struct] expressions.
13cf67c4
XL
264 <!--
265 These were likely stabilized inadvertently.
266 See https://github.com/rust-lang/rust/issues/32796 and
267 https://github.com/rust-lang/rust/issues/15701
268 -->
269* The tail expression of [block expressions].
270<!-- Keep list in sync with block-expr.md -->
271
272They are never allowed before:
13cf67c4
XL
273* [Range][_RangeExpression_] expressions.
274* Binary operator expressions ([_ArithmeticOrLogicalExpression_],
275 [_ComparisonExpression_], [_LazyBooleanExpression_], [_TypeCastExpression_],
276 [_AssignmentExpression_], [_CompoundAssignmentExpression_]).
277
278
416331ca
XL
279[block expressions]: expressions/block-expr.md
280[call expressions]: expressions/call-expr.md
416331ca
XL
281[field]: expressions/field-expr.md
282[functional update]: expressions/struct-expr.md#functional-update-syntax
283[`if let`]: expressions/if-expr.md#if-let-expressions
284[match]: expressions/match-expr.md
285[method-call]: expressions/method-call-expr.md
286[paths]: expressions/path-expr.md
287[struct]: expressions/struct-expr.md
288[tuple expressions]: expressions/tuple-expr.md
289[`while let`]: expressions/loop-expr.md#predicate-pattern-loops
290
291[array expressions]: expressions/array-expr.md
292[array indexing]: expressions/array-expr.md#array-and-slice-indexing-expressions
293
294[assign]: expressions/operator-expr.md#assignment-expressions
295[borrow]: expressions/operator-expr.md#borrow-operators
296[comparison]: expressions/operator-expr.md#comparison-operators
297[compound assignment]: expressions/operator-expr.md#compound-assignment-expressions
298[deref]: expressions/operator-expr.md#the-dereference-operator
299
300[destructors]: destructors.md
f9f354fc
XL
301[drop scope]: destructors.md#drop-scopes
302
303[`Box<T>`]: ../std/boxed/struct.Box.html
416331ca
XL
304[`Copy`]: special-types-and-traits.md#copy
305[`Drop`]: special-types-and-traits.md#drop
306[`Sized`]: special-types-and-traits.md#sized
ff7c6d11
XL
307[implicit borrow]: #implicit-borrows
308[implicitly mutably borrowed]: #implicit-borrows
f9f354fc 309[interior mutability]: interior-mutability.md
416331ca
XL
310[let statement]: statements.md#let-statements
311[Mutable `static` items]: items/static-items.md#mutable-statics
312[scrutinee]: glossary.md#scrutinee
f9f354fc 313[promoted]: destructors.md#constant-promotion
416331ca
XL
314[slice]: types/slice.md
315[statement]: statements.md
316[static variables]: items/static-items.md
f9f354fc 317[Temporary values]: #temporaries
416331ca
XL
318[Variables]: variables.md
319
416331ca
XL
320[_ArithmeticOrLogicalExpression_]: expressions/operator-expr.md#arithmetic-and-logical-binary-operators
321[_ArrayExpression_]: expressions/array-expr.md
e1599b0c
XL
322[_AsyncBlockExpression_]: expressions/block-expr.md#async-blocks
323[_AwaitExpression_]: expressions/await-expr.md
416331ca
XL
324[_AssignmentExpression_]: expressions/operator-expr.md#assignment-expressions
325[_BlockExpression_]: expressions/block-expr.md
326[_BreakExpression_]: expressions/loop-expr.md#break-expressions
327[_CallExpression_]: expressions/call-expr.md
328[_ClosureExpression_]: expressions/closure-expr.md
329[_ComparisonExpression_]: expressions/operator-expr.md#comparison-operators
330[_CompoundAssignmentExpression_]: expressions/operator-expr.md#compound-assignment-expressions
331[_ContinueExpression_]: expressions/loop-expr.md#continue-expressions
416331ca
XL
332[_FieldExpression_]: expressions/field-expr.md
333[_GroupedExpression_]: expressions/grouped-expr.md
334[_IfExpression_]: expressions/if-expr.md#if-expressions
335[_IfLetExpression_]: expressions/if-expr.md#if-let-expressions
336[_IndexExpression_]: expressions/array-expr.md#array-and-slice-indexing-expressions
337[_LazyBooleanExpression_]: expressions/operator-expr.md#lazy-boolean-operators
338[_LiteralExpression_]: expressions/literal-expr.md
339[_LoopExpression_]: expressions/loop-expr.md
340[_MacroInvocation_]: macros.md#macro-invocation
341[_MatchExpression_]: expressions/match-expr.md
342[_MethodCallExpression_]: expressions/method-call-expr.md
343[_OperatorExpression_]: expressions/operator-expr.md
344[_OuterAttribute_]: attributes.md
345[_PathExpression_]: expressions/path-expr.md
346[_RangeExpression_]: expressions/range-expr.md
347[_ReturnExpression_]: expressions/return-expr.md
348[_StructExpression_]: expressions/struct-expr.md
349[_TupleExpression_]: expressions/tuple-expr.md
350[_TupleIndexingExpression_]: expressions/tuple-expr.md#tuple-indexing-expressions
351[_TypeCastExpression_]: expressions/operator-expr.md#type-cast-expressions
352[_UnsafeBlockExpression_]: expressions/block-expr.md#unsafe-blocks