Skip to content

Commit 20d9fe6

Browse files
authored
Merge pull request #888 from Havvy/exe-order
Document execution order
2 parents 4df4225 + 6a17a57 commit 20d9fe6

File tree

2 files changed

+86
-18
lines changed

2 files changed

+86
-18
lines changed

src/expressions.md

+57-6
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,12 @@
4545
An expression may have two roles: it always produces a *value*, and it may have
4646
*effects* (otherwise known as "side effects"). An expression *evaluates to* a
4747
value, and has effects during *evaluation*. Many expressions contain
48-
sub-expressions (operands). The meaning of each kind of expression dictates
49-
several things:
48+
sub-expressions, called the *operands* of the expression. The meaning of each
49+
kind of expression dictates several things:
5050

51-
* Whether or not to evaluate the sub-expressions when evaluating the expression
52-
* The order in which to evaluate the sub-expressions
53-
* How to combine the sub-expressions' values to obtain the value of the
54-
expression
51+
* Whether or not to evaluate the operands when evaluating the expression
52+
* The order in which to evaluate the operands
53+
* How to combine the operands' values to obtain the value of the expression
5554

5655
In this way, the structure of expressions dictates the structure of execution.
5756
Blocks are just another kind of expression, so blocks, statements, expressions,
@@ -85,6 +84,58 @@ in the order given by their associativity.
8584
| `=` `+=` `-=` `*=` `/=` `%=` <br> `&=` <code>&#124;=</code> `^=` `<<=` `>>=` | right to left |
8685
| `return` `break` closures | |
8786

87+
## Evaluation order of operands
88+
89+
The following list of expressions all evaluate their operands the same way, as
90+
described after the list. Other expressions either don't take operands or
91+
evaluate them conditionally as described on their respective pages.
92+
93+
* Dereference expression
94+
* Error propagation expression
95+
* Negation expression
96+
* Arithmetic and logical binary operators
97+
* Comparison operators
98+
* Type cast expression
99+
* Grouped expression
100+
* Array expression
101+
* Await expression
102+
* Index expression
103+
* Tuple expression
104+
* Tuple index expression
105+
* Struct expression
106+
* Enumeration variant expression
107+
* Call expression
108+
* Method call expression
109+
* Field expression
110+
* Break expression
111+
* Range expression
112+
* Return expression
113+
114+
The operands of these expressions are evaluated prior to applying the effects of
115+
the expression. Expressions taking multiple operands are evaluated left to right
116+
as written in the source code.
117+
118+
> **Note**: Which subexpressions are the operands of an expression is
119+
> determined by expression precedence as per the previous section.
120+
121+
For example, the two `next` method calls will always be called in the same
122+
order:
123+
124+
```rust
125+
# // Using vec instead of array to avoid references
126+
# // since there is no stable owned array iterator
127+
# // at the time this example was written.
128+
let mut one_two = vec![1, 2].into_iter();
129+
assert_eq!(
130+
(1, 2),
131+
(one_two.next().unwrap(), one_two.next().unwrap())
132+
);
133+
```
134+
135+
> **Note**: Since this is applied recursively, these expressions are also
136+
> evaluated from innermost to outermost, ignoring siblings until there are no
137+
> inner subexpressions.
138+
88139
## Place Expressions and Value Expressions
89140

90141
Expressions are divided into two main categories: place expressions and

src/expressions/operator-expr.md

+29-12
Original file line numberDiff line numberDiff line change
@@ -409,20 +409,35 @@ halfway between two floating point numbers.
409409
> _AssignmentExpression_ :\
410410
> &nbsp;&nbsp; [_Expression_] `=` [_Expression_]
411411
412-
An _assignment expression_ consists of a [place expression] followed by an
413-
equals sign (`=`) and a [value expression]. Such an expression always has
414-
the [`unit` type].
415-
416-
Evaluating an assignment expression [drops](../destructors.md) the left-hand
417-
operand, unless it's an uninitialized local variable or field of a local variable,
418-
and [either copies or moves](../expressions.md#moved-and-copied-types) its
419-
right-hand operand to its left-hand operand. The left-hand operand must be a
420-
place expression: using a value expression results in a compiler error, rather
412+
An *assignment expression* moves a value into a specified place.
413+
414+
An assignment expression consists of a [mutable] [place expression], the
415+
*assigned place operand*, followed by an equals sign (`=`) and a [value
416+
expression], the *assigned value operand*.
417+
418+
Unlike other place operands, the assigned place operand must be a place
419+
expression. Attempting to use a value expression is a compiler error rather
421420
than promoting it to a temporary.
422421

422+
Evaluating assignment expressions begins by evaluating its operands. The
423+
assigned value operand is evaluated first, followed by the assigned place
424+
operand.
425+
426+
> **Note**: This is different than other expressions in that the right operand
427+
> is evaluated before the left one.
428+
429+
It then has the effect of first [dropping] the value at the assigned place,
430+
unless the place is an uninitialized local variable or an uninitialized field of
431+
a local variable. Next it either [copies or moves] the assigned value to the
432+
assigned place.
433+
434+
An assignment expression always produces [the unit value][unit].
435+
436+
Example:
437+
423438
```rust
424-
# let mut x = 0;
425-
# let y = 0;
439+
let mut x = 0;
440+
let y = 0;
426441
x = y;
427442
```
428443

@@ -506,13 +521,15 @@ dependency.
506521

507522
</div>
508523

524+
[copies or moves]: ../expressions.md#moved-and-copied-types
525+
[dropping]: ../destructors.md
509526
[mutable]: ../expressions.md#mutability
510527
[place expression]: ../expressions.md#place-expressions-and-value-expressions
528+
[unit]: ../types/tuple.md
511529
[value expression]: ../expressions.md#place-expressions-and-value-expressions
512530
[temporary value]: ../expressions.md#temporaries
513531
[this test]: https://github.com/rust-lang/rust/blob/master/src/test/ui/expr/compound-assignment/eval-order.rs
514532
[float-float]: https://github.com/rust-lang/rust/issues/15536
515-
[`unit` type]: ../types/tuple.md
516533
[Function pointer]: ../types/function-pointer.md
517534
[Function item]: ../types/function-item.md
518535

0 commit comments

Comments
 (0)