fix(diagnostics): reject reserved type-name bindings in every module (issue 0077)
The issue-0076 reserved-type-name binding diagnostic only ran over main-file decls, so an imported module (or the stdlib) could still declare `s2 := ...` and reach lowering, where the address-of family loads the whole aggregate and passes it by value to a `ptr` param — LLVM verifier abort. Extend coverage to every compiled module: a dedicated `checkBindingNames` walk (in semantic_diagnostics.zig) visits every var/`:=`/typed-local binding name and function/lambda/struct-method parameter at any depth, with NO main-file filter, descending the `namespace_decl` that a `mod :: #import` wraps so imported-module decls are reached. It tracks each module's source_file (save/restore per node) so the diagnostic renders against the imported module's text. Rejection still defers to the parser's `Type.fromName` classifier; the unknown-type check (0064) stays main-file-only. No lowering special-case; `.identifier`-only address-of paths are unchanged. Stdlib audit: the only reserved-name bindings under library/ were two `u1` locals in ui/renderer.sx (UV coords) — renamed to u_min/u_max/v_min/v_max. Regression test: examples/1120-diagnostics-imported-reserved-type-name.sx (+ companion mod.sx) — an imported `s2 := ...` now emits the clean diagnostic at the import's declaration site (exit 1), not an LLVM abort. Resolves issues 0076 (coverage extension) and 0077.
This commit is contained in:
16
examples/1120-diagnostics-imported-reserved-type-name.sx
Normal file
16
examples/1120-diagnostics-imported-reserved-type-name.sx
Normal file
@@ -0,0 +1,16 @@
|
||||
// A value binding spelled as a reserved type name (`s2`, the `sN` arbitrary-
|
||||
// width int syntax) is rejected at its declaration site even when it lives in
|
||||
// an IMPORTED module — the reserved-name binding diagnostic covers every
|
||||
// compiled module, not just the main file. Without universal coverage the
|
||||
// binding reaches lowering and aborts LLVM verification (a loaded aggregate
|
||||
// passed by value to a `*Box` param).
|
||||
//
|
||||
// Regression (issue 0077): the imported-module facet of issue 0076. Expected:
|
||||
// one clean diagnostic pointing at the imported module's `s2 := ...`, exit 1 —
|
||||
// NOT an LLVM verifier abort.
|
||||
#import "modules/std.sx";
|
||||
mod :: #import "1120-diagnostics-imported-reserved-type-name/mod.sx";
|
||||
|
||||
main :: () -> s32 {
|
||||
return mod.run_imported_reserved_name();
|
||||
}
|
||||
16
examples/1120-diagnostics-imported-reserved-type-name/mod.sx
Normal file
16
examples/1120-diagnostics-imported-reserved-type-name/mod.sx
Normal file
@@ -0,0 +1,16 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
Box :: struct { total: s64 = 0; count: s64 = 0; }
|
||||
|
||||
update :: (self: *Box, n: s64) {
|
||||
self.total += n;
|
||||
self.count += 1;
|
||||
}
|
||||
|
||||
run_imported_reserved_name :: () -> s32 {
|
||||
s2 := Box.{ total = 0, count = 0 };
|
||||
update(@s2, 5);
|
||||
s2.update(7);
|
||||
print("imported s2 total={} count={}\n", s2.total, s2.count);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,5 @@
|
||||
error: 's2' is a reserved type name and cannot be used as an identifier
|
||||
--> examples/1120-diagnostics-imported-reserved-type-name/mod.sx:11:5
|
||||
|
|
||||
11 | s2 := Box.{ total = 0, count = 0 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
Reference in New Issue
Block a user