fix: optional-chain getter/field correctness from 0160 adversarial review
Five adversarial reviews of the issue-0160 fix surfaced three more bugs in the touched optional-chain / optional-coercion code; all fixed here: 1. A COLD generic-instance getter through `?.` (`?*Vec(i64)` `.getter`, never called directly first) panicked with "unresolved type reached LLVM emission": a cold instance method is absent from resolveFuncByName, so the getter's return type resolved to .unresolved → a ?unresolved merge type. lowerOptionalChain and getterReturnTypeOnDeref now warm the monomorph (ensureGenericInstanceMethodLowered) before querying its return type. (The 0907 test passed only by luck — List(i64) is warmed by stdlib use; 0907 now also exercises a cold user generic.) 2. A real-field read through a `?*T` chain (`op?.field`, op: ?*T) reinterpreted the pointer bits as the field (silent garbage) — the some-branch real-field path didn't load through the pointer. It now derefs `?*T` before the field access. (Pre-existing — the else-branch predates 0160 — but it's the same function and a silent miscompile, so fixed here.) 3. `?[]T = array` skipped the array→slice promotion (corrupt .len/.ptr): the lowerVarDecl optional arm wrapped the raw array. It now coerces the value to the optional's child type (array→slice) before wrapping. Regression examples 0906/0907 extended to cover all three. Distinct PRE-EXISTING bugs the reviews surfaced in untouched subsystems are filed as issues 0161 (struct-literal vs scalar), 0162 (#run returning an optional aggregate), 0163 (untagged-union payload-binding match).
This commit is contained in:
@@ -17,6 +17,19 @@
|
||||
> unsupported for all fields) and was never part of this bug. Regression tests:
|
||||
> `examples/optionals/0906-optionals-struct-literal-into-optional.sx` and
|
||||
> `examples/optionals/0907-optionals-accessor-through-chain.sx`.
|
||||
>
|
||||
> **Review follow-ups (5 adversarial reviews on the fix):** three further
|
||||
> optional bugs in the touched code were fixed in the same pass — (1) a COLD
|
||||
> generic-instance getter through `?.` panicked (`?unresolved`) because the
|
||||
> monomorph wasn't lowered before its return type was queried; `lowerOptionalChain`
|
||||
> + `getterReturnTypeOnDeref` now warm it. (2) a real-field read through a `?*T`
|
||||
> chain reinterpreted the pointer bits as the field (silent garbage); the
|
||||
> some-branch now loads through the pointer. (3) `?[]T = array` skipped
|
||||
> array→slice promotion (corrupt `.len`); `lowerVarDecl`'s optional arm now
|
||||
> coerces to the child before wrapping. Both regression examples were extended.
|
||||
> Separately-filed PRE-EXISTING bugs the reviews surfaced (distinct subsystems,
|
||||
> untouched here): [[0161]] struct-literal vs scalar, [[0162]] `#run` returning an
|
||||
> optional aggregate, [[0163]] untagged-union payload-binding match.
|
||||
|
||||
## Symptom
|
||||
|
||||
|
||||
Reference in New Issue
Block a user