Skip to content

Commit

Permalink
Merge pull request #888 from Havvy/exe-order
Browse files Browse the repository at this point in the history
Document execution order
  • Loading branch information
Havvy authored Jan 14, 2021
2 parents 4df4225 + 6a17a57 commit 20d9fe6
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 18 deletions.
63 changes: 57 additions & 6 deletions src/expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,12 @@
An expression may have two roles: it always produces a *value*, and it may have
*effects* (otherwise known as "side effects"). An expression *evaluates to* a
value, and has effects during *evaluation*. Many expressions contain
sub-expressions (operands). The meaning of each kind of expression dictates
several things:
sub-expressions, called the *operands* of the expression. The meaning of each
kind of expression dictates several things:

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

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

## Evaluation order of operands

The following list of expressions all evaluate their operands the same way, as
described after the list. Other expressions either don't take operands or
evaluate them conditionally as described on their respective pages.

* Dereference expression
* Error propagation expression
* Negation expression
* Arithmetic and logical binary operators
* Comparison operators
* Type cast expression
* Grouped expression
* Array expression
* Await expression
* Index expression
* Tuple expression
* Tuple index expression
* Struct expression
* Enumeration variant expression
* Call expression
* Method call expression
* Field expression
* Break expression
* Range expression
* Return expression

The operands of these expressions are evaluated prior to applying the effects of
the expression. Expressions taking multiple operands are evaluated left to right
as written in the source code.

> **Note**: Which subexpressions are the operands of an expression is
> determined by expression precedence as per the previous section.
For example, the two `next` method calls will always be called in the same
order:

```rust
# // Using vec instead of array to avoid references
# // since there is no stable owned array iterator
# // at the time this example was written.
let mut one_two = vec![1, 2].into_iter();
assert_eq!(
(1, 2),
(one_two.next().unwrap(), one_two.next().unwrap())
);
```

> **Note**: Since this is applied recursively, these expressions are also
> evaluated from innermost to outermost, ignoring siblings until there are no
> inner subexpressions.
## Place Expressions and Value Expressions

Expressions are divided into two main categories: place expressions and
Expand Down
41 changes: 29 additions & 12 deletions src/expressions/operator-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -409,20 +409,35 @@ halfway between two floating point numbers.
> _AssignmentExpression_ :\
> &nbsp;&nbsp; [_Expression_] `=` [_Expression_]
An _assignment expression_ consists of a [place expression] followed by an
equals sign (`=`) and a [value expression]. Such an expression always has
the [`unit` type].

Evaluating an assignment expression [drops](../destructors.md) the left-hand
operand, unless it's an uninitialized local variable or field of a local variable,
and [either copies or moves](../expressions.md#moved-and-copied-types) its
right-hand operand to its left-hand operand. The left-hand operand must be a
place expression: using a value expression results in a compiler error, rather
An *assignment expression* moves a value into a specified place.

An assignment expression consists of a [mutable] [place expression], the
*assigned place operand*, followed by an equals sign (`=`) and a [value
expression], the *assigned value operand*.

Unlike other place operands, the assigned place operand must be a place
expression. Attempting to use a value expression is a compiler error rather
than promoting it to a temporary.

Evaluating assignment expressions begins by evaluating its operands. The
assigned value operand is evaluated first, followed by the assigned place
operand.

> **Note**: This is different than other expressions in that the right operand
> is evaluated before the left one.
It then has the effect of first [dropping] the value at the assigned place,
unless the place is an uninitialized local variable or an uninitialized field of
a local variable. Next it either [copies or moves] the assigned value to the
assigned place.

An assignment expression always produces [the unit value][unit].

Example:

```rust
# let mut x = 0;
# let y = 0;
let mut x = 0;
let y = 0;
x = y;
```

Expand Down Expand Up @@ -506,13 +521,15 @@ dependency.

</div>

[copies or moves]: ../expressions.md#moved-and-copied-types
[dropping]: ../destructors.md
[mutable]: ../expressions.md#mutability
[place expression]: ../expressions.md#place-expressions-and-value-expressions
[unit]: ../types/tuple.md
[value expression]: ../expressions.md#place-expressions-and-value-expressions
[temporary value]: ../expressions.md#temporaries
[this test]: https://github.com/rust-lang/rust/blob/master/src/test/ui/expr/compound-assignment/eval-order.rs
[float-float]: https://github.com/rust-lang/rust/issues/15536
[`unit` type]: ../types/tuple.md
[Function pointer]: ../types/function-pointer.md
[Function item]: ../types/function-item.md

Expand Down

0 comments on commit 20d9fe6

Please sign in to comment.