Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: rust-lang/reference
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 93b921c7d3213d38d920f7f905a3bec093d2217d
Choose a base ref
...
head repository: rust-lang/reference
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 4249fb411dd27f945e2881eb0378044b94cee06f
Choose a head ref

Commits on Jan 29, 2025

  1. Copy the full SHA
    92c5a32 View commit details
  2. Copy the full SHA
    7dae7c6 View commit details
  3. Copy the full SHA
    fc7622c View commit details
  4. Copy the full SHA
    1013e20 View commit details
  5. Copy the full SHA
    5f86d06 View commit details
  6. Copy the full SHA
    e88f411 View commit details
  7. Copy the full SHA
    3698cd5 View commit details
  8. Fix tests on non-x86_64 targets

    ehuss committed Jan 29, 2025
    Copy the full SHA
    19f3c52 View commit details
  9. Fix incorrect syntax in example

    ehuss committed Jan 29, 2025
    Copy the full SHA
    1b7a454 View commit details
  10. Reformat the assembly tests a little

    This is intended to make them render consistently (no unusual spacing),
    to have formatting that is a little more consistent with the style guide,
    to fit width-wise, to include explicit ERROR annotations.
    ehuss committed Jan 29, 2025
    Copy the full SHA
    487f69a View commit details
  11. Merge pull request #1648 from chorman0773/spec-inline-assembly-tests

    Spec inline assembly tests
    ehuss authored Jan 29, 2025
    Copy the full SHA
    7982061 View commit details

Commits on Jan 30, 2025

  1. Merge pull request #1723 from ehuss/exclude-summary

    Exclude the test summary from the search index
    traviscross authored Jan 30, 2025
    Copy the full SHA
    75df12e View commit details
  2. Copy the full SHA
    9134fe5 View commit details
  3. Copy the full SHA
    9446598 View commit details
  4. Add identifier syntax to call-expr

    chorman0773 authored and ehuss committed Jan 30, 2025
    Copy the full SHA
    60b1720 View commit details
  5. Copy the full SHA
    aae16d5 View commit details
  6. Copy the full SHA
    c4ebffe View commit details
  7. Copy the full SHA
    2e00df4 View commit details
  8. Copy the full SHA
    735991b View commit details
  9. Add identifier syntax to path-expr, range-expr, return-expr, struct-e…

    …xpr, tuple-expr, and underscore-expr
    chorman0773 authored and ehuss committed Jan 30, 2025
    Copy the full SHA
    54ed666 View commit details
  10. Copy the full SHA
    a7b725b View commit details
  11. Copy the full SHA
    53c23d7 View commit details
  12. Copy the full SHA
    b25591a View commit details
  13. Fix spelling from behaviour to behavior

    chorman0773 authored and ehuss committed Jan 30, 2025
    Copy the full SHA
    1f38602 View commit details
  14. Copy the full SHA
    eed74c2 View commit details
  15. Apply suggestions from code review

    Co-authored-by: Travis Cross <tc@traviscross.com>
    2 people authored and ehuss committed Jan 30, 2025
    Copy the full SHA
    fbe355b View commit details

Commits on Jan 31, 2025

  1. Adjust rules next to headers

    ehuss committed Jan 31, 2025
    Copy the full SHA
    853ccb4 View commit details
  2. Add some missing rules

    ehuss committed Jan 31, 2025
    Copy the full SHA
    efe16bf View commit details
  3. Adjust some rule names for clarity

    This adjusts some rule names to be more explicit about what they are
    for.
    ehuss committed Jan 31, 2025
    Copy the full SHA
    3e57a06 View commit details
  4. Merge pull request #1591 from chorman0773/spec-add-identifiers-exprs

    Add Spec Identifier Syntax to expressions.md and subchapters
    ehuss authored Jan 31, 2025
    Copy the full SHA
    4249fb4 View commit details
3 changes: 3 additions & 0 deletions book.toml
Original file line number Diff line number Diff line change
@@ -10,6 +10,9 @@ git-repository-url = "https://github.com/rust-lang/reference/"
edit-url-template = "https://github.com/rust-lang/reference/edit/master/{path}"
smart-punctuation = true

