fix: type-safe stores + Any unbox/eq; finish multi-return deferrals

Type-checking gaps (segfault/corruption → compile errors):

- 0197: reject a store into an annotated slot whose value has no modeled
  coercion AND a different byte width (a 16-byte string into a 4-byte i32
  overran the slot and segfaulted). New checkAssignable / noneReinterpretIsUnsafe
  (coerce.zig, width via the LLVM-accurate typeSizeBytes) wired into every store
  site: var/const-decl, single + multi assignment (identifier/field/index/
  element/deref), named-return defaults. Same-width reinterpretations (*T→[*]T,
  i64→isize, fn-ref) and explicit xx/cast stay allowed; cascades suppressed via
  externalErrorsExist. Examples 1205, 1206.
- 0198: an implicit `Any → T` unbox is now a compile error (it blindly
  reinterpreted the boxed payload — silent garbage for a wrong scalar, a segfault
  for an aggregate). xx and compiler-generated match/pack unboxes are unaffected.
  Example 1207.
- 0199: `Any == <concrete>` (one operand Any) aborted the LLVM verifier — the
  comparison arm now fires when either operand is Any, boxing the concrete side
  first. Example 0654.

Multi-return deferrals (PLAN-MULTIRET #6 + named-order + D3 + generic):

- Reorder named return elements by name instead of requiring slot order; error on
  unknown/duplicate/missing (value-only AND full-failable-tuple forms). Examples
  0210, 0214.
- Reject a bare-paren (A, B) multi-return signature in generic-arg position
  (return-position-only). Example 0215.
- Multi-return closure types / lambda literals work via the reused tuple
  machinery (destructure, single-bind+field, lambda arg). Example 0216.
- Generic multi-return: positional works (0217); 0200: the named-slot
  implicit-return form now works for generic free fns + struct methods —
  monomorphizeFunction now calls bindNamedReturnSlots. Example 0218.

readme.md documents the annotated-store coercion rule; CHECKPOINT-MULTIRET.md
updated. Full corpus green (850/0).
This commit is contained in:
agra
2026-06-27 17:28:27 +03:00
parent 97772abf54
commit b322dcfe61
51 changed files with 1000 additions and 56 deletions

View File

@@ -0,0 +1,17 @@
error: cannot initialize 'x' of type 'i32' with a value of type 'string'
--> examples/diagnostics/1205-diagnostics-annotated-init-type-mismatch.sx:19:15
|
19 | x : i32 = "hi"; // error: cannot initialize 'x' (string ↛ i32)
| ^^^^
error: cannot reassign 'y' of type 'i32' with a value of type 'string'
--> examples/diagnostics/1205-diagnostics-annotated-init-type-mismatch.sx:22:9
|
22 | y = "nope"; // error: cannot reassign 'y' (string ↛ i32)
| ^^^^^^
error: cannot initialize 'C' of type 'i32' with a value of type 'string'
--> examples/diagnostics/1205-diagnostics-annotated-init-type-mismatch.sx:24:15
|
24 | C : i32 : "also"; // error: cannot initialize 'C' (string ↛ i32)
| ^^^^^^

View File

@@ -0,0 +1,23 @@
error: cannot assign 'a' of type 'i32' with a value of type 'string'
--> examples/diagnostics/1206-diagnostics-store-width-mismatch.sx:21:11
|
21 | s.a = "field"; // error: struct field, string ↛ i32
| ^^^^^^^
error: cannot assign 'element' of type 'i64' with a value of type 'string'
--> examples/diagnostics/1206-diagnostics-store-width-mismatch.sx:24:14
|
24 | arr[0] = "elem"; // error: array element, string ↛ i32
| ^^^^^^
error: cannot assign 'target' of type 'i32' with a value of type 'string'
--> examples/diagnostics/1206-diagnostics-store-width-mismatch.sx:28:11
|
28 | p.* = "deref"; // error: pointer deref, string ↛ i32
| ^^^^^^^
error: cannot assign 'u' of type 'i32' with a value of type 'string'
--> examples/diagnostics/1206-diagnostics-store-width-mismatch.sx:31:12
|
31 | u, v = "multi", 9; // error: multi-assign target, string ↛ i32
| ^^^^^^^

View File

@@ -0,0 +1,11 @@
error: an 'Any' does not implicitly unbox to 'i64': the boxed type is not checked, so a wrong target reinterprets the payload (a wrong scalar silently yields garbage; an aggregate dereferences it and crashes). Dispatch on the value's type with `match`, or force it with `xx` if you know the boxed type.
--> examples/diagnostics/1207-diagnostics-any-implicit-unbox-rejected.sx:19:5
|
19 | n : i64 = x; // error: 'Any' does not implicitly unbox to 'i64'
| ^^^^^^^^^^^^
error: an 'Any' does not implicitly unbox to 'S': the boxed type is not checked, so a wrong target reinterprets the payload (a wrong scalar silently yields garbage; an aggregate dereferences it and crashes). Dispatch on the value's type with `match`, or force it with `xx` if you know the boxed type.
--> examples/diagnostics/1207-diagnostics-any-implicit-unbox-rejected.sx:20:5
|
20 | s : S = x; // error: 'Any' does not implicitly unbox to 'S'
| ^^^^^^^^^^