Why this fires¶
A perform targets an effect operation declared multi (resumable more than once — a multi-shot continuation):
effect Choice { multi fn pick(opts: [int]) -> int }The native (Cranelift) backend's calling convention has no support for stack-copying continuations, so a multi-shot effect operation can only run on the VM. The effect-safety pass has a native-backend mode (EffectBackend::Native) that rejects performs of multi operations for exactly this reason.
Current status: as of this writing,
zolo build --target nativedoes not actually run the effect-safety pass in its native-backend mode — a program usingmulti fnbuilds and runs natively today withoutTE812ever firing (the multi-shot semantics simply aren't exercised by the test program in that case).TE812is reachable through the compiler's internal API (zolo_compiler::compiler::compile_to_lua_with_native_effect_check), which is how the compiler's own test suite exercises it; it is not yet wired into thezolo build --target nativeCLI path.
Fix it¶
- Run the program on the VM (
zolo run file.zolo), which fully supports multi-shot effects. - If native/LLVM support is required, avoid
multi-shot operations — restructure the effect to only resume once (or not at all), which both backends support.
See also¶
- /docs/algebraic-effects — effect operations and multi-shot handlers.