Skip to content

fix: Global identifier inside nested function call - #2789

Open
cieplypolar wants to merge 3 commits into
mainfrom
fix/name-collision
Open

fix: Global identifier inside nested function call#2789
cieplypolar wants to merge 3 commits into
mainfrom
fix/name-collision

Conversation

@cieplypolar

Copy link
Copy Markdown
Collaborator

Closes #2788.

Copilot AI review requested due to automatic review settings August 5, 2026 11:31
@cieplypolar cieplypolar changed the title fix: Nested global identifier collision fix: Global identifier inside nested function call Aug 5, 2026
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

pkg.pr.new

packages
Ready to be installed by your favorite package manager ⬇️

https://pkg.pr.new/software-mansion/TypeGPU/eslint-plugin-typegpu@038b32a78bdaa2cbf7354f4344791a458dd5f49f
https://pkg.pr.new/software-mansion/TypeGPU/tgpu-gen@038b32a78bdaa2cbf7354f4344791a458dd5f49f
https://pkg.pr.new/software-mansion/TypeGPU/tinyest-for-wgsl@038b32a78bdaa2cbf7354f4344791a458dd5f49f
https://pkg.pr.new/software-mansion/TypeGPU/typegpu@038b32a78bdaa2cbf7354f4344791a458dd5f49f
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/cli@038b32a78bdaa2cbf7354f4344791a458dd5f49f
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/color@038b32a78bdaa2cbf7354f4344791a458dd5f49f
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/gl@038b32a78bdaa2cbf7354f4344791a458dd5f49f
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/noise@038b32a78bdaa2cbf7354f4344791a458dd5f49f
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/radiance-cascades@038b32a78bdaa2cbf7354f4344791a458dd5f49f
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/react@038b32a78bdaa2cbf7354f4344791a458dd5f49f
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/sdf@038b32a78bdaa2cbf7354f4344791a458dd5f49f
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/three@038b32a78bdaa2cbf7354f4344791a458dd5f49f
https://pkg.pr.new/software-mansion/TypeGPU/unplugin-typegpu@038b32a78bdaa2cbf7354f4344791a458dd5f49f

benchmark
view benchmark

commit
view commit

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

Resolution Time Benchmark

---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Random Branching (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [0.82, 1.69, 3.76, 5.65, 6.49, 11.80, 21.08, 22.05]
  line [0.78, 1.60, 3.62, 5.00, 6.05, 9.54, 19.92, 19.85]
  line [0.83, 1.72, 3.87, 5.93, 7.34, 10.25, 19.58, 22.29]
Loading
---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Linear Recursion (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [0.31, 0.46, 0.63, 0.84, 1.05, 1.07, 1.26, 1.49]
  line [0.28, 0.45, 0.58, 0.69, 0.96, 1.00, 1.23, 1.38]
  line [0.26, 0.51, 0.64, 0.77, 1.04, 1.07, 1.29, 1.41]
Loading
---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Full Tree (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [0.88, 1.83, 3.48, 5.75, 10.71, 23.70, 48.38, 96.40]
  line [0.74, 1.83, 3.42, 6.01, 10.54, 22.45, 48.36, 94.24]
  line [0.83, 1.83, 4.13, 6.08, 11.52, 23.79, 49.39, 100.41]
Loading

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

Bundle size comparison (import * as ... in PR vs import * as ... in target):

🟢 Decreased ➖ Unchanged 🔴 Increased (max 0.09%) ❔ Unknown
0 301 21 0

import { ... } in PR vs import * as ... in PR (is the library tree-Shakeable?):

Test tsdown
tgpu_init.ts 260.28 kB ($${\color{green}-3.2\%}$$)
tgpu_initFromDevice.ts 259.75 kB ($${\color{green}-3.4\%}$$)
tgpu_resolve.ts 165.65 kB ($${\color{green}-38.4\%}$$)
tgpu_resolveWithContext.ts 165.59 kB ($${\color{green}-38.4\%}$$)
tgpu_bindGroupLayout.ts 69.27 kB ($${\color{green}-74.2\%}$$)
tgpu_mutableAccessor.ts 66.27 kB ($${\color{green}-75.3\%}$$)
tgpu_accessor.ts 66.26 kB ($${\color{green}-75.4\%}$$)
tgpu_privateVar.ts 65.61 kB ($${\color{green}-75.6\%}$$)
tgpu_workgroupVar.ts 65.60 kB ($${\color{green}-75.6\%}$$)
tgpu_const.ts 64.85 kB ($${\color{green}-75.9\%}$$)
tgpu_fn.ts 38.45 kB ($${\color{green}-85.7\%}$$)
tgpu_fragmentFn.ts 38.45 kB ($${\color{green}-85.7\%}$$)
tgpu_vertexFn.ts 38.27 kB ($${\color{green}-85.8\%}$$)
tgpu_computeFn.ts 37.97 kB ($${\color{green}-85.9\%}$$)
tgpu_vertexLayout.ts 27.08 kB ($${\color{green}-89.9\%}$$)
tgpu_comptime.ts 14.77 kB ($${\color{green}-94.5\%}$$)
tgpu_unroll.ts 1.66 kB ($${\color{green}-99.4\%}$$)
tgpu_slot.ts 1.54 kB ($${\color{green}-99.4\%}$$)
tgpu_lazy.ts 1.19 kB ($${\color{green}-99.6\%}$$)

If you wish to run a comparison for other, slower bundlers, run the 'Tree-shake test' from the GitHub Actions menu.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a TGSL/WGSL name-collision bug where a globally-declared identifier could be generated with a name that later becomes shadowed by an identifier in a wrapping (caller) function, causing subsequent references to bind to the wrong symbol.

Changes:

  • Extend identifier-collision checks to distinguish between global and block scopes, so global identifiers avoid collisions with identifiers taken in any active block scope on the current resolution stack.
  • Add a regression test covering a global declaration accessed inside a nested function while the wrapping function has a colliding argument name.
  • Update multiple docs example snapshot tests to reflect the new, collision-free global naming (e.g., seedseed_1/seed_2).

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/typegpu/tests/tgsl/nameClashes.test.ts Adds regression test for global identifier collisions across nested resolution contexts.
packages/typegpu/src/types.ts Updates ResolutionCtx.isIdentifierTaken signature to include an explicit scope parameter.
packages/typegpu/src/resolutionCtx.ts Implements scoped identifier-taken checks and adds global-aware stack scanning for collisions.
apps/typegpu-docs/tests/individual-example-tests/vaporrave.test.ts Updates expected WGSL snapshots for new global identifier naming.
apps/typegpu-docs/tests/individual-example-tests/uniformity.test.ts Updates expected WGSL snapshots for new global identifier naming.
apps/typegpu-docs/tests/individual-example-tests/smoky-triangle.test.ts Updates expected WGSL snapshots for new global identifier naming.
apps/typegpu-docs/tests/individual-example-tests/slime-mold.test.ts Updates expected WGSL snapshots for new global identifier naming.
apps/typegpu-docs/tests/individual-example-tests/slime-mold-3d.test.ts Updates expected WGSL snapshots for new global identifier naming.
apps/typegpu-docs/tests/individual-example-tests/ripple-cube.test.ts Updates expected WGSL snapshots for new global identifier naming.
apps/typegpu-docs/tests/individual-example-tests/probability.test.ts Updates expected WGSL snapshots for new global identifier naming.
apps/typegpu-docs/tests/individual-example-tests/perlin-noise.test.ts Updates expected WGSL snapshots for new global identifier naming.
apps/typegpu-docs/tests/individual-example-tests/jump-flood-voronoi.test.ts Updates expected WGSL snapshots for new global identifier naming.
apps/typegpu-docs/tests/individual-example-tests/jelly-switch.test.ts Updates expected WGSL snapshots for new global identifier naming.
apps/typegpu-docs/tests/individual-example-tests/jelly-slider.test.ts Updates expected WGSL snapshots for new global identifier naming.
apps/typegpu-docs/tests/individual-example-tests/game-of-life.test.ts Updates expected WGSL snapshots for new global identifier naming.
apps/typegpu-docs/tests/individual-example-tests/fluid-double-buffering.test.ts Updates expected WGSL snapshots for new global identifier naming.
apps/typegpu-docs/tests/individual-example-tests/clouds.test.ts Updates expected WGSL snapshots for new global identifier naming.
apps/typegpu-docs/tests/individual-example-tests/caustics.test.ts Updates expected WGSL snapshots for new global identifier naming.
apps/typegpu-docs/tests/individual-example-tests/3d-fish.test.ts Updates expected WGSL snapshots for new global identifier naming.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed changes

This PR fixes the name-collision bug reported in #2788: a global identifier referenced from inside a nested function was not being checked against local identifiers in enclosing function/block scopes, so it could end up shadowed by a parameter of an outer function.

  • resolutionCtx.ts adds isIdentifierTakenGlobally and routes isIdentifierTaken by scope so global-scoped generation considers all enclosing block scopes.
  • types.ts updates the public ResolutionCtx interface accordingly.
  • A focused regression test in nameClashes.test.ts reproduces the exact COLLISION case from the issue.
  • 16 example-test snapshots are updated because module-scope seed variables now correctly avoid colliding with parameters named seed.

I ran the targeted tests, the full packages/typegpu/tests/tgsl suite, and the apps/typegpu-docs/tests/individual-example-tests suite — all passed, and npx tsc -p packages/typegpu/tsconfig.json --noEmit is clean.

✅ No new issues found.

One small polish item: isIdentifierTaken in packages/typegpu/src/types.ts (~line 363) is now part of the public ResolutionCtx contract with a new scope parameter, but it has no JSDoc. Adding a brief docstring (mirroring makeUniqueIdentifier/reserveIdentifier) would help consumers understand that 'global' checks the whole namespace plus all enclosing block scopes while 'block' stops at the function boundary.

Pullfrog  | View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏

Comment thread packages/typegpu/src/resolutionCtx.ts Outdated
Comment thread packages/typegpu/src/types.ts

@aleksanderkatan aleksanderkatan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great!
Just address Iwo's comments before merging

Comment thread packages/typegpu/tests/tgsl/nameClashes.test.ts

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

This incremental review covers the follow-up commits since the last Pullfrog review. The new commits address the prior JSDoc feedback and tighten the naming around the global identifier collision helper.

  • Renamed and documented the call-stack collision helper. isIdentifierTakenGlobally is now isIdentifierTakenInCallStack in resolutionCtx.ts, with a JSDoc note explaining it is used when resolving a global identifier for the first time within a nested function.
  • Added JSDoc to the public isIdentifierTaken contract. The ResolutionCtx interface in types.ts now documents the name and scope parameters.
  • Added a local-variable regression test. nameClashes.test.ts now also covers the case where a wrapping function declares const COLLISION = 1; and a nested function references a global of the same name.
  • Verified the fix. packages/typegpu/tests/tgsl/nameClashes.test.ts (10/10), the full packages/typegpu/tests/tgsl suite, apps/typegpu-docs/tests/individual-example-tests (59/59), and npx tsc -p packages/typegpu/tsconfig.json --noEmit all pass.

Pullfrog  | View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

This incremental review covers the merge commit that landed after the previous review.

  • Merged latest main into the feature branch. Commit 038b32a7 is a clean merge that does not touch the core fix files (resolutionCtx.ts, types.ts, nameClashes.test.ts).
  • Snapshot fallout is limited to vaporrave.test.ts. The merge pulled in the updated vaporrave example from main, which added a new sphereColorUniform vec4f binding and shifted subsequent binding numbers; the inline snapshot was regenerated accordingly.
  • Verified post-merge. packages/typegpu/tests/tgsl/nameClashes.test.ts (10/10), the full packages/typegpu/tests/tgsl suite, apps/typegpu-docs/tests/individual-example-tests (59/59), and npx tsc -p packages/typegpu/tsconfig.json --noEmit all pass.

Pullfrog  | View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏

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.

fix: Name collisions

4 participants