[−][src]Attribute Macro forward_goto::rewrite_forward_goto
#[rewrite_forward_goto]
This macro will rewrite the annotated function so that the control-flow
will go from a goto forward_goto!('label)
directly to a corresponding label
forward_label!('label)
.
This is achieved by wrapping necessary statements into loops
and jump to
their ends via break
. Because of this implementation it is only possible to jump
forward in the control-flow and not backwards. This, however, implies that
all normal rust features — especially the borrow checker — work as expected.
For gotos and labels apply multiple restrictions:
- Every goto has at most one corresponding label, but multiple gotos can go to the same label.
- Only forward jumps are allowed, meaning that the goto must come before the label. in the code. Backward jumps are not allowed. 'Side jumps' (i.e. from a then-branch into an else-branch) are possible, as long as the goto is physically before the label.
- Any statement after a label in the control-flow may not be the result statement of a block until all current labels are rewired to their corresponding gotos.
ⓘThis example is not tested
#[rewrite_forward_goto] fn test() -> i32 { forward_goto!('into_block); let result = { forward_label!('into_block); "the result" // <- error } 42 // would be allowed, because it's outside of 'into_block influence }
Because of they way the rewriting is done, it is only possible to use definitions that are reachable on all code paths.
#[rewrite_forward_goto] fn test(b: bool) { fn f1() {} if b { forward_goto!('jump); } fn f2() {} { f2(); // f2 can be used here forward_label!('jump); f1(); // f2 cannot be used here }; f1(); }