fix(diag): generic VALUE param ($N: u32) used as a field/annotation type → diagnostic (no .unresolved LLVM panic) [stdlib E3 attempt-3]
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.
This commit is contained in:
29
examples/0172-types-value-param-as-field-type.sx
Normal file
29
examples/0172-types-value-param-as-field-type.sx
Normal file
@@ -0,0 +1,29 @@
|
||||
// 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;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,5 @@
|
||||
error: 'N' is a value parameter, not a type; introduce a generic type parameter with `$N: Type`
|
||||
--> examples/0172-types-value-param-as-field-type.sx:22:8
|
||||
|
|
||||
22 | x: N;
|
||||
| ^
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
Reference in New Issue
Block a user