Skip to content

feat: std.isKnownAtComptime - #3043

Open
iwoplaza wants to merge 1 commit into
software-mansion:mainfrom
iwoplaza:feat/std-is-known-at-comptime
Open

iwoplaza wants to merge 1 commit into
software-mansion:mainfrom
iwoplaza:feat/std-is-known-at-comptime

Conversation

@iwoplaza

Copy link
Copy Markdown
Collaborator

Implements #3027

@iwoplaza
iwoplaza marked this pull request as ready for review September 20, 2026 18:54
Copilot AI lite review requested due to automatic review settings September 20, 2026 18:54

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

The comptime probe can incorrectly classify array expressions and prune runtime-dependent branches.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity · 2 Low severity

Open (3)
What changed in this PR

Adds std.isKnownAtComptime for compile-time branching during shader generation, with exports, tests, and documentation.

Changes:

  • Implements and exports the new utility.
  • Adds coverage for literals, runtime values, arrays, side effects, and simulation.
  • Documents usage and loop-unrolling integration.
File Summary
packages/​typegpu/​tests/​std/​comptime.test.ts Adds behavioral and regression test coverage.
packages/​typegpu/​src/​std/​index.ts Exports the new utility.
packages/​typegpu/​src/​std/​comptime.ts Implements the comptime probe. Critical (1 vote): array expressions can be misclassified when containing runtime values, allowing incorrect branch pruning; add composite-value handling and a regression test. Nit (3 votes): rephrase the grammatically incorrect “it being able” sentence.
apps/​typegpu-docs/​src/​content/​docs/​apis/​utils.mdx Documents the API and usage. Nit (3 votes): rephrase the grammatically incorrect “it being able” sentence.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

}

return snip(
isSnippetKnownAtComptime(value),
Comment thread apps/typegpu-docs/src/content/docs/apis/utils.mdx Outdated
Comment thread packages/typegpu/src/std/comptime.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.

Important

std.isKnownAtComptime throws for valid, side-effect-free arguments. The guard keys off Snippet.possibleSideEffects, which is deliberately conservative ("unable to reliably determine it doesn't have side effects" also sets it), so an argument that is genuinely comptime-known can still be rejected. Confirmed repro below — this should be fixed (or the guard narrowed) before merge.

Reviewed changes

  • New std.isKnownAtComptime (packages/typegpu/src/std/comptime.ts) — custom DualFn; returns true in JS, and during codegen inspects isKnownAtComptime(arg) to return a bool constant snippet.
  • Export (packages/typegpu/src/std/index.ts) — wired into the std barrel.
  • Docs (apps/typegpu-docs/.../apis/utils.mdx) — new section plus a tgpu.unroll tip linking to it.
  • Tests (packages/typegpu/tests/std/comptime.test.ts) — 9 tests covering JS, literals, fn args, fixed/runtime array length, unroll selection, side-effect throw, stored side-effect, and simulate. All pass locally.
Technical details
# `std.isKnownAtComptime` rejects side-effect-free arguments

## Affected sites
- `packages/typegpu/src/std/comptime.ts:83-87` (new) — throws whenever `value.possibleSideEffects` is true.
- `packages/typegpu/src/tgsl/wgslGenerator.ts:1744` — the unroll element index is built as `snip(i, u32, 'constant')` with no 4th argument, so `possibleSideEffects` defaults to `true` (`packages/typegpu/src/data/snippet.ts:158`).
- `packages/typegpu/src/tgsl/accessIndex.ts:55` — propagates that flag to the element snippet.

## Repro (verified against this branch)
```ts
const arr = tgpu.accessor(d.arrayOf(d.u32, 3), [10, 20, 30]); // comptime default
const f = () => {
  'use gpu';
  let acc = d.u32();
  for (const x of tgpu.unroll(arr.$)) {
    acc += std.isKnownAtComptime(x) ? 1 : 0; // throws
  }
  return acc;
};
tgpu.resolve([f]);
```
Each `x` is the comptime value `10/20/30`, so `true` is the correct answer, yet resolution fails with `\`isKnownAtComptime\` received an argument with possible side effects`. Unrolling a fixed buffer-backed array (`tgpu.unroll(layout.$.boids)`) fails the same way, where the correct answer is `false`. The error message's premise ("a side-effectful expression is never known at comptime anyway, so the result would always be `false`") is therefore not accurate here.

## Required outcome
- `std.isKnownAtComptime` must not throw for arguments whose evaluation is side-effect-free but which merely carry the conservative `possibleSideEffects` flag.
- Add a regression test exercising the guard inside an unrolled loop.

## Suggested approach (optional)
- Tighten the producer: pass `/* possibleSideEffects */ false` for the synthesized constant index at `wgslGenerator.ts:1744` (and audit similar `snip(..., 'constant')` sites), or
- Narrow the guard to only reject arguments that are definitely side-effectful rather than merely not provably pure.

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

Comment on lines +83 to +85
if (value.possibleSideEffects) {
throw new WgslTypeError(
'`isKnownAtComptime` received an argument with possible side effects. The expression is never emitted into the shader, so its side effects would silently not happen, and a side-effectful expression is never known at comptime anyway, so the result would always be `false`. Remove the check, and run the side effect as a separate statement if it is needed.',

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.

This guard throws for arguments that are side-effect-free but carry the conservative possibleSideEffects flag. Snippet.possibleSideEffects is documented as "sure it has side effects OR unable to reliably determine it doesn't", so valid code like for (const x of tgpu.unroll(arr.$)) { std.isKnownAtComptime(x) } over a comptime array throws, even though x is comptime-known. See the review body for a verified repro and fix options.

Comment thread apps/typegpu-docs/src/content/docs/apis/utils.mdx
@iwoplaza
iwoplaza force-pushed the feat/std-is-known-at-comptime branch from 04c0623 to b869b07 Compare September 22, 2026 12:52
@iwoplaza
iwoplaza force-pushed the feat/std-is-known-at-comptime branch from b869b07 to 51872b1 Compare September 22, 2026 12:52

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.

2 participants