Skip to content

Give const bindings with bound-method fields (generators) real identity storage#244

Merged
ASDAlexander77 merged 1 commit into
mainfrom
const-let-storage-rework
Jul 18, 2026
Merged

Give const bindings with bound-method fields (generators) real identity storage#244
ASDAlexander77 merged 1 commit into
mainfrom
const-let-storage-rework

Conversation

@ASDAlexander77

Copy link
Copy Markdown
Owner

Summary

  • Root-cause fix superseding the boundRefMaterializedCache workaround: a const binding whose type is a value-typed tuple aggregate with a bound-method field (currently only the generator wrapper's next()) now gets real storage (an alloca) at declaration time, exactly like let — instead of lazily discovering the need for a ref cache at the first property access.
  • Surveyed how classes/arrays/objects/tuples actually lower to LLVM first: classes, arrays, and objects are already pointer-like regardless of const/let, so they don't need this treatment — only tuple-shaped values with a bound method do. Full writeup in tslang/docs/const-let-storage-design.md.
  • Surfaced and fixed a second bug along the way: resolveIdentifierAsVariable only loads through a variable's ref when getReadWriteAccess() is set, which previously never mattered for const (no storage). Now that identity-storage consts have storage, that flag is also set for them, fixing a crash where call sites got the raw ref/pointer instead of the loaded value.

Test plan

  • Debug build clean (cmake --build ... --target tslang --config Debug)
  • 00generator_manual_next.ts, 00generator_manual_next2.ts, 00generator7.ts pass via JIT
  • Full suite: 350/350 JIT + 354/354 compile, 0 failures (ctest -R "^test-jit-" / -R "^test-compile-", -j8)
  • Confirmed the separate, known parameter-aliasing bug (generator passed as a function parameter still copies rather than aliases) is unaffected — still present, not masked, not newly broken — via a throwaway repro

🤖 Generated with Claude Code

@ASDAlexander77
ASDAlexander77 merged commit a8f4b14 into main Jul 18, 2026
2 checks passed
@ASDAlexander77
ASDAlexander77 deleted the const-let-storage-rework branch July 18, 2026 12:13
ASDAlexander77 added a commit that referenced this pull request Jul 18, 2026
… value tuple (#245)

Object literals in this compiler compile to value-typed tuples by default,
even though the generator wrapper ({step, next()}) has mutable identity that
must be shared across aliases. This meant passing a generator to a function,
capturing it in a closure, or reassigning it (const b = a) all silently
copied its state instead of aliasing it.

Add InternalFlags::BoxAsObject to mark the synthetic wrapper literal built by
buildGeneratorWrapperDeclaration, and heap-box it (NewOp + StoreOp + CastOp,
the same recipe castTupleToInterface already uses) into ObjectType instead of
leaving it as a tuple. Property access on ObjectType already emits a
PropertyRefOp directly on the pointer, so .next() now mutates shared storage
for every alias.

Supersedes the const-storage-only fix in #244 for generators specifically,
and fixes the parameter-aliasing bug that fix explicitly left open.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
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.

1 participant