selfhost: alias-aware istaggedtype for nested-union match

`type error = !(invalid | overflow)` miscompiled — istaggedtype
only matched N_TTAGGED directly, so an `e: error` param spilled
as 8B scalar and the match's slot+8 read trailed into saved BP.

Mirror isstrtype's alias+bang unwrap; add resolvetagged() for
is/as/match sites that need the inner N_TTAGGED. Frame scan
counts via slotsize so wwstage stays byte-identical to cstage.
Unblocks lib/strconv.strerror.
This commit is contained in:
2026-05-13 04:23:31 +09:00
parent e16634baec
commit 6e7c9e0df4
9 changed files with 893 additions and 59 deletions

View File

@@ -8,6 +8,7 @@
// today). Graduate to the static-buffer shape once that lands.
use os;
use strings;
// invalid — input wasn't a valid number in the requested format.
// Payload is the byte index of the first offending position.
@@ -352,8 +353,13 @@ export fn f64tos(v: f64) str = {
return r;
};
// strerror — Hare has strconv::strerror; ww doesn't ship it yet
// because a `match (e) { case invalid => ... }` arm over the wider
// `error = !(invalid | overflow)` union exposes a cstage-vs-wwstage
// cgen divergence (one cgen spills the unused payload slot, the
// other elides it). Restore once the cgens converge.
// strerror — convert an strconv error to a user-readable string.
// Returns owned str; release via os.free. Mirrors Hare's
// strconv::strerror.
export fn strerror(e: error) str = {
match (e) {
case let v: invalid => return strings.dup("input is not a valid number");
case let v: overflow => return strings.dup("input number doesn't fit target type");
};
return strings.dup("");
};