@@ -2071,6 +2071,52 @@ the loop.
2071
2071
A ` loop ` expression is only permitted in the body of a loop.
2072
2072
2073
2073
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
+
2074
2120
### For expressions
2075
2121
2076
2122
~~~~~~~~ {.ebnf .gram}
0 commit comments