return is refused inside handler-bind and restart-case blanketly, and rightly: a return always crosses the frames they pushed. A break does not. A loop written wholly inside a restart-case body has a perfectly good local break, so the rule is a barrier on the loop stack rather than a flag — a jump is refused exactly when a barrier stands between it and the loop it names, and the message says which construct. handler-bind and restart-case bodies are barriers, so is a restart clause, so are a defer's forms; a handler clause is lifted into its own function and needs no rule at all. in_frames is untouched: a return is the special case where the target is always outside every barrier. continue wanted the other blocker. check_dotimes folded its step onto the end of the body, which a continue would jump past, so the counter would never advance and the loop would hang. Tast.While carries a latch now — condition, body, latch — the step goes there, and emit_while emits four blocks. A while's latch is empty and folds away. Labels are Odin's, in the head position: (while :outer c ...) and (break :outer). A keyword there is unambiguous because a loop condition is never one, so one label function serves while, until, dotimes, break and continue. It is not a goto — the checker resolves a label against the loops the form is lexically inside, so control can only leave a loop it is already in. Break and Continue carry a relative depth rather than a name, because that is what a backend already has: emit keeps one entry per While the way it keeps one pad per frame, and indexes it. Nothing in the prelude wants either. Every early exit there is a return from the function, which break cannot replace; the sentinel-flag loop break exists to remove does not appear in it. The two the compiler emits are that shape and are the one place it cannot help — their sentinel is set inside a restart-case. reach.ml and render.ml take the While arity change and nothing else.
Description
Languages
OCaml
67.2%
Emacs Lisp
15.2%
C
10.4%
HTML
2.9%
Standard ML
2.8%
Other
1.5%