writeonce/tests/corpus/run/try-nil-int-zero/fixture.wo
shoney.arickathil 82efb498d4 fix(compiler): lang-41 side defects — ?T-typed nil try, WO-E305 on moves out of a field
- emit.ml: a `try … catch (e) nil` is `?T` (ty_of_expr) and the nil arm takes that destination, so a `?Int` nil is WO_NIL_SCALAR and an Int body's legitimate 0 no longer reads as nil (it used to fall back to the zero word via the body type / enclosing return type)
- owner.ml: `transfer` on a projection (`d.tags`, `x[i]`) of an owned value reports WO-E305 instead of returning false silently — the silent path compiled `Out { tags: d.tags }` to an alias that both records dropped (the "json.decode as T corruption": not json's, a double free language 44's poison now aborts on); heap scalars exempt (store sites copy)
- error catalog: WO-E305 row; owner.ml module doc updated
- corpus: run/try-nil-int-zero, compile-fail/no-partial-move, run/decode-record-crosses-return (Text copied, record moved whole — the archived `.. ""` workaround is unnecessary)
- verified: oop-e2e 126/0, tests/regress/lang-41 compile, --emit sweep over the non-porch examples, web-app gate 56/0 (porch in project mode) — no legitimate program trips WO-E305
- story 41: both side defects marked fixed; board prose updated

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 2d54710e693fafee4b8d6561cc9cba7b95415d89)
2026-09-15 01:16:13 +02:00

18 lines
767 B
Text

-- lang-41 side defect 1: `try EXPR catch (e) nil` over an Int body used to
-- spell its nil as the zero word, so a legitimate 0 reply read as a trap.
-- The try is `?Int`: nil is the scalar sentinel, 0 stays 0, in a void fn
-- and in one whose own return type is Int (the archived porch shape).
fn zero() -> Int { return 0 }
fn boom() -> Int { let d = 0; return 1 / d }
fn probe() -> Int {
let z = try zero() catch (e) nil
if z == nil { print("ZERO-READ-AS-NIL-IN-INT-FN") } else { print("zero-kept-in-int-fn") }
return 1
}
fn main() {
let z = try zero() catch (e) nil
if z == nil { print("ZERO-READ-AS-NIL") } else { print_int(z) }
let t = try boom() catch (e) nil
if t == nil { print("trap-is-nil") } else { print("TRAP-READ-AS-VALUE") }
probe()
}