diff options
| author | Graydon Hoare <graydon@mozilla.com> | 2012-10-11 15:46:16 -0700 |
|---|---|---|
| committer | Graydon Hoare <graydon@mozilla.com> | 2012-10-11 18:18:53 -0700 |
| commit | fd85a0000a542a52f0fda3bd2f941fba452e0698 (patch) | |
| tree | e2cd4dbf5822c2a5d3282876f9daf9852ab77055 | |
| parent | 693866d75e25425053c61dc16adcc12b977d86f0 (diff) | |
| download | rust-fd85a0000a542a52f0fda3bd2f941fba452e0698.tar.gz rust-fd85a0000a542a52f0fda3bd2f941fba452e0698.zip | |
manual: add section on do-expressions.
| -rw-r--r-- | doc/rust.md | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/doc/rust.md b/doc/rust.md index 628cb137061..1dfeaddc1a2 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -2071,6 +2071,52 @@ the loop. A `loop` expression is only permitted in the body of a loop. +### Do expressions + +~~~~~~~~{.ebnf .gram} +do_expr : "do" expr [ '|' ident_list '|' ] ? '{' block '}' ; +~~~~~~~~ + +A _do expression_ provides a more-familiar block-syntax for a [lambda expression](#lambda-expressions), +including a special translation of [return expressions](#return-expressions) inside the supplied block. + +The optional `ident_list` and `block` provided in a `do` expression are parsed as though they constitute a lambda expression; +if the `ident_list` is missing, an empty `ident_list` is implied. + +The lambda expression is then provided as a _trailing argument_ +to the outermost [call](#call-expressions) or [method call](#method-call-expressions) expression +in the `expr` following `do`. +If the `expr` is a [path expression](#path-expressions), it is parsed as though it is a call expression. +If the `expr` is a [field expression](#field-expressions), it is parsed as though it is a method call expression. + +Additionally, any occurrence of a [return expression](#return-expressions) +inside the `block` of a `do` expression is rewritten +as a reference to an (anonymous) flag set in the caller's environment, +which is checked on return from the `expr` and, if set, +causes a corresponding return from the caller. +In this way, the meaning of `return` statements in language built-in control blocks is preserved, +if they are rewritten using lambda functions and `do` expressions as abstractions. + +Therefore the two calls to `f` in this example are equivalent. +Both cause an early return from the caller's frame: + +~~~~ +# fn f(f: fn(int)) { } +# fn g(i: int) { } + +{ + let mut _early_ret = false; + f(|j| { g(j); _early_ret = true; }); + if early_ret { return; } +} + +do f |j| { + g(j); + return; +} +~~~~ + + ### For expressions ~~~~~~~~{.ebnf .gram} |