[output.html.search.chapter]
"test-summary.md" = { enable = false }

[output.html.redirect]
"/expressions/enum-variant-expr.html" = "struct-expr.html"
"/unsafe-blocks.html" = "unsafe-keyword.html"
48 changes: 47 additions & 1 deletion src/expressions.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
r[expr]
# Expressions

r[expr.syntax]
> **<sup>Syntax</sup>**\
> _Expression_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; _ExpressionWithoutBlock_\
@@ -43,20 +45,29 @@
> &nbsp;&nbsp; &nbsp;&nbsp; | [_MatchExpression_]\
> &nbsp;&nbsp; )
r[expr.intro]
An expression may have two roles: it always produces a *value*, and it may have *effects* (otherwise known as "side effects").

r[expr.evaluation]
An expression *evaluates to* a value, and has effects during *evaluation*.

r[expr.operands]
Many expressions contain sub-expressions, called the *operands* of the expression.

r[expr.behavior]
The meaning of each kind of expression dictates several things:

* 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

r[expr.structure]
In this way, the structure of expressions dictates the structure of execution.
Blocks are just another kind of expression, so blocks, statements, expressions, and blocks again can recursively nest inside each other to an arbitrary depth.

> **Note**: We give names to the operands of expressions so that we may discuss them, but these names are not stable and may be changed.
r[expr.precedence]
## Expression precedence

The precedence of Rust operators and expressions is ordered as follows, going from strong to weak.
@@ -84,8 +95,10 @@ Binary Operators at the same precedence level are grouped in the order given by
| `=` `+=` `-=` `*=` `/=` `%=` <br> `&=` <code>&#124;=</code> `^=` `<<=` `>>=` | right to left |
| `return` `break` closures | |

r[expr.operand-order]
## Evaluation order of operands

r[expr.operand-order.default]
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.

@@ -109,6 +122,7 @@ Other expressions either don't take operands or evaluate them conditionally as d
* Range expression
* Return expression

r[expr.operand-order.operands-before-primary]
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.

@@ -130,19 +144,28 @@ assert_eq!(

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

r[expr.place-value.intro]
Expressions are divided into two main categories: place expressions and value expressions;
there is also a third, minor category of expressions called assignee expressions.
Within each expression, operands may likewise occur in either place context or value context.
The evaluation of an expression depends both on its own category and the context it occurs within.

r[expr.place-value.place-memory-location]
A *place expression* is an expression that represents a memory location.

r[expr.place-value.place-expr-kinds]
These expressions are [paths] which refer to local variables, [static variables], [dereferences][deref] (`*expr`), [array indexing] expressions (`expr[expr]`), [field] references (`expr.f`) and parenthesized place expressions.

r[expr.place-value.value-expr-kinds]
All other expressions are value expressions.

r[expr.place-value.value-result]
A *value expression* is an expression that represents an actual value.

r[expr.place-value.place-context]
The following contexts are *place expression* contexts:

* The left operand of a [compound assignment] expression.
@@ -157,6 +180,7 @@ The following contexts are *place expression* contexts:

> Note: Historically, place expressions were called *lvalues* and value expressions were called *rvalues*.
r[expr.place-value.assignee]
An *assignee expression* is an expression that appears in the left operand of an [assignment][assign] expression.
Explicitly, the assignee expressions are:

@@ -169,29 +193,44 @@ Explicitly, the assignee expressions are:
fields).
- [Unit structs][_StructExpression_].

r[expr.place-value.parenthesis]
Arbitrary parenthesisation is permitted inside assignee expressions.

r[expr.move]
### Moved and copied types

r[expr.move.intro]
When a place expression is evaluated in a value expression context, or is bound by value in a pattern, it denotes the value held _in_ that memory location.

r[expr.move.copy]
If the type of that value implements [`Copy`], then the value will be copied.

r[expr.move.requires-sized]
In the remaining situations, if that type is [`Sized`], then it may be possible to move the value.

r[expr.move.movable-place]
Only the following place expressions may be moved out of:

* [Variables] which are not currently borrowed.
* [Temporary values](#temporaries).
* [Fields][field] of a place expression which can be moved out of and don't implement [`Drop`].
* The result of [dereferencing][deref] an expression with type [`Box<T>`] and that can also be moved out of.

r[expr.move.deinitialization]
After moving out of a place expression that evaluates to a local variable, the location is deinitialized and cannot be read from again until it is reinitialized.

r[expr.move.place-invalid]
In all other cases, trying to use a place expression in a value expression context is an error.

r[expr.mut]
### Mutability

r[expr.mut.intro]
For a place expression to be [assigned][assign] to, mutably [borrowed][borrow], [implicitly mutably borrowed], or bound to a pattern containing `ref mut`, it must be _mutable_.
We call these *mutable place expressions*.
In contrast, other place expressions are called *immutable place expressions*.

r[expr.mut.valid-places]
The following expressions can be mutable place expression contexts:

* Mutable [variables] which are not currently borrowed.
@@ -206,14 +245,17 @@ The following expressions can be mutable place expression contexts:
* [Array indexing] of a type that implements `IndexMut`:
this then evaluates the value being indexed, but not the index, in mutable place expression context.

r[expr.temporary]
### Temporaries

When using a value expression in most place expression contexts, a temporary unnamed memory location is created and initialized to that value.
The expression evaluates to that location instead, except if [promoted] to a `static`.
The [drop scope] of the temporary is usually the end of the enclosing statement.

r[expr.implicit-borrow]
### Implicit Borrows

r[expr.implicit-borrow-intro]
Certain expressions will treat an expression as a place expression by implicitly borrowing it.
For example, it is possible to compare two unsized [slices][slice] for equality directly, because the `==` operator implicitly borrows its operands:

@@ -230,6 +272,7 @@ let b: &[i32];
::std::cmp::PartialEq::eq(&*a, &*b);
```

r[expr.implicit-borrow.application]
Implicit borrows may be taken in the following expressions:

* Left operand in [method-call] expressions.
@@ -240,25 +283,28 @@ Implicit borrows may be taken in the following expressions:
* Operands of [comparison].
* Left operands of the [compound assignment].

r[expr.overload]
## Overloading Traits

Many of the following operators and expressions can also be overloaded for other types using traits in `std::ops` or `std::cmp`.
These traits also exist in `core::ops` and `core::cmp` with the same names.

r[expr.attr]
## Expression Attributes

r[expr.attr.restriction]
[Outer attributes][_OuterAttribute_] before an expression are allowed only in a few specific cases:

* Before an expression used as a [statement].
* Elements of [array expressions], [tuple expressions], [call expressions], and tuple-style [struct] expressions.
* The tail expression of [block expressions].
<!-- Keep list in sync with block-expr.md -->

r[expr.attr.never-before]
They are never allowed before:
* [Range][_RangeExpression_] expressions.
* Binary operator expressions ([_ArithmeticOrLogicalExpression_], [_ComparisonExpression_], [_LazyBooleanExpression_], [_TypeCastExpression_], [_AssignmentExpression_], [_CompoundAssignmentExpression_]).


[block expressions]: expressions/block-expr.md
[call expressions]: expressions/call-expr.md
[field]: expressions/field-expr.md
31 changes: 31 additions & 0 deletions src/expressions/array-expr.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
r[expr.array]
# Array and array index expressions

## Array expressions

r[expr.array.syntax]
> **<sup>Syntax</sup>**\
> _ArrayExpression_ :\
> &nbsp;&nbsp; `[` _ArrayElements_<sup>?</sup> `]`
@@ -10,23 +12,45 @@
> &nbsp;&nbsp; &nbsp;&nbsp; [_Expression_] ( `,` [_Expression_] )<sup>\*</sup> `,`<sup>?</sup>\
> &nbsp;&nbsp; | [_Expression_] `;` [_Expression_]
r[expr.array.constructor]
*Array expressions* construct [arrays][array].
Array expressions come in two forms.

r[expr.array.array]
The first form lists out every value in the array.

r[expr.array.array-syntax]
The syntax for this form is a comma-separated list of expressions of uniform type enclosed in square brackets.

r[expr.array.array-behavior]
This produces an array containing each of these values in the order they are written.

r[expr.array.repeat]
The syntax for the second form is two expressions separated by a semicolon (`;`) enclosed in square brackets.

r[expr.array.repeat-operand]
The expression before the `;` is called the *repeat operand*.

r[expr.array.length-operand]
The expression after the `;` is called the *length operand*.

r[expr.array.length-restriction]
It must have type `usize` and be a [constant expression], such as a [literal] or a [constant item].

r[expr.array.repeat-behavior]
An array expression of this form creates an array with the length of the value of the length operand with each element being a copy of the repeat operand.
That is, `[a; b]` creates an array containing `b` copies of the value of `a`.

r[expr.array.repeat-copy]
If the length operand has a value greater than 1 then this requires that the type of the repeat operand is [`Copy`] or that it must be a [path] to a constant item.

r[expr.array.repeat-const-item]
When the repeat operand is a constant item, it is evaluated the length operand's value times.

r[expr.array.repeat-evaluation-zero]
If that value is `0`, then the constant item is not evaluated at all.

r[expr.array.repeat-non-const]
For expressions that are not a constant item, it is evaluated exactly once, and then the result is copied the length operand's value times.

```rust
@@ -39,19 +63,25 @@ const EMPTY: Vec<i32> = Vec::new();
[EMPTY; 2];
```

r[expr.array.index]
## Array and slice indexing expressions

> **<sup>Syntax</sup>**\
> _IndexExpression_ :\
> &nbsp;&nbsp; [_Expression_] `[` [_Expression_] `]`
r[expr.array.index.array]
[Array] and [slice]-typed values can be indexed by writing a square-bracket-enclosed expression of type `usize` (the index) after them.
When the array is mutable, the resulting [memory location] can be assigned to.

r[expr.array.index.trait]
For other types an index expression `a[b]` is equivalent to `*std::ops::Index::index(&a, b)`, or `*std::ops::IndexMut::index_mut(&mut a, b)` in a mutable place expression context.
Just as with methods, Rust will also insert dereference operations on `a` repeatedly to find an implementation.

r[expr.array.index.zero-index]
Indices are zero-based for arrays and slices.

r[expr.array.index.const]
Array access is a [constant expression], so bounds can be checked at compile-time with a constant index value.
Otherwise a check will be performed at run-time that will put the thread in a _panicked state_ if it fails.

@@ -73,6 +103,7 @@ let arr = ["a", "b"];
arr[10]; // warning: index out of bounds
```

r[expr.array.index.trait-impl]
The array index expression can be implemented for types other than arrays and slices by implementing the [Index] and [IndexMut] traits.

[`Copy`]: ../special-types-and-traits.md#copy
10 changes: 10 additions & 0 deletions src/expressions/await-expr.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
r[expr.await]
# Await expressions

r[expr.await.syntax]
> **<sup>Syntax</sup>**\
> _AwaitExpression_ :\
> &nbsp;&nbsp; [_Expression_] `.` `await`
r[expr.await.intro]
An `await` expression is a syntactic construct for suspending a computation
provided by an implementation of `std::future::IntoFuture` until the given
future is ready to produce a value.

r[expr.await.construct]
The syntax for an await expression is an expression with a type that implements the [`IntoFuture`] trait, called the *future operand*, then the token `.`, and then the `await` keyword.

r[expr.await.allowed-positions]
Await expressions are legal only within an [async context], like an [`async fn`], [`async` closure], or [`async` block].

r[expr.await.effects]
More specifically, an await expression has the following effect.

1. Create a future by calling [`IntoFuture::into_future`] on the future operand.
@@ -21,11 +29,13 @@ More specifically, an await expression has the following effect.

> **Edition differences**: Await expressions are only available beginning with Rust 2018.
r[expr.await.task]
## Task context

The task context refers to the [`Context`] which was supplied to the current [async context] when the async context itself was polled.
Because `await` expressions are only legal in an async context, there must be some task context available.

r[expr.await.desugar]
## Approximate desugaring

Effectively, an await expression is roughly equivalent to the following non-normative desugaring:
Loading