|
7 | 7 | > | [_PredicateLoopExpression_]\
|
8 | 8 | > | [_PredicatePatternLoopExpression_]\
|
9 | 9 | > | [_IteratorLoopExpression_]\
|
| 10 | +> | [_LabelBlockExpression_]\ |
10 | 11 | > )
|
11 | 12 |
|
12 | 13 | [_LoopLabel_]: #loop-labels
|
13 | 14 | [_InfiniteLoopExpression_]: #infinite-loops
|
14 | 15 | [_PredicateLoopExpression_]: #predicate-loops
|
15 | 16 | [_PredicatePatternLoopExpression_]: #predicate-pattern-loops
|
16 | 17 | [_IteratorLoopExpression_]: #iterator-loops
|
| 18 | +[_LabelBlockExpression_]: #labelled-block-expressions |
17 | 19 |
|
18 |
| -Rust supports four loop expressions: |
| 20 | +Rust supports five loop expressions: |
19 | 21 |
|
20 | 22 | * A [`loop` expression](#infinite-loops) denotes an infinite loop.
|
21 | 23 | * A [`while` expression](#predicate-loops) loops until a predicate is false.
|
22 | 24 | * A [`while let` expression](#predicate-pattern-loops) tests a pattern.
|
23 | 25 | * A [`for` expression](#iterator-loops) extracts values from an iterator, looping until the iterator is empty.
|
| 26 | +* A [labelled block expression](#labelled-block-expressions) runs a loop exactly once, but allows exiting the loop early with `break`. |
24 | 27 |
|
25 |
| -All four types of loop support [`break` expressions](#break-expressions), [`continue` expressions](#continue-expressions), and [labels](#loop-labels). |
26 |
| -Only `loop` supports [evaluation to non-trivial values](#break-and-loop-values). |
| 28 | +All five types of loop support [`break` expressions](#break-expressions), and [labels](#loop-labels). |
| 29 | +All except labelled block expressions support [`continue` expressions](#continue-expressions). |
| 30 | +Only `loop` and labelled block expressions support [evaluation to non-trivial values](#break-and-loop-values). |
27 | 31 |
|
28 | 32 | ## Infinite loops
|
29 | 33 |
|
@@ -193,6 +197,18 @@ A loop expression may optionally have a _label_. The label is written as a lifet
|
193 | 197 | If a label is present, then labeled `break` and `continue` expressions nested within this loop may exit out of this loop or return control to its head.
|
194 | 198 | See [break expressions](#break-expressions) and [continue expressions](#continue-expressions).
|
195 | 199 |
|
| 200 | +Labels follow the hygiene and shadowing rules of local variables. For example, this code will print "outer loop": |
| 201 | + |
| 202 | +```rust |
| 203 | +'a: loop { |
| 204 | + 'a: loop { |
| 205 | + break 'a; |
| 206 | + } |
| 207 | + print!("outer loop"); |
| 208 | + break 'a; |
| 209 | +} |
| 210 | +``` |
| 211 | + |
196 | 212 | ## `break` expressions
|
197 | 213 |
|
198 | 214 | > **<sup>Syntax</sup>**\
|
@@ -226,6 +242,16 @@ Example:
|
226 | 242 |
|
227 | 243 | A `break` expression is only permitted in the body of a loop, and has one of the forms `break`, `break 'label` or ([see below](#break-and-loop-values)) `break EXPR` or `break 'label EXPR`.
|
228 | 244 |
|
| 245 | +## Labelled block expressions |
| 246 | + |
| 247 | +> **<sup>Syntax</sup>**\ |
| 248 | +> _LabelBlockExpression_ :\ |
| 249 | +> [_BlockExpression_] |
| 250 | +
|
| 251 | +Labelled block expressions are exactly like block expressions, except that they allow using `break` expressions within the block. |
| 252 | +Unlike other loops, `break` expressions within a label expression *must* have a label (i.e. the label is not optional). |
| 253 | +Unlike other loops, labelled block expressions *must* begin with a label. |
| 254 | + |
229 | 255 | ## `continue` expressions
|
230 | 256 |
|
231 | 257 | > **<sup>Syntax</sup>**\
|
|
0 commit comments