diff --git a/src/expressions/if-expr.md b/src/expressions/if-expr.md
index c8f57f077..0b711445d 100644
--- a/src/expressions/if-expr.md
+++ b/src/expressions/if-expr.md
@@ -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
diff --git a/src/expressions/loop-expr.md b/src/expressions/loop-expr.md
index 9cd1120ba..5d3b15b48 100644
--- a/src/expressions/loop-expr.md
+++ b/src/expressions/loop-expr.md
@@ -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
> **Syntax**
@@ -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
> **Syntax**
@@ -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