[P2] Compiler: structuredClone duplicates shared object references

Closed
#3,463 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

A pull request for this has already been merged.

  • #3329 by @nickna — merged

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
22/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
csharp, nodejs, typescript
Domain
compilers

Research direction

Start from the emitted CloneCore(Object) path that the structuredClone call compiles to, and check how it recurses into each child without a per-call reference memo. Run the four-line alias repro ({left:child,right:child}) through the compiler and confirm value.left===value.right prints false in saved output but true under Node. Done means the saved and whole-IL runs both print true 1, with the memo scoped to a single clone call and no global cache or guest constructor calls.

Written by the indexing model from the issue text.

Description

bug priority: P2

Saved compiled structuredClone duplicates a repeated ordinary object reference instead of preserving the input graph's identity.

const child:any={n:1};
const value:any=structuredClone({left:child,right:child});
console.log(value.left===value.right,value.left.n);

Strict TypeScript6.0.3 accepts. Node22.23.2 and copied immutable1aa interpretation print true1. Identical compiled source passes independent wholeIL0 before saved execution, then prints false1. Both naturally exit0; this is an observable value/identity defect.

The emitted CloneCore(Object) recursively clones each child without carrying a per-call reference memo. A bounded private recursive helper may retain the existing entry signature, share one reference dictionary across recursive container arms, and register an allocated result before visiting children. It must not use a global cache, invoke guest constructors, or add arbitrary CLR reflection/metadata roots.

This was found while planning #3458 ordinary-class cloning, whose cycle/shared-child controls need the same graph identity guarantee. The memo prerequisite is independently demonstrated on already supported plain records and must remain separate from class admission. No unsafe cyclic compiled baseline was executed; the finite acyclic witness above suffices. Candidate cycle controls should run only after the corrected allocation/memo seams are reviewed.

All-state identity/shared-reference/alias/cycle searches found no focused open owner. Closed #1255 corrected shallow cloning but does not establish repeated-reference graph preservation. #3432 owns transfer-option ordering, #3440 retained detached-view state, and #3458 class-instance admission; none owns this plain-record alias witness.

Evidence: artifacts/p2-work/structured-clone-class-instances-3458/alias-dependency-baseline-1aa-v1/proof.json
Proof SHA256: A5DC15A572BF73925A8648311A927A4EEF0D4AE2AF39BA5E7E3108B5DA17407C
Source SHA256: B89085DB65CD1E0AE96EFFD2F8B271AD36BEA4A585C6DD579571144DB7479811
Compiler SHA256: 1693E6DD014F474E8FB27170A6E03F9B2DBFDEAE8154EFBD358AF422AF1044CD
Profile: --no-tsconfig --lib es2022,dom, standalone/ref-asm, wholeIL0 before saved. All original raw TS/Node/I/compile/IL/saved receipts are retained. Repeated-reference identity is standard observable structured-clone behavior, warranting priority P2.

Dominant language
C#
Stars
156
Forks
4
Avg merge
14h 43m
Merged PRs (30d)
43

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from nickna/SharpTS

All issues in nickna/SharpTS

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.