fix(lower): genuinely-undeclared type → diagnostic + .unresolved (no silent stub) [stdlib E3]
Phase E3: remove the silent empty-struct fall-throughs in type resolution for genuinely-undeclared names, replacing them with a real "unknown type" diagnostic + the dedicated `.unresolved` sentinel (already present, with the sizeOf @panic tripwire) — the REJECTED-PATTERN this project bans. Split `TypeHeadResolution.undeclared` into `.forward` (a real author not interned yet — self/forward/mutual/foreign reference, adopted on registration via internNamedTypeDecl) vs `.undeclared` (NO author anywhere). `resolveNominalLeaf`: - `.pending` / `.forward` keep the empty-struct stub the type adopts on register. - `.undeclared` in a NON-main (imported/library) module — which the UnknownTypeChecker trusts and never walks — emits "unknown type 'X'" + poisons with `.unresolved`. In the MAIN file the checker owns the diagnostic (and a valid unbound generic leaf legitimately lands here), so the leaf keeps the legacy stub and does not double-report. Also convert the `parameterized_type_expr` constructor-head fallback (resolveParameterizedWithBindings): an unresolvable base now emits + returns `.unresolved` (mirroring the `.call`-node sibling) instead of a 0-field stub that mis-sizes `b.field` / `b.len`. Threads the reference span through both callers. Triage of the other empty-struct sites (all load-bearing on the green suite or unable to distinguish forward from undeclared — KEPT): resolveNamed's legacy namer (forward/generic/Self/foreign-opaque: R/Self/Object/Array), the foreign-class struct + JNI Self placeholders, the shadow-slot reservation, the type_bridge stateless pack/generic namer, and the struct-literal inference fallback (front-run by the leaf; 0 suite hits). Regression: examples/0759-modules-undeclared-type-in-import — an undeclared type in an imported module now errors (exit 1) instead of silently compiling (the pre-fix code printed `thing.x = 42`, exit 0). Gate: zig build; zig build test (423/423 + LSP corpus sweep); run_examples 497 passed / 0 failed (prior 496 byte-identical); m3te ios-sim build exit 0.
This commit is contained in:
22
examples/0759-modules-undeclared-type-in-import.sx
Normal file
22
examples/0759-modules-undeclared-type-in-import.sx
Normal file
@@ -0,0 +1,22 @@
|
||||
// A genuinely-undeclared type name used in an IMPORTED (non-main) module must
|
||||
// emit a clean "unknown type" diagnostic, not silently compile.
|
||||
//
|
||||
// The `UnknownTypeChecker` only walks MAIN-file decls — imported / library
|
||||
// modules are trusted and never checked. So an undeclared type name in an
|
||||
// imported module used to fall through the type leaf's empty-struct stub and
|
||||
// silently fabricate a 0-field struct: `make_thing()` below compiled and ran
|
||||
// (printing `thing.x = 42`) even though `lib.sx` references the non-existent
|
||||
// type `Coordnate`. The source-aware nominal leaf now poisons a genuinely-
|
||||
// undeclared name with the `.unresolved` sentinel and emits the diagnostic at
|
||||
// the reference, so the typo surfaces instead of mis-sizing `Thing` downstream.
|
||||
//
|
||||
// Expected: `error: unknown type 'Coordnate'` pointing into lib.sx; exit 1.
|
||||
// Regression (stdlib E3).
|
||||
#import "modules/std.sx";
|
||||
|
||||
#import "0759-modules-undeclared-type-in-import/lib.sx";
|
||||
|
||||
main :: () -> s32 {
|
||||
print("thing.x = {}\n", make_thing());
|
||||
return 0;
|
||||
}
|
||||
14
examples/0759-modules-undeclared-type-in-import/lib.sx
Normal file
14
examples/0759-modules-undeclared-type-in-import/lib.sx
Normal file
@@ -0,0 +1,14 @@
|
||||
// Flat-imported helper. `Coordnate` is a typo — no such type is declared
|
||||
// anywhere. Because this module is imported (not the main file), the
|
||||
// `UnknownTypeChecker` trusts it and never walks it, so the type leaf is the
|
||||
// sole guard against the silently-fabricated empty-struct stub.
|
||||
Thing :: struct {
|
||||
x: s32;
|
||||
y: Coordnate;
|
||||
}
|
||||
|
||||
make_thing :: () -> s32 {
|
||||
t : Thing = ---;
|
||||
t.x = 42;
|
||||
return t.x;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,5 @@
|
||||
error: unknown type 'Coordnate'
|
||||
--> examples/0759-modules-undeclared-type-in-import/lib.sx:7:8
|
||||
|
|
||||
7 | y: Coordnate;
|
||||
| ^^^^^^^^^
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
Reference in New Issue
Block a user