Files
scriptc/tests/diagnostics/unassigned-fields.ts
Chris Tate fc84780ebe Deferred-init fields: stream!-style classes lower with typed extraction reads
- a !-asserted (or SPI-off) field first assigned past the constructor's top level rides an undefined-armed union slot: allocation writes the interned undefined, writes wrap, reads extract the declared type
- scalar reads take unit defaults where JS-undefined behavior survives (bool false, f64 NaN — conditions and arithmetic exact); string/ref reads keep the checked-extraction trap, JS's own first-member-use TypeError named earlier
- union/map/dyn-typed ! fields keep the fence; deferral propagates down the base chain with the fields map
- diagnostics fixtures re-pin the surviving fences; corpus 2429 pins the Output.initialize idiom on both backends; SEMANTICS.md 372-375
2026-07-23 00:40:54 -05:00

45 lines
1.3 KiB
TypeScript

// The definite-assignment fences, deferral-era. A field whose type ADMITS
// undefined starts as JS's undefined and compiles (corpus 1584-1587); a
// `!`-asserted field assigned past the constructor's top level now DEFERS
// instead of fencing — the slot rides `T | undefined` and reads extract
// the declared type (corpus 2429; SEMANTICS.md 372) — so `Lazy` compiles.
// The deferral needs a single-arm declared type the undefined-armed union
// can carry: a UNION-typed `!` field (the extraction would need a
// sub-union re-tag) and a MAP-typed one (map arms cannot join a union)
// keep the fence.
class Lazy {
path!: string; // compiles: deferred init — reads checked-extract
init(): void {
this.path = "/tmp/lazy";
}
}
class Eager {
root!: string; // compiles: the constructor's top level assigns it
constructor() {
this.root = "/";
}
}
class UnionLazy {
mode!: string | null; // fenced: union-typed `!` fields have no deferral
init(): void {
this.mode = null;
}
}
class MapLazy {
cache!: Map<string, number>; // fenced: map arms cannot join the deferral union
init(): void {
this.cache = new Map();
}
}
// Reached: collection defers its diagnostics until a reference makes
// them relevant.
new Lazy().init();
new Eager();
new UnionLazy();
new MapLazy();