wcc: collapse exprfloatkind structural body onto checker stamp (#121)

wwstage exprfloatkind now reads n.type_ via classifytinfo (typeisf32→1,
typeisfloat→2, else 0) — wwstage classifies float-ness from the cstage-
equal stamp; delete the 9-arm structural body + the transient bridge.

Permanent residual sibling-evidence guards: cgbin float-arith (primary,
fires on unstamped float operand), tupstore + cgwidentaggedstore float
arms (pins, unreachable today, contract assertions against future
regression). cgcast excluded (int→float CVTSI2SD legitimately nil-typed).

Closes the gate-blind cs≠ww float family root (STATUS:14, named (b)-phase
goal). Builds on 98e1665 (A-narrow N_IDENT destructure stamp) +
1c4cea4 (transient floatness-disagreement bridge).
This commit is contained in:
2026-05-26 18:30:18 +09:00
parent 1c4cea4e2c
commit 0a2747ce5b
5 changed files with 387 additions and 570 deletions

View File

@@ -187,6 +187,33 @@ fn tupstore(c: *cgen, cur: i32, off: i32, wide: bool, tn: *node) void = {
// the FACE-Z field read sees it. X0 survives the reg->mem stores.
// Single-float scope; multi-float collides on X0 at RETURN (#107).
if (isfloattype(c, tn)) {
// #121 (Package B) RESIDUAL sibling-evidence guard, pin form.
// In destructure mode tn IS the tuple-element-type-AST node
// (commit 98e1665's N_MLET arm sets l.lhs = pt.lhs); the "value
// stored" rides X0 with no separate AST. isfloattype(c, tn) at
// the branch head already implies tn.type_!=nil (typeisfloat is
// false on nil), so this assertion is structurally unreachable
// today — RETAINED to PIN the contract: "the float-store branch
// requires a stamped slot." Catches a future change that opens
// this branch on a nil-typed tn (e.g. an N_DOT-callee float-tuple
// element binding where the destructure stamp didn't land —
// #16/#17 cascade). Loud-abort idiom mirrors cgenstmt.ww:1405/
// 1475 + asserttyped file:line at check.ww:3340-3344.
if (tn != nil) { if (tn.type_ == nil) {
let msg: str = "tupstore float-arm: slot tn unstamped (#121 sibling-evidence) at ";
os.write(2, msg.ptr, msg.len: u64);
if (tn.file.len > 0) {
os.write(2, tn.file.ptr, tn.file.len: u64);
os.write(2, ":".ptr, 1u64);
let ls: str = strconv.i32tos(tn.line, strconv.base.DEC);
os.write(2, ls.ptr, ls.len: u64);
os.write(2, " ".ptr, 1u64);
};
let kn: str = nkname(tn.kind);
os.write(2, kn.ptr, kn.len: u64);
os.write(2, "\n".ptr, 1u64);
os.exit(1);
}; };
let mov: str = "MOVSD";
if (isf32type(c, tn)) { mov = "MOVSS"; };
emitline("\t");