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:
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -12756,6 +12756,48 @@ fn coercefloatlit(c: *checker, e: *node, target: *node) void = {
|
||||
};
|
||||
};
|
||||
|
||||
// coercerunelit — #29: an un-suffixed rune literal narrowing into an
|
||||
// integer slot. Same intent as coercefloatlit (:2324) but CHECKER-only:
|
||||
// wwstage stamps N_RUNELIT concrete `rune` (:2652), so isassignable's
|
||||
// untyped arms never fire and the operand falls to the "two known
|
||||
// primitives, different names → confident reject" arm (:4139) — the #29
|
||||
// over-reject. cstage stamps N_RUNELIT untyped_rune (cmd/wcc/check.c:1296)
|
||||
// which type_assignable admits into ANY integer UNCONDITIONALLY
|
||||
// (cmd/wcc/type.c:379 — coarse, NO range check; harec's range-precise
|
||||
// promote_flexible at types.c:928 is the reference cstage already
|
||||
// flattened, so wwstage mirrors cstage's coarse rule, not harec's gate).
|
||||
// Return the integer target tnode so the caller overrides its `src`/
|
||||
// `atype` and isassignable sees su==target → accept. Does NOT touch
|
||||
// e.type_: cgen narrows a rune immediate by the DESTINATION width (proven
|
||||
// byte-id at let/call-arg/index-store; #251 array-elem twin) and for a
|
||||
// tagged-union target the variant boxing falls to taggedvariantindext's
|
||||
// scalar-shape fallback (cgenutil.ww:3054) which picks the first scalar
|
||||
// variant — the same u8 variant cstage's untyped_rune boxes into — so the
|
||||
// unchanged node stamp keeps cgen provably identical to the pre-fix
|
||||
// bare-literal lowering. Array-LITERAL elements are NOT routed here: they
|
||||
// keep harec's per-element range gate via checkarrlitfits's foldint /
|
||||
// defcastfits path (:4634). For a tagged-union target (fnmatch pat_next's
|
||||
// (u8 | star | ...)) return the first integer variant.
|
||||
fn coercerunelit(c: *checker, e: *node, target: *node) *node = {
|
||||
if (e == nil) { return nil; };
|
||||
if (e.kind != nkind.N_RUNELIT) { return nil; };
|
||||
if (target == nil) { return nil; };
|
||||
let tu: *node = resolvealias(c, unwrapbang(target));
|
||||
if (tu == nil) { return nil; };
|
||||
if (isinttypeast(tu)) { return tu; };
|
||||
if (tu.kind == nkind.N_TTAGGED) {
|
||||
let v: *node = tu.list;
|
||||
for (v != nil) {
|
||||
let vu: *node = resolvealias(c, unwrapbang(v));
|
||||
if (vu != nil) {
|
||||
if (isinttypeast(vu)) { return vu; };
|
||||
};
|
||||
v = v.next;
|
||||
};
|
||||
};
|
||||
return nil;
|
||||
};
|
||||
|
||||
// binoptype — derive the result tnode of an N_BIN operator expression.
|
||||
// Mirrors cstage cmd/wcc/check.c:598-640 `cbinop`. Operates on tnodes
|
||||
// returned by exprtype; ptr arithmetic / bitwise / shifts / comparisons /
|
||||
@@ -15215,6 +15257,14 @@ fn desugarcallargs(c: *checker, n: *node) void = {
|
||||
if (param.kind == nkind.N_PARAM) {
|
||||
if (param.op != tkind.TK_ELLIPSIS) {
|
||||
let atype: *node = exprtype(c, a, nil);
|
||||
// #29: a rune literal narrowing into an integer param
|
||||
// (`take('b')` where take(b: u8)). Override atype to the
|
||||
// integer target so c3's general isassignable accepts,
|
||||
// mirroring cstage's coarse untyped_rune rule. See
|
||||
// coercerunelit. cgen is byte-id-neutral (narrows by the
|
||||
// param/destination width).
|
||||
let runet: *node = coercerunelit(c, a, param.lhs);
|
||||
if (runet != nil) { atype = runet; };
|
||||
// #258: an array arg into a []T param with a
|
||||
// MISMATCHED element is not a borrow — loud reject,
|
||||
// mirror cstage's call-arg type_assignable failure.
|
||||
@@ -15267,6 +15317,13 @@ fn checkassign(c: *checker, n: *node) void = {
|
||||
if (n.rhs == nil) { return; };
|
||||
let ltn: *node = exprtype(c, n.lhs, nil);
|
||||
let rtn: *node = exprtype(c, n.rhs, nil);
|
||||
// #29: a rune literal narrowing into an integer assign/index-store
|
||||
// target (`buf[i] = 'F'`). Override rtn to the integer target so a
|
||||
// general assign typecheck accepts, mirroring cstage's coarse
|
||||
// untyped_rune rule. See coercerunelit. cgen narrows by the destination
|
||||
// width (byte-id-neutral). Removes the getopt `'X': u8` index casts.
|
||||
let runet: *node = coercerunelit(c, n.rhs, ltn);
|
||||
if (runet != nil) { rtn = runet; };
|
||||
// #31/#33: bare array-literal rhs has no backing — loud-reject
|
||||
// (supported only at a `let`).
|
||||
if (!rejectarrlitborrow(c, ltn, n.rhs)) {
|
||||
@@ -15508,6 +15565,11 @@ fn checkletassign(c: *checker, n: *node) void = {
|
||||
n.rhs.lhs = arr;
|
||||
src = arr;
|
||||
};
|
||||
// #29: an un-suffixed rune literal narrowing into an integer let target
|
||||
// (`let b: u8 = 'a'`). Override src to the integer target so isassignable
|
||||
// accepts, mirroring cstage's coarse untyped_rune rule. See coercerunelit.
|
||||
let runet: *node = coercerunelit(c, n.rhs, n.lhs);
|
||||
if (runet != nil) { src = runet; };
|
||||
let conf: bool = false;
|
||||
let ok: bool = isassignable(c, n.lhs, src, &conf);
|
||||
// #206: direct `&fn` → `*alias` / `(*alias | void)` slot.
|
||||
@@ -15573,6 +15635,12 @@ fn checkretassign(c: *checker, n: *node) void = {
|
||||
};
|
||||
let src: *node = exprtype(c, n.lhs, nil);
|
||||
if (src == nil) { return; };
|
||||
// #29: a rune literal returned into an integer (or integer-variant)
|
||||
// fnret (`return '\\';` into u8 or (u8 | star | ...)). Override src so
|
||||
// isassignable accepts; cgen boxes via the shape fallback. See
|
||||
// coercerunelit. Removes the fnmatch.ww:126 `'\\': u8` workaround cast.
|
||||
let runet: *node = coercerunelit(c, n.lhs, c.fnret);
|
||||
if (runet != nil) { src = runet; };
|
||||
let conf: bool = false;
|
||||
let ok: bool = isassignable(c, c.fnret, src, &conf);
|
||||
// #206: direct `&fn` returned into a `*alias` / `(*alias | void)`.
|
||||
|
||||
@@ -2336,6 +2336,48 @@ fn coercefloatlit(c: *checker, e: *node, target: *node) void = {
|
||||
};
|
||||
};
|
||||
|
||||
// coercerunelit — #29: an un-suffixed rune literal narrowing into an
|
||||
// integer slot. Same intent as coercefloatlit (:2324) but CHECKER-only:
|
||||
// wwstage stamps N_RUNELIT concrete `rune` (:2652), so isassignable's
|
||||
// untyped arms never fire and the operand falls to the "two known
|
||||
// primitives, different names → confident reject" arm (:4139) — the #29
|
||||
// over-reject. cstage stamps N_RUNELIT untyped_rune (cmd/wcc/check.c:1296)
|
||||
// which type_assignable admits into ANY integer UNCONDITIONALLY
|
||||
// (cmd/wcc/type.c:379 — coarse, NO range check; harec's range-precise
|
||||
// promote_flexible at types.c:928 is the reference cstage already
|
||||
// flattened, so wwstage mirrors cstage's coarse rule, not harec's gate).
|
||||
// Return the integer target tnode so the caller overrides its `src`/
|
||||
// `atype` and isassignable sees su==target → accept. Does NOT touch
|
||||
// e.type_: cgen narrows a rune immediate by the DESTINATION width (proven
|
||||
// byte-id at let/call-arg/index-store; #251 array-elem twin) and for a
|
||||
// tagged-union target the variant boxing falls to taggedvariantindext's
|
||||
// scalar-shape fallback (cgenutil.ww:3054) which picks the first scalar
|
||||
// variant — the same u8 variant cstage's untyped_rune boxes into — so the
|
||||
// unchanged node stamp keeps cgen provably identical to the pre-fix
|
||||
// bare-literal lowering. Array-LITERAL elements are NOT routed here: they
|
||||
// keep harec's per-element range gate via checkarrlitfits's foldint /
|
||||
// defcastfits path (:4634). For a tagged-union target (fnmatch pat_next's
|
||||
// (u8 | star | ...)) return the first integer variant.
|
||||
fn coercerunelit(c: *checker, e: *node, target: *node) *node = {
|
||||
if (e == nil) { return nil; };
|
||||
if (e.kind != nkind.N_RUNELIT) { return nil; };
|
||||
if (target == nil) { return nil; };
|
||||
let tu: *node = resolvealias(c, unwrapbang(target));
|
||||
if (tu == nil) { return nil; };
|
||||
if (isinttypeast(tu)) { return tu; };
|
||||
if (tu.kind == nkind.N_TTAGGED) {
|
||||
let v: *node = tu.list;
|
||||
for (v != nil) {
|
||||
let vu: *node = resolvealias(c, unwrapbang(v));
|
||||
if (vu != nil) {
|
||||
if (isinttypeast(vu)) { return vu; };
|
||||
};
|
||||
v = v.next;
|
||||
};
|
||||
};
|
||||
return nil;
|
||||
};
|
||||
|
||||
// binoptype — derive the result tnode of an N_BIN operator expression.
|
||||
// Mirrors cstage cmd/wcc/check.c:598-640 `cbinop`. Operates on tnodes
|
||||
// returned by exprtype; ptr arithmetic / bitwise / shifts / comparisons /
|
||||
@@ -4795,6 +4837,14 @@ fn desugarcallargs(c: *checker, n: *node) void = {
|
||||
if (param.kind == nkind.N_PARAM) {
|
||||
if (param.op != tkind.TK_ELLIPSIS) {
|
||||
let atype: *node = exprtype(c, a, nil);
|
||||
// #29: a rune literal narrowing into an integer param
|
||||
// (`take('b')` where take(b: u8)). Override atype to the
|
||||
// integer target so c3's general isassignable accepts,
|
||||
// mirroring cstage's coarse untyped_rune rule. See
|
||||
// coercerunelit. cgen is byte-id-neutral (narrows by the
|
||||
// param/destination width).
|
||||
let runet: *node = coercerunelit(c, a, param.lhs);
|
||||
if (runet != nil) { atype = runet; };
|
||||
// #258: an array arg into a []T param with a
|
||||
// MISMATCHED element is not a borrow — loud reject,
|
||||
// mirror cstage's call-arg type_assignable failure.
|
||||
@@ -4847,6 +4897,13 @@ fn checkassign(c: *checker, n: *node) void = {
|
||||
if (n.rhs == nil) { return; };
|
||||
let ltn: *node = exprtype(c, n.lhs, nil);
|
||||
let rtn: *node = exprtype(c, n.rhs, nil);
|
||||
// #29: a rune literal narrowing into an integer assign/index-store
|
||||
// target (`buf[i] = 'F'`). Override rtn to the integer target so a
|
||||
// general assign typecheck accepts, mirroring cstage's coarse
|
||||
// untyped_rune rule. See coercerunelit. cgen narrows by the destination
|
||||
// width (byte-id-neutral). Removes the getopt `'X': u8` index casts.
|
||||
let runet: *node = coercerunelit(c, n.rhs, ltn);
|
||||
if (runet != nil) { rtn = runet; };
|
||||
// #31/#33: bare array-literal rhs has no backing — loud-reject
|
||||
// (supported only at a `let`).
|
||||
if (!rejectarrlitborrow(c, ltn, n.rhs)) {
|
||||
@@ -5088,6 +5145,11 @@ fn checkletassign(c: *checker, n: *node) void = {
|
||||
n.rhs.lhs = arr;
|
||||
src = arr;
|
||||
};
|
||||
// #29: an un-suffixed rune literal narrowing into an integer let target
|
||||
// (`let b: u8 = 'a'`). Override src to the integer target so isassignable
|
||||
// accepts, mirroring cstage's coarse untyped_rune rule. See coercerunelit.
|
||||
let runet: *node = coercerunelit(c, n.rhs, n.lhs);
|
||||
if (runet != nil) { src = runet; };
|
||||
let conf: bool = false;
|
||||
let ok: bool = isassignable(c, n.lhs, src, &conf);
|
||||
// #206: direct `&fn` → `*alias` / `(*alias | void)` slot.
|
||||
@@ -5153,6 +5215,12 @@ fn checkretassign(c: *checker, n: *node) void = {
|
||||
};
|
||||
let src: *node = exprtype(c, n.lhs, nil);
|
||||
if (src == nil) { return; };
|
||||
// #29: a rune literal returned into an integer (or integer-variant)
|
||||
// fnret (`return '\\';` into u8 or (u8 | star | ...)). Override src so
|
||||
// isassignable accepts; cgen boxes via the shape fallback. See
|
||||
// coercerunelit. Removes the fnmatch.ww:126 `'\\': u8` workaround cast.
|
||||
let runet: *node = coercerunelit(c, n.lhs, c.fnret);
|
||||
if (runet != nil) { src = runet; };
|
||||
let conf: bool = false;
|
||||
let ok: bool = isassignable(c, c.fnret, src, &conf);
|
||||
// #206: direct `&fn` returned into a `*alias` / `(*alias | void)`.
|
||||
|
||||
@@ -12756,6 +12756,48 @@ fn coercefloatlit(c: *checker, e: *node, target: *node) void = {
|
||||
};
|
||||
};
|
||||
|
||||
// coercerunelit — #29: an un-suffixed rune literal narrowing into an
|
||||
// integer slot. Same intent as coercefloatlit (:2324) but CHECKER-only:
|
||||
// wwstage stamps N_RUNELIT concrete `rune` (:2652), so isassignable's
|
||||
// untyped arms never fire and the operand falls to the "two known
|
||||
// primitives, different names → confident reject" arm (:4139) — the #29
|
||||
// over-reject. cstage stamps N_RUNELIT untyped_rune (cmd/wcc/check.c:1296)
|
||||
// which type_assignable admits into ANY integer UNCONDITIONALLY
|
||||
// (cmd/wcc/type.c:379 — coarse, NO range check; harec's range-precise
|
||||
// promote_flexible at types.c:928 is the reference cstage already
|
||||
// flattened, so wwstage mirrors cstage's coarse rule, not harec's gate).
|
||||
// Return the integer target tnode so the caller overrides its `src`/
|
||||
// `atype` and isassignable sees su==target → accept. Does NOT touch
|
||||
// e.type_: cgen narrows a rune immediate by the DESTINATION width (proven
|
||||
// byte-id at let/call-arg/index-store; #251 array-elem twin) and for a
|
||||
// tagged-union target the variant boxing falls to taggedvariantindext's
|
||||
// scalar-shape fallback (cgenutil.ww:3054) which picks the first scalar
|
||||
// variant — the same u8 variant cstage's untyped_rune boxes into — so the
|
||||
// unchanged node stamp keeps cgen provably identical to the pre-fix
|
||||
// bare-literal lowering. Array-LITERAL elements are NOT routed here: they
|
||||
// keep harec's per-element range gate via checkarrlitfits's foldint /
|
||||
// defcastfits path (:4634). For a tagged-union target (fnmatch pat_next's
|
||||
// (u8 | star | ...)) return the first integer variant.
|
||||
fn coercerunelit(c: *checker, e: *node, target: *node) *node = {
|
||||
if (e == nil) { return nil; };
|
||||
if (e.kind != nkind.N_RUNELIT) { return nil; };
|
||||
if (target == nil) { return nil; };
|
||||
let tu: *node = resolvealias(c, unwrapbang(target));
|
||||
if (tu == nil) { return nil; };
|
||||
if (isinttypeast(tu)) { return tu; };
|
||||
if (tu.kind == nkind.N_TTAGGED) {
|
||||
let v: *node = tu.list;
|
||||
for (v != nil) {
|
||||
let vu: *node = resolvealias(c, unwrapbang(v));
|
||||
if (vu != nil) {
|
||||
if (isinttypeast(vu)) { return vu; };
|
||||
};
|
||||
v = v.next;
|
||||
};
|
||||
};
|
||||
return nil;
|
||||
};
|
||||
|
||||
// binoptype — derive the result tnode of an N_BIN operator expression.
|
||||
// Mirrors cstage cmd/wcc/check.c:598-640 `cbinop`. Operates on tnodes
|
||||
// returned by exprtype; ptr arithmetic / bitwise / shifts / comparisons /
|
||||
@@ -15215,6 +15257,14 @@ fn desugarcallargs(c: *checker, n: *node) void = {
|
||||
if (param.kind == nkind.N_PARAM) {
|
||||
if (param.op != tkind.TK_ELLIPSIS) {
|
||||
let atype: *node = exprtype(c, a, nil);
|
||||
// #29: a rune literal narrowing into an integer param
|
||||
// (`take('b')` where take(b: u8)). Override atype to the
|
||||
// integer target so c3's general isassignable accepts,
|
||||
// mirroring cstage's coarse untyped_rune rule. See
|
||||
// coercerunelit. cgen is byte-id-neutral (narrows by the
|
||||
// param/destination width).
|
||||
let runet: *node = coercerunelit(c, a, param.lhs);
|
||||
if (runet != nil) { atype = runet; };
|
||||
// #258: an array arg into a []T param with a
|
||||
// MISMATCHED element is not a borrow — loud reject,
|
||||
// mirror cstage's call-arg type_assignable failure.
|
||||
@@ -15267,6 +15317,13 @@ fn checkassign(c: *checker, n: *node) void = {
|
||||
if (n.rhs == nil) { return; };
|
||||
let ltn: *node = exprtype(c, n.lhs, nil);
|
||||
let rtn: *node = exprtype(c, n.rhs, nil);
|
||||
// #29: a rune literal narrowing into an integer assign/index-store
|
||||
// target (`buf[i] = 'F'`). Override rtn to the integer target so a
|
||||
// general assign typecheck accepts, mirroring cstage's coarse
|
||||
// untyped_rune rule. See coercerunelit. cgen narrows by the destination
|
||||
// width (byte-id-neutral). Removes the getopt `'X': u8` index casts.
|
||||
let runet: *node = coercerunelit(c, n.rhs, ltn);
|
||||
if (runet != nil) { rtn = runet; };
|
||||
// #31/#33: bare array-literal rhs has no backing — loud-reject
|
||||
// (supported only at a `let`).
|
||||
if (!rejectarrlitborrow(c, ltn, n.rhs)) {
|
||||
@@ -15508,6 +15565,11 @@ fn checkletassign(c: *checker, n: *node) void = {
|
||||
n.rhs.lhs = arr;
|
||||
src = arr;
|
||||
};
|
||||
// #29: an un-suffixed rune literal narrowing into an integer let target
|
||||
// (`let b: u8 = 'a'`). Override src to the integer target so isassignable
|
||||
// accepts, mirroring cstage's coarse untyped_rune rule. See coercerunelit.
|
||||
let runet: *node = coercerunelit(c, n.rhs, n.lhs);
|
||||
if (runet != nil) { src = runet; };
|
||||
let conf: bool = false;
|
||||
let ok: bool = isassignable(c, n.lhs, src, &conf);
|
||||
// #206: direct `&fn` → `*alias` / `(*alias | void)` slot.
|
||||
@@ -15573,6 +15635,12 @@ fn checkretassign(c: *checker, n: *node) void = {
|
||||
};
|
||||
let src: *node = exprtype(c, n.lhs, nil);
|
||||
if (src == nil) { return; };
|
||||
// #29: a rune literal returned into an integer (or integer-variant)
|
||||
// fnret (`return '\\';` into u8 or (u8 | star | ...)). Override src so
|
||||
// isassignable accepts; cgen boxes via the shape fallback. See
|
||||
// coercerunelit. Removes the fnmatch.ww:126 `'\\': u8` workaround cast.
|
||||
let runet: *node = coercerunelit(c, n.lhs, c.fnret);
|
||||
if (runet != nil) { src = runet; };
|
||||
let conf: bool = false;
|
||||
let ok: bool = isassignable(c, c.fnret, src, &conf);
|
||||
// #206: direct `&fn` returned into a `*alias` / `(*alias | void)`.
|
||||
|
||||
Reference in New Issue
Block a user