Skip to content

fixes #26680; reuse the cached instance for generic types with static parameters - #26690

Open
Araq wants to merge 3 commits into
develfrom
fix-26680
Open

Araq wants to merge 3 commits into
develfrom
fix-26680

Conversation

@Araq

@Araq Araq commented Nov 11, 2026 •

Copy link
Copy Markdown
Member

fixes #26680

This is related to static generic parameters, but not in injectdestructors:

  • handleGenericInvocation substitutes only tyGenericParam arguments of an invocation before it searches the instance cache a second time. In B[n], n is an unresolved tyStatic, so nothing is substituted, the second search is skipped and each instantiation produces a fresh B[3] (11 instances for the test case).
  • Hooks are attached to the canonical B[3] ref and to the tyGenericInst, but the inner ref of the duplicate that b has gets none. genSink looks the op up on that ref without the canonical-type fallback that genOp has, finds no =sink and takes the =destroy(dest); dest = ri path. deepAliases doesn't see the read of b in :tmpD = g(b), so b is freed before g(b) reads it.

The fix substitutes unresolved static arguments too (only when they are bound, so a plain static[int] is left alone). With that there is a single B[3] instance and =sink is found.

In addition genSink now uses the same canonical-type fallback as genOp (factored out as findOp), so a duplicate instance that slips through some other way no longer takes the destroy-first path. Each of the two changes fixes the test case on its own.

🤖 Generated with Claude Code

Araq and others added 3 commits November 11, 2026 11:40
… parameters

`handleGenericInvocation` substituted only `tyGenericParam` arguments before
searching the instance cache again, so for `B[n]` with a `static` parameter
every instantiation created a new `B[3]`. The duplicate instance in the
caller had no lifted hooks: `genSink` found no `=sink` and its fallback
destroyed `b` before `f(g(b))` read it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Like genOp, so a structurally equal duplicate of a type without its own
hooks does not take the destroy-first fallback (bug #26680).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fixes tests/metatype/tmatrix4.nim: for implicit generics a static
parameter can be bound to its base type, which turned `TVector[T, C]`
into `TVector[float32, int]`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

ARC/ORC: =destroy emitted before the right side of x = f(g(x)) for ref types instantiated through a static generic proc

1 participant