software-mansion / software-mansion/TypeGPU

feat: Smarter reference assignment checks thanks to a sort of borrow checker

Open
#2,354 0 comments 0 reactions 1 assignee View on GitHub

@cieplypolar is already working on this.

Since Apr 8, 2026.

enhancement
Dominant language
TypeScript
Stars
3.2k
Forks
122
Avg merge
3d 5h
Merged PRs (30d)
34

Description

We're given the following mutable buffer:

const Boid = d.struct({
  pos: d.vec2f,
  vel: d.vec2f,
});

const boids = root.createMutable(d.arrayOf(Boid, 512));

Let's consider a situation where we create a local boid: Boid variable, set its properties in some non-trivial way, then assign it to a mutable buffer. As of writing this issue, we throw an error saying that references cannot be assigned.

function init() {
  'use gpu';
  
  const boid = Boid();
  
  // ...
  boid.pos.x = 123;
  // ...

  boids.$[0] = boid; // ❌ Error: 'boids[0] = boid' is invalid, because references cannot be assigned (...)
}

We do this to ensure that a certain guarantee is not broken:

[!NOTE]
Expecting boids.$[0] and boid to point to the same reference after the assignment.

This is however very limiting, considering that mutating a reference that has been assigned to something is quite rare in our own examples, and we ourselves frequently reach this limitation and have to explicitly copy. What we can do instead, is forbid the code that follows an assignment to mutate a reference.

function init() {
  'use gpu';
  
  const boid = Boid();
  
  // ...
  boid.pos.x = 123;
  // ...

  boids.$[0] = boid; // ✅ This is okay, we let this assignment "consume" the reference
  
  fn(boid); // ✅ This is okay, non-pointer arguments are immutable

  boid.pos.x = 234; // ❌ Error: Cannot mutate an already assigned ("consumed") reference
}

What counts as consumption?

We need to allow up-to-one consumption of a resource, so that we don't end up with two things pointing to the same value.

  • foo = reference
  • return reference statements - since the caller of a function takes ownership of the returned value, we can't track it for further mutations. By counting return statements like consumptions, we don't allow an assigned value to be returned later on.
  • (any more?)
function init() {
  'use gpu';
  
  const boid = Boid();
  
  boids.$[0] = boid; // We let this assignment "consume" the reference

  return boid; // ❌ Error: Cannot consume a resource more than once
}

Contributor guide

Open the contributing guide

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.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.