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