Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document desugarings that happen when creating hir #414

Merged
merged 1 commit into from
Sep 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/expressions/if-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,24 @@ let a = if let Some(1) = x {
assert_eq!(a, 3);
```

An `if let` expression is equivalent to a `match` expression as follows:

```rust,ignore
if let PAT = EXPR {
/* body */
} else {
/*else */
}
```

is equivalent to

```rust,ignore
match EXPR {
PAT => { /* body */ },
_ => { /* else */ }, // () if there is no else
}
```

[_Expression_]: expressions.html
[_BlockExpression_]: expressions/block-expr.html
58 changes: 58 additions & 0 deletions src/expressions/loop-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,26 @@ while let Some(y) = x.pop() {
}
```

A `while let` loop is equivalent to a `loop` expression containing a `match`
expression as follows.

```rust,ignore
'label: while let PAT = EXPR {
/* loop body */
}
```

is equivalent to

```rust,ignore
'label: loop {
match EXPR {
PAT => { /* loop body */ },
_ => break,
}
}
```

## Iterator loops

> **<sup>Syntax</sup>**
Expand Down Expand Up @@ -118,6 +138,43 @@ for n in 1..11 {
assert_eq!(sum, 55);
```

A for loop is equivalent to the following block expression.

```rust,ignore
'label: for PATTERN in iter_expr {
/* loop body */
}
```

is equivalent to

```rust,ignore
{
let result = match IntoIterator::into_iter(iter_expr) {
mut iter => 'label: loop {
let mut next;
match Iterator::next(&mut iter) {
Option::Some(val) => next = val,
Option::None => break,
};
let PAT = next;
let () = { /* loop body */ };
},
};
result
}
```

`IntoIterator`, `Iterator` and `Option` are always the standard library items
here, not whatever those names resolve to in the current scope. The variable
names `next`, `iter` and `val` are for exposition only, they do not actually
have names the user can type.

> **Note**: that the outer `match` is used to ensure that any
> [temporary values] in `iter_expr` don't get dropped before the loop is
> finished. `next` is declared before being assigned because it results in
> types being inferred correctly more often.

## Loop labels

> **<sup>Syntax</sup>**
Expand Down Expand Up @@ -210,6 +267,7 @@ and the `loop` must have a type compatible with each `break` expression.
expression `()`.

[IDENTIFIER]: identifiers.html
[temporary values]: expressions.html#temporary-lifetimes

[_Expression_]: expressions.html
[_BlockExpression_]: expressions/block-expr.html
Expand Down