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 > **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.
61 ## Expression precedence
63 The precedence of Rust operators and expressions is ordered as follows, going
64 from strong to weak. Binary Operators at the same precedence level are grouped
65 in the order given by their associativity.
67 | Operator/Expression | Associativity |
68 |-----------------------------|---------------------|
71 | Field expressions | left to right |
72 | Function calls, array indexing | |
74 | Unary `-` `*` `!` `&` `&mut` | |
75 | `as` | left to right |
76 | `*` `/` `%` | left to right |
77 | `+` `-` | left to right |
78 | `<<` `>>` | left to right |
79 | `&` | left to right |
80 | `^` | left to right |
81 | <code>|</code> | left to right |
82 | `==` `!=` `<` `>` `<=` `>=` | Require parentheses |
83 | `&&` | left to right |
84 | <code>||</code> | left to right |
85 | `..` `..=` | Require parentheses |
86 | `=` `+=` `-=` `*=` `/=` `%=` <br> `&=` <code>|=</code> `^=` `<<=` `>>=` | right to left |
87 | `return` `break` closures | |
89 ## Evaluation order of operands
91 The following list of expressions all evaluate their operands the same way, as
92 described after the list. Other expressions either don't take operands or
93 evaluate them conditionally as described on their respective pages.
95 * Dereference expression
96 * Error propagation expression
98 * Arithmetic and logical binary operators
99 * Comparison operators
100 * Type cast expression
106 * Tuple index expression
109 * Method call expression
115 The operands of these expressions are evaluated prior to applying the effects of
116 the expression. Expressions taking multiple operands are evaluated left to right
117 as written in the source code.
119 > **Note**: Which subexpressions are the operands of an expression is
120 > determined by expression precedence as per the previous section.
122 For example, the two `next` method calls will always be called in the same
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.
129 let mut one_two = vec![1, 2].into_iter();
132 (one_two.next().unwrap(), one_two.next().unwrap())
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.
140 ## Place Expressions and Value Expressions
142 Expressions are divided into two main categories: place expressions and
143 value expressions. Likewise within each expression, operands may occur
144 in either place context or value context. The evaluation of an expression
145 depends both on its own category and the context it occurs within.
147 A *place expression* is an expression that represents a memory location. These
148 expressions are [paths] which refer to local variables, [static variables],
149 [dereferences][deref] (`*expr`), [array indexing] expressions (`expr[expr]`),
150 [field] references (`expr.f`) and parenthesized place expressions. All other
151 expressions are value expressions.
153 A *value expression* is an expression that represents an actual value.
155 The following contexts are *place expression* contexts:
157 * The left operand of an [assignment][assign] or [compound assignment]
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`]
166 * The base of a [functional update] struct expression.
168 > Note: Historically, place expressions were called *lvalues* and value
169 > expressions were called *rvalues*.
171 ### Moved and copied types
173 When a place expression is evaluated in a value expression context, or is bound
174 by value in a pattern, it denotes the value held _in_ that memory location. If
175 the type of that value implements [`Copy`], then the value will be copied. In
176 the remaining situations if that type is [`Sized`], then it may be possible to
177 move the value. Only the following place expressions may be moved out of:
179 * [Variables] which are not currently borrowed.
180 * [Temporary values](#temporaries).
181 * [Fields][field] of a place expression which can be moved out of and
182 doesn't implement [`Drop`].
183 * The result of [dereferencing][deref] an expression with type [`Box<T>`] and
184 that can also be moved out of.
186 Moving out of a place expression that evaluates to a local variable, the
187 location is deinitialized and cannot be read from again until it is
188 reinitialized. In all other cases, trying to use a place expression in a value
189 expression context is an error.
193 For a place expression to be [assigned][assign] to, mutably [borrowed][borrow],
194 [implicitly mutably borrowed], or bound to a pattern containing `ref mut` it
195 must be _mutable_. We call these *mutable place expressions*. In contrast,
196 other place expressions are called *immutable place expressions*.
198 The following expressions can be mutable place expression contexts:
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
205 * [Dereferences][deref] of a `*mut T` pointer.
206 * Dereference of a variable, or field of a variable, with type `&mut T`. Note:
207 This is an exception to the requirement of the next rule.
208 * Dereferences of a type that implements `DerefMut`, this then requires that
209 the value being dereferenced is evaluated is a mutable place expression context.
210 * [Array indexing] of a type that implements `IndexMut`, this
211 then evaluates the value being indexed, but not the index, in mutable place
216 When using a value expression in most place expression contexts, a temporary
217 unnamed memory location is created initialized to that value and the expression
218 evaluates 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.
223 Certain expressions will treat an expression as a place expression by implicitly
224 borrowing it. For example, it is possible to compare two unsized [slices][slice] for
225 equality directly, because the `==` operator implicitly borrows it's operands:
229 # let d = vec![1, 2, 3];
237 ::std::cmp::PartialEq::eq(&*a, &*b);
240 Implicit borrows may be taken in the following expressions:
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.
246 * Operand of the [dereference operator][deref] (`*`).
247 * Operands of [comparison].
248 * Left operands of the [compound assignment].
250 ## Overloading Traits
252 Many of the following operators and expressions can also be overloaded for
253 other types using traits in `std::ops` or `std::cmp`. These traits also
254 exist in `core::ops` and `core::cmp` with the same names.
256 ## Expression Attributes
258 [Outer attributes][_OuterAttribute_] before an expression are allowed only in
259 a few specific cases:
261 * Before an expression used as a [statement].
262 * Elements of [array expressions], [tuple expressions], [call expressions],
263 and tuple-style [struct] expressions.
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
269 * The tail expression of [block expressions].
270 <!-- Keep list in sync with block-expr.md -->
272 They are never allowed before:
273 * [Range][_RangeExpression_] expressions.
274 * Binary operator expressions ([_ArithmeticOrLogicalExpression_],
275 [_ComparisonExpression_], [_LazyBooleanExpression_], [_TypeCastExpression_],
276 [_AssignmentExpression_], [_CompoundAssignmentExpression_]).
279 [block expressions]: expressions/block-expr.md
280 [call expressions]: expressions/call-expr.md
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
291 [array expressions]: expressions/array-expr.md
292 [array indexing]: expressions/array-expr.md#array-and-slice-indexing-expressions
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
300 [destructors]: destructors.md
301 [drop scope]: destructors.md#drop-scopes
303 [`Box<T>`]: ../std/boxed/struct.Box.html
304 [`Copy`]: special-types-and-traits.md#copy
305 [`Drop`]: special-types-and-traits.md#drop
306 [`Sized`]: special-types-and-traits.md#sized
307 [implicit borrow]: #implicit-borrows
308 [implicitly mutably borrowed]: #implicit-borrows
309 [interior mutability]: interior-mutability.md
310 [let statement]: statements.md#let-statements
311 [Mutable `static` items]: items/static-items.md#mutable-statics
312 [scrutinee]: glossary.md#scrutinee
313 [promoted]: destructors.md#constant-promotion
314 [slice]: types/slice.md
315 [statement]: statements.md
316 [static variables]: items/static-items.md
317 [Temporary values]: #temporaries
318 [Variables]: variables.md
320 [_ArithmeticOrLogicalExpression_]: expressions/operator-expr.md#arithmetic-and-logical-binary-operators
321 [_ArrayExpression_]: expressions/array-expr.md
322 [_AsyncBlockExpression_]: expressions/block-expr.md#async-blocks
323 [_AwaitExpression_]: expressions/await-expr.md
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
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