Skip to content

fix(typecheck): resolve indexed writes at the field path they target - #42

Merged
wolfy-j merged 2 commits into
mainfrom
fix/typecheck-indexed-field-assignment
Sep 9, 2026
Merged

wolfy-j merged 2 commits into
mainfrom
fix/typecheck-indexed-field-assignment

Conversation

@wolfy-j

@wolfy-j wolfy-j commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Defect

An element assignment through a record field path later in a function (r.kinds[1] = x) makes every earlier read of r.kinds on that flow version resolve to the enclosing record type. Reproduction: a library exporting type Report = {kinds: {string}, sources: {string}} and describe(): Report; a caller doing

local described = lib.describe()
same(described.kinds, {"a", "b"})   -- error: argument 1: expected string[], got Report
described.kinds[1] = "changed"

Removing the assignment, or assigning through a local, removes the error.

Cause

Flow widening for a dynamic index write resolved the container from the path's root symbol instead of the path itself, so a.b[k] = v computed a widened type from a and stored it under the path key for a.b.

Fix

  • types/flow/transfer.go: processIndexerAssignmentReturnKey resolves the container type at the full path; predecessor joins are keyed by the path's segments; declaredTypeAtPath walks segments through the root declaration; mergeMapValueDomain keeps a declared map value domain from unioning with its own refinement.
  • Regression tests: TestIndexedFieldElementWriteKeepsFieldType, TestIndexedFieldElementWriteKeepsFieldTypeAcrossModules, TestDeclaredMapFieldIndexerWriteKeepsValueType.

go test ./... and go vet clean. Found while linting Bee (Wippy application) under wippy lint; the runtime pins go-lua v1.5.19 and needs a release plus bump to pick this up.

Flow widening for a dynamic index write resolved the container from the
path's root symbol instead of the path itself, so `a.b[k] = v` stored a
type derived from `a` under the path key for `a.b`. Every read of `a.b`
sharing that SSA version then reported the enclosing record's type.

Resolve the container, its predecessor versions and its declared template
at the full path, and apply the same path-aware declared lookup to map
element reads and iterator sources. Widening now reaches real declared
containers, so restrict value-domain widening to values the container
cannot already hold.
@skhaz
skhaz self-requested a review September 9, 2026 00:08
@wolfy-j
wolfy-j requested a review from skhaz September 9, 2026 02:01
@wolfy-j
wolfy-j merged commit 52d2294 into main Sep 9, 2026
6 checks passed
@wolfy-j
wolfy-j deleted the fix/typecheck-indexed-field-assignment branch September 9, 2026 22:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants