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).
28 lines
1.0 KiB
Plaintext
28 lines
1.0 KiB
Plaintext
// Comparing an `Any` against a concrete value (a MIXED `Any == <concrete>`, in
|
|
// either operand order) compares the boxed value words — the same value-identity
|
|
// the both-`Any` comparison uses. Boxing the concrete side first keeps the
|
|
// operands shape-compatible.
|
|
//
|
|
// Regression (issue 0199): a mixed `Any == <concrete>` fell through to a plain
|
|
// `icmp` on a 16-byte `{tag, value}` aggregate vs a scalar, aborting the LLVM
|
|
// verifier ("Both operands to ICmp are not of the same type"). The both-`Any`
|
|
// form already worked; this extends it to one-sided `Any` comparisons.
|
|
|
|
#import "modules/std.sx";
|
|
|
|
main :: () -> i64 {
|
|
x : Any = 5;
|
|
print("{}\n", x == 5); // true
|
|
print("{}\n", x == 6); // false
|
|
print("{}\n", x != 6); // true
|
|
print("{}\n", 5 == x); // true (concrete on the left)
|
|
|
|
b : Any = true;
|
|
print("{}\n", b == true); // true
|
|
print("{}\n", b == false); // false
|
|
|
|
y : Any = 5;
|
|
print("{}\n", x == y); // true (both Any — unchanged)
|
|
return 0;
|
|
}
|