fix: reject non-type expression in type position instead of fabricating {} (issue 0189)

Two type-resolution paths silently resolved a non-type AST node in type
position to a zero-field `{}` struct that reached codegen with no
diagnostic:
  - a dotted `type_expr` / field-access (`g.a`, `g` a runtime value) whose
    prefix is not a namespace alias
  - an `error_type_expr` (`!Name`) whose `Name` is not a declared error set

Now both reject loudly:
  - `resolveTypeWithBindings` (lower.zig): "expected a type, found a value
    '<name>' in type position" + `.unresolved`
  - `checkTypeNodeForUnknown` (semantic_diagnostics.zig): validates a named
    `!E` against the declared error-set names — "unknown error set
    '<name>'" / "expected an error set after '!', found type '<name>'".

A bare `!` (void channel) and a declared `!E` in return position stay
valid; namespace-qualified types (`pkg.Type`) are unaffected.

Regression: examples/diagnostics/1195-diagnostics-non-type-in-type-position.
This commit is contained in:
agra
2026-06-25 20:35:02 +03:00
parent f52e16a3fc
commit 45e69ac1bb
7 changed files with 197 additions and 5 deletions

View File

@@ -0,0 +1,29 @@
error: unknown error set 'Nonexistent'
--> examples/diagnostics/1195-diagnostics-non-type-in-type-position.sx:31:9
|
31 | z : !Nonexistent = ---; // `!` of an undeclared name
| ^^^^^^^^^^^^
error: unknown error set 'Nonexistent'
--> examples/diagnostics/1195-diagnostics-non-type-in-type-position.sx:32:20
|
32 | w : Tuple(i32, !Nonexistent) = ---; // nested in a tuple
| ^^^^^^^^^^^^
error: unknown error set 'Nonexistent'
--> examples/diagnostics/1195-diagnostics-non-type-in-type-position.sx:33:17
|
33 | v : Closure(!Nonexistent) -> i32 = ---; // nested in a closure param
| ^^^^^^^^^^^^
error: expected a type, found a value 'g.a' in type position
--> examples/diagnostics/1195-diagnostics-non-type-in-type-position.sx:29:9
|
29 | x : g.a = ---; // field-access value in type position
| ^^^
error: expected a type, found a value 'g.a' in type position
--> examples/diagnostics/1195-diagnostics-non-type-in-type-position.sx:30:20
|
30 | y : Tuple(i32, g.a) = ---; // same, as a tuple element
| ^^^