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).
23 lines
1.0 KiB
Plaintext
23 lines
1.0 KiB
Plaintext
// An `Any` does not IMPLICITLY unbox to a concrete type. A blind unbox
|
|
// reinterprets the boxed payload word as the target with NO runtime tag check,
|
|
// so a wrong target silently yields garbage (a scalar) or dereferences the
|
|
// payload as a pointer and segfaults (an aggregate). sx rejects the implicit
|
|
// unbox at compile time — like the no-implicit-optional-unwrap rule — and
|
|
// directs the user to `match` on the value's type or an explicit `xx`.
|
|
//
|
|
// Regression (issue 0198): `s : S = some_any` segfaulted and `f : f64 = some_any`
|
|
// silently produced 0.0; both are now compile errors. The fix is in `coerceMode`
|
|
// (`.unbox_any` arm, mode == .implicit). The `xx` escape hatch and the
|
|
// compiler-generated type-dispatch / pack-extraction unboxes are unaffected.
|
|
|
|
#import "modules/std.sx";
|
|
|
|
S :: struct { a: i64; }
|
|
|
|
main :: () -> i64 {
|
|
x : Any = 5;
|
|
n : i64 = x; // error: 'Any' does not implicitly unbox to 'i64'
|
|
s : S = x; // error: 'Any' does not implicitly unbox to 'S'
|
|
return 0;
|
|
}
|