Open and answer this issue on GitHub.
ready · opened 2026-11-01 · updated 2026-11-01 · 0 comments
ADR-343 D1 says process::exit(code) ends main immediately. The move checker does not treat the call as diverging, though. A value moved in an if branch that ends with process::exit(…) still counts as moved after the branch.
Probe:
use std::process
fn take(xs: Vec[String]) {}
fn main() throws {
let s = process::run("echo", ["a"]).stdout.trim().clone()
if s.len() > 5 {
take([s])
process::exit(2)
}
take([s]) // NK2105: `s` moved
}
The probe compiles once you add an explicit return after process::exit(2). I found this while writing scripts/pre-push.nika, which was restructured so it does not depend on this.
To build:
process::exit(…) in main as ending the flow, the way return does (ADR-343 D1). That covers moves, definite assignment and the end-of-branch type.tests/compiler/ from the probe above, with no return after the exit.