@@ -7,23 +7,65 @@ mod goto;
77mod state_machine;
88mod switch;
99
10- // switch!(match <condition> {
11- // <pat> [if <guard>] => <body>,
12- // <pat> [if <guard>] => <body>,
13- // ...
14- // _ => <body>,
15- // });
10+ // switch!(match <condition> {
11+ // <pat> [if <guard>] => { /* body; may contain break or continue */ },
12+ // ...
13+ // _ => <body>,
14+ // });
15+ //
16+ // Desugars to a goto_block! with a synthetic dispatch arm prepended.
17+ //
18+ // goto_block! {
19+ // '__dispatch => {
20+ // match <condition> {
21+ // <pat_1> => { __s = 1; continue '__sm; }
22+ // ...
23+ // _ => break '__sm,
24+ // }
25+ // },
26+ // '__c1 => { /* body_1 with `break` rewritten to `break '__sm` */ },
27+ // ...
28+ // '__cN => { /* body_N with same rewrite */ },
29+ // };
30+ //
31+ // __sm is the inner label used to describe the state machine insinde goto_block. See goto_block!
32+ // for more info.
1633
1734#[ proc_macro]
1835pub fn switch ( input : TokenStream ) -> TokenStream {
1936 switch:: expand ( input)
2037}
2138
22- // goto_block! {
23- // '<label> => <body>,
24- // '<label> => <body>,
25- // ...
26- // };
39+ // goto_block! {
40+ // '<label> => { /* body; may contain `break` or `continue` */ },
41+ // ...
42+ // };
43+ //
44+ // Expands to
45+ //
46+ // {
47+ // let mut __user_break: bool = false; // only if any arm has `break`
48+ // let mut __user_continue: bool = false; // only if any arm has `continue`
49+ // let mut __s: u32 = 0;
50+ // '__sm: loop {
51+ // match __s {
52+ // 0u32 => {
53+ // /* body_0 with these rewrites (outside nested user loops): */
54+ // /* break; -> { __user_break = true; break '__sm; } */
55+ // /* continue; -> { __user_continue = true; break '__sm; } */
56+ // __s = 1; continue '__sm;
57+ // }
58+ // ...
59+ // (N-1)u32 => { /* body_N-1 with same rewrites */ break '__sm; }
60+ // _ => break '__sm, // written only for match exhaustiveness
61+ // }
62+ // }
63+ // if __user_break { break; } // only if any arm has `break;`
64+ // if __user_continue { continue; } // only if any arm has `continue;`
65+ // }
66+ //
67+ // __user_break and __user_continue propagate the `break`s and `continue`s outside the goto state
68+ // machine loop.
2769
2870#[ proc_macro]
2971pub fn goto_block ( input : TokenStream ) -> TokenStream {
0 commit comments