Rule 6.2
On this page

Rule 6.2

Chapter 6, Declarations and resources Test

A storage binding’s access mode is its second type argument: storage<T> is var<storage, read> and storage<T, "read_write"> is var<storage, read_write>. The only two words the argument takes are "read" and "read_write", spelled as string literal types. A uniform binding is read-only and has no access mode, so uniform<T> takes one type argument. A write to a read-only resource must be refused, by the compiler and by the editor.

The rule text and the parts under it are the compiler's own English, as the design document writes them.

Rationale

the access mode is part of the WGSL type, so it belongs in the type, and the host’s bind group layout has to agree with it; the declaration keyword cannot carry it, because a TypeScript const array forbids rebinding the name and permits arr[0] = 1, which is the opposite of what a const storage buffer meant.

Derives from

var Declarations and Memory Access Mode; surface §7. The two words are WGSL’s own enumerants and already appear on this surface in texture_storage_2d<"r32float", "read_write">, so neither takes a §9.3 row.

How it is verified

Checked by a test. A test, a gate script or a CI workflow names this rule, and the traceability check fails when a file listed below stops naming it.

Where the rule says the compiler enforces it:

  • TS8002 for an access word outside the two, and for a second type argument on a uniform<T>, raised in src/compiler/ts/bindings.ts, which recovers the binding as read_write so that the author’s own write is not a second sentence on the same program;
  • TS8099 for the retired { access } option of the call form, raised in the same file, whose sentence names the type-argument spelling to write;
  • TS8005 CONST_ASSIGN for a write to a read-only resource, whose sentence names the storage<T, "read_write"> remedy when the target is a storage binding (writableRemedy in src/compiler/ts/context.ts), and for an atomic builtin on a read binding, whose sentence names the mode rather than the keyword (src/compiler/ts/lower/atomics.ts). It names no line in the two cases where no line would close the program: when the binding’s declared value type was itself refused and recovered, since the line would be built from a type the compiler could not read (storage<mat2x3<f64>> was answered with storage<mat2x3, "read_write">, the <f64> dropped), and when the target is no place on either mode, which is why the root’s access is checked after the target is known to be one, for an element (md[0] on an f64 matrix) and for a member after every one of that branch’s refusals (src.length, an emulated-double lane dv[0].x, a multi-component swizzle v.xy);
  • TypeScript’s own codes in the editor, because the ambient library resolves storage<T> and uniform<T> to ReadView<T> and storage<T, "read_write"> to T itself: TS2542 on an indexed write (src[0] = 1.), TS2540 on a field write (u.scale = 1.), TS2344 on an access word outside the two and TS2314 on a second type argument to a uniform (src/language-service/ambient.test.ts);
  • src/compiler/ts/declare-bind.test.ts for the access mode each spelling collects, and src/compiler/ts/remedy-lines.test.ts for the lines these sentences name: every refusal that quotes a declaration has that declaration written back into its own program, which must then compile clean and be clean in the editor;
  • not by the editor in two places, which Appendix B records: an atomic builtin on a read binding and a mutating method on a class-typed read binding are refused by the compiler alone.

The files that verify it at commit 26de7be8, each at the first line that names the rule:

Explained in

The sections of the surface document that explain this rule, at commit 26de7be8:

Error codes that enforce it

The diagnostic codes the rule names under Enforced by, or whose registry text names the rule:

TS8002 UNKNOWN_TYPE
A type name nothing declares, said once for the file wherever it is written (a parameter, a claim, a type argument, B<vec3<Foo>> included, an alias, an implements clause, the base a class or an interface extends, a body no call lowers), a type the library declares for TypeScript alone (Number) where the file declares none of its name, or a type this surface does not take in a position the mapper reads (Rule 2.1).
TS8005 CONST_ASSIGN
An assignment to a name that cannot change, such as a const or a read-only resource.
TS8099 UNSUPPORTED
UNSUPPORTED (TS8099) is the one deliberate exception to "sequential": it is the catch-all for a diagnostic whose site does not yet deserve its own code, so it stays parked past the sequential range instead of at its head.

See also

Source

The rule at commit 26de7be8:

Edit this page Report a problem