Skip to content

Commit 221ea65

Browse files
authored
Merge pull request #414 from matthewjasper/hir-desugaring
Document desugarings that happen when creating hir
2 parents e905395 + d659d0e commit 221ea65

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

src/expressions/if-expr.md

+19
Original file line numberDiff line numberDiff line change
@@ -92,5 +92,24 @@ let a = if let Some(1) = x {
9292
assert_eq!(a, 3);
9393
```
9494

95+
An `if let` expression is equivalent to a `match` expression as follows:
96+
97+
```rust,ignore
98+
if let PAT = EXPR {
99+
/* body */
100+
} else {
101+
/*else */
102+
}
103+
```
104+
105+
is equivalent to
106+
107+
```rust,ignore
108+
match EXPR {
109+
PAT => { /* body */ },
110+
_ => { /* else */ }, // () if there is no else
111+
}
112+
```
113+
95114
[_Expression_]: expressions.html
96115
[_BlockExpression_]: expressions/block-expr.html

src/expressions/loop-expr.md

+58
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,26 @@ while let Some(y) = x.pop() {
8585
}
8686
```
8787

88+
A `while let` loop is equivalent to a `loop` expression containing a `match`
89+
expression as follows.
90+
91+
```rust,ignore
92+
'label: while let PAT = EXPR {
93+
/* loop body */
94+
}
95+
```
96+
97+
is equivalent to
98+
99+
```rust,ignore
100+
'label: loop {
101+
match EXPR {
102+
PAT => { /* loop body */ },
103+
_ => break,
104+
}
105+
}
106+
```
107+
88108
## Iterator loops
89109

90110
> **<sup>Syntax</sup>**\
@@ -118,6 +138,43 @@ for n in 1..11 {
118138
assert_eq!(sum, 55);
119139
```
120140

141+
A for loop is equivalent to the following block expression.
142+
143+
```rust,ignore
144+
'label: for PATTERN in iter_expr {
145+
/* loop body */
146+
}
147+
```
148+
149+
is equivalent to
150+
151+
```rust,ignore
152+
{
153+
let result = match IntoIterator::into_iter(iter_expr) {
154+
mut iter => 'label: loop {
155+
let mut next;
156+
match Iterator::next(&mut iter) {
157+
Option::Some(val) => next = val,
158+
Option::None => break,
159+
};
160+
let PAT = next;
161+
let () = { /* loop body */ };
162+
},
163+
};
164+
result
165+
}
166+
```
167+
168+
`IntoIterator`, `Iterator` and `Option` are always the standard library items
169+
here, not whatever those names resolve to in the current scope. The variable
170+
names `next`, `iter` and `val` are for exposition only, they do not actually
171+
have names the user can type.
172+
173+
> **Note**: that the outer `match` is used to ensure that any
174+
> [temporary values] in `iter_expr` don't get dropped before the loop is
175+
> finished. `next` is declared before being assigned because it results in
176+
> types being inferred correctly more often.
177+
121178
## Loop labels
122179

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

212269
[IDENTIFIER]: identifiers.html
270+
[temporary values]: expressions.html#temporary-lifetimes
213271

214272
[_Expression_]: expressions.html
215273
[_BlockExpression_]: expressions/block-expr.html

0 commit comments

Comments
 (0)