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