wcc/ww: flexible rune-const promotion at scalar seams (coercerunelit)

wwstage stamped N_RUNELIT as concrete rune (cstage: untyped_rune,
check.c:1296), so an uncast rune literal into a fitting integer slot
over-rejected where harec accepts (promote_flexible). Add coercerunelit
(mirror of coercefloatlit) at the scalar seams — let-init, return,
call-arg, index-store; coarse accept, no range check (mirror cstage
type.c:379); array-literal elements keep the range gate
(arrlit_init_fits, types.c:923). Teeth: the fnmatch.ww '\\': u8
workaround cast and getopttest's 'X': u8 index-store casts are removed
and compile green. Checker-only (no e.type_ restamp): byte-id held.
This commit is contained in:
2026-06-11 20:41:20 +09:00
parent fa17459558
commit 8d2d157a58
5 changed files with 216 additions and 13 deletions

View File

@@ -123,8 +123,7 @@ fn pat_next(pat: str, pos: *i32, fl: flag) (u8 | star | question | bracket | end
*pos += 1;
return c2;
};
// #29: wwstage over-rejects the implicit flexible-rune-const narrow (harec promote_flexible accepts); explicit cast until flexible-const promotion lands — revert to bare '\\' then.
return '\\': u8;
return '\\';
};
return c;
};

View File

@@ -63,10 +63,10 @@ fn streq(a: str, b: str) bool = {
// (wantflag, wantval) parallel arrays, indexed by option order.
let wantf: [4]u8;
let wantv: [4]str;
wantf[0] = 'F': u8; wantv[0] = "";
wantf[1] = 'a': u8; wantv[1] = "";
wantf[2] = 'h': u8; wantv[2] = "";
wantf[3] = 's': u8; wantv[3] = "";
wantf[0] = 'F'; wantv[0] = "";
wantf[1] = 'a'; wantv[1] = "";
wantf[2] = 'h'; wantv[2] = "";
wantf[3] = 's'; wantv[3] = "";
let i: i32 = 0;
for (i < 4) {
@@ -108,8 +108,8 @@ fn streq(a: str, b: str) bool = {
let wantf: [2]u8;
let wantv: [2]str;
wantf[0] = 'e': u8; wantv[0] = "s/foo/bar/";
wantf[1] = 'f': u8; wantv[1] = "/tmp/x.sed";
wantf[0] = 'e'; wantv[0] = "s/foo/bar/";
wantf[1] = 'f'; wantv[1] = "/tmp/x.sed";
let i: i32 = 0;
for (i < 2) {
@@ -280,9 +280,9 @@ fn streq(a: str, b: str) bool = {
let argn: [3]i32;
let wantk: [3]i32;
let wantf: [3]u8;
argo[0] = 0; argn[0] = 2; wantk[0] = 1; wantf[0] = 'x': u8; // UNKNOWNOPT=1
argo[1] = 2; argn[1] = 2; wantk[1] = 0; wantf[1] = 'e': u8; // REQUIRESARG=0
argo[2] = 4; argn[2] = 3; wantk[2] = 0; wantf[2] = 'e': u8;
argo[0] = 0; argn[0] = 2; wantk[0] = 1; wantf[0] = 'x'; // UNKNOWNOPT=1
argo[1] = 2; argn[1] = 2; wantk[1] = 0; wantf[1] = 'e'; // REQUIRESARG=0
argo[2] = 4; argn[2] = 3; wantk[2] = 0; wantf[2] = 'e';
let i: i32 = 0;
for (i < 3) {
@@ -316,8 +316,8 @@ fn streq(a: str, b: str) bool = {
let flags: [2]u8;
let names: [2]str;
let wants: [2]str;
kinds[0]=1; flags[0]='x': u8; names[0]="prog"; wants[0]="prog: unrecognized option: -x";
kinds[1]=0; flags[1]='e': u8; names[1]="sed"; wants[1]="sed: option -e requires an argument";
kinds[0]=1; flags[0]='x'; names[0]="prog"; wants[0]="prog: unrecognized option: -x";
kinds[1]=0; flags[1]='e'; names[1]="sed"; wants[1]="sed: option -e requires an argument";
let i: i32 = 0;
for (i < 2) {