The generic-struct field checker (attempt-2) accepted ALL struct type
params as valid type-name leaves, including VALUE params. The parser
marks any reference to a struct's own param `is_generic` (so `x: T`
resolves without `$`), and it marks a value param `$N: u32` the same
way — so `Bad :: struct($N: u32) { x: N; }` instantiated `Bad(3)` slipped
past the unknown-type walk, resolved the field's type leaf to the
`.unresolved` sentinel, and panicked at LLVM emission instead of
diagnosing.
Distinguish TYPE params (`$T: Type`, `$T: SomeProtocol`, the `..$Ts`
pack) from VALUE params (`$N: u32`) using the binder's own classification
rule (lower.zig). A value param named in a type position now gets the
tailored "'N' is a value parameter, not a type" hint, exit 1, before
codegen. Two dispatch paths covered: the `is_generic` struct-field path
(reportIfValueParamInTypePosition) and the non-generic annotation path
(reportIfUnknownType in-scope filter). A value param in a VALUE position
(array dim `[N]u8`, `Vector` lane) still resolves.
Regression: 0172-types-value-param-as-field-type (panic-before / clean
diagnostic-after). 0171 and 0759 stay green; 499 markers, prior
byte-identical.
30 lines
1.2 KiB
Plaintext
30 lines
1.2 KiB
Plaintext
// A generic struct's VALUE param (`$N: u32`) is a compile-time integer, not a
|
|
// type. Naming it in a TYPE position — here a field type `x: N` — must emit a
|
|
// clean diagnostic, NOT silently compile.
|
|
//
|
|
// The parser marks any reference to a struct's own type param `is_generic`
|
|
// (so `x: T` for a real `$T: Type` resolves without a `$`). That marking is
|
|
// the same for a value param, so the unknown-type walk used to skip `x: N`
|
|
// entirely; the field's type leaf then resolved to the `.unresolved` sentinel
|
|
// and PANICKED at LLVM emission ("unresolved type reached LLVM emission").
|
|
//
|
|
// The checker now distinguishes TYPE params (`$T: Type`, `$T: SomeProtocol`,
|
|
// the `..$Ts` pack) from VALUE params (`$N: u32`) using the binder's own rule:
|
|
// a value param named in a type position gets the tailored hint. A value param
|
|
// in a VALUE position (a `[N]u8` array dimension, a `Vector` lane count) still
|
|
// works (see 0147 / 0201).
|
|
//
|
|
// Expected: `error: 'N' is a value parameter, not a type`; exit 1.
|
|
// Regression (stdlib E3).
|
|
#import "modules/std.sx";
|
|
|
|
Bad :: struct($N: u32) {
|
|
x: N;
|
|
}
|
|
|
|
main :: () -> s32 {
|
|
b : Bad(3) = .{ x = 1 };
|
|
print("{}\n", b.x);
|
|
return 0;
|
|
}
|