@@ -2071,6 +2071,52 @@ the loop.
20712071A ` loop ` expression is only permitted in the body of a loop.
20722072
20732073
2074+ ### Do expressions
2075+
2076+ ~~~~~~~~ {.ebnf .gram}
2077+ do_expr : "do" expr [ '|' ident_list '|' ] ? '{' block '}' ;
2078+ ~~~~~~~~
2079+
2080+ A _ do expression_ provides a more-familiar block-syntax for a [ lambda expression] ( #lambda-expressions ) ,
2081+ including a special translation of [ return expressions] ( #return-expressions ) inside the supplied block.
2082+
2083+ The optional ` ident_list ` and ` block ` provided in a ` do ` expression are parsed as though they constitute a lambda expression;
2084+ if the ` ident_list ` is missing, an empty ` ident_list ` is implied.
2085+
2086+ The lambda expression is then provided as a _ trailing argument_
2087+ to the outermost [ call] ( #call-expressions ) or [ method call] ( #method-call-expressions ) expression
2088+ in the ` expr ` following ` do ` .
2089+ If the ` expr ` is a [ path expression] ( #path-expressions ) , it is parsed as though it is a call expression.
2090+ If the ` expr ` is a [ field expression] ( #field-expressions ) , it is parsed as though it is a method call expression.
2091+
2092+ Additionally, any occurrence of a [ return expression] ( #return-expressions )
2093+ inside the ` block ` of a ` do ` expression is rewritten
2094+ as a reference to an (anonymous) flag set in the caller's environment,
2095+ which is checked on return from the ` expr ` and, if set,
2096+ causes a corresponding return from the caller.
2097+ In this way, the meaning of ` return ` statements in language built-in control blocks is preserved,
2098+ if they are rewritten using lambda functions and ` do ` expressions as abstractions.
2099+
2100+ Therefore the two calls to ` f ` in this example are equivalent.
2101+ Both cause an early return from the caller's frame:
2102+
2103+ ~~~~
2104+ # fn f(f: fn(int)) { }
2105+ # fn g(i: int) { }
2106+
2107+ {
2108+ let mut _early_ret = false;
2109+ f(|j| { g(j); _early_ret = true; });
2110+ if early_ret { return; }
2111+ }
2112+
2113+ do f |j| {
2114+ g(j);
2115+ return;
2116+ }
2117+ ~~~~
2118+
2119+
20742120### For expressions
20752121
20762122~~~~~~~~ {.ebnf .gram}
0 commit comments