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:
@@ -246,6 +246,13 @@ pub const Lowering = struct {
|
||||
resolved_root: ?*const Node = null, // full AST root (for building comptime modules)
|
||||
comptime_param_nodes: ?std.StringHashMap(*const Node) = null, // active comptime substitutions
|
||||
target_type: ?TypeId = null, // target type for struct/enum literals without explicit names
|
||||
// Count of diagnostics emitted by the annotated-store assignability guard
|
||||
// (`checkAssignable` / the named-return-default guard, issue 0197). Lets the
|
||||
// guard skip when ANY OTHER error already exists (`errorCount() > this`) —
|
||||
// suppressing cascades onto a pre-lowering error (an unknown annotation
|
||||
// type) or a failed initializer, while still reporting multiple INDEPENDENT
|
||||
// mismatches (each of those is one of the guard's OWN errors, not external).
|
||||
assignability_error_count: usize = 0,
|
||||
lowered_functions: std.StringHashMap(void), // tracks which functions have been fully lowered
|
||||
/// Identity map: authoring `*const ast.FnDecl` → the FuncId `declareFunction`
|
||||
/// created for it. The name-keyed function table (`resolveFuncByName`) returns
|
||||
@@ -2044,6 +2051,9 @@ pub const Lowering = struct {
|
||||
pub const lowerCoercedDefault = lower_coerce.lowerCoercedDefault;
|
||||
pub const coerceToType = lower_coerce.coerceToType;
|
||||
pub const coerceExplicit = lower_coerce.coerceExplicit;
|
||||
pub const checkAssignable = lower_coerce.checkAssignable;
|
||||
pub const noneReinterpretIsUnsafe = lower_coerce.noneReinterpretIsUnsafe;
|
||||
pub const externalErrorsExist = lower_coerce.externalErrorsExist;
|
||||
pub const coerceMode = lower_coerce.coerceMode;
|
||||
pub const diagNonIntegralNarrow = lower_coerce.diagNonIntegralNarrow;
|
||||
pub const promoteCVariadicArgs = lower_coerce.promoteCVariadicArgs;
|
||||
|
||||
Reference in New Issue
Block a user