Files
sx/examples/1116-diagnostics-tuple-type-nontype-element-rejected.sx
agra 744decc6a1 fix(ir): reject non-type elements in tuple-literal-as-type (issue 0067)
`size_of((s32, 1))` treated the tuple literal as a tuple TYPE: for the non-type
element `1` it emitted a `std.debug.print` and substituted `.s64` for that field,
then compiled and printed a bogus size — a silent fabricated type (the forbidden
silent-fallback pattern).

Fix:
- type_bridge.resolveTupleLiteralAsType: a non-type element now yields
  `.unresolved` (no `.s64`, no debug print) — it refuses to fabricate a tuple.
  type_bridge is stateless, so this is the binding-free backstop.
- New stateful Lowering.resolveTupleLiteralTypeArg validates each element via
  isTypeShapedAstNode, emits a user-facing diagnostic at the offending element's
  span, and returns `.unresolved`. Wired into resolveTypeArg (size_of/align_of/…)
  and the resolveTypeWithBindings name-fallback; type_bridge builds the tuple
  only after validation passes.

Regression: examples/1116-diagnostics-tuple-type-nontype-element-rejected.sx
(exit 1 + diagnostic). Valid `(s32, s32)` still works (0115). Gate: zig build,
zig build test, run_examples 351/0.
2026-06-02 15:51:04 +03:00

14 lines
543 B
Plaintext

// A tuple literal used in a type position (`(s32, s32)` reinterpreted as a tuple
// type at a type-demanding site like `size_of`) must list only types. A non-type
// element — here the `1` in `(s32, 1)` — is rejected with a user-facing
// diagnostic instead of silently fabricating an `s64` field for that slot.
// Regression (issue 0067).
// Expected: a clean "tuple type element is not a type" error at the `1`; exit 1.
#import "modules/std.sx";
main :: () -> s32 {
print("bad tuple type size = {}\n", size_of((s32, 1)));
0
}