Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Pitfalls and Constraints

Run Order Is Declaration Order

Extensions run in the order listed in #[wgsl(extensions = [...])]. There is no priority field, no topological sort, no guaranteed order beyond the list. If two extensions conflict, order them explicitly in the attribute.

Type Substitution Happens After modify_ir

modify_ir runs before type instantiation. Do not attempt to outsmart substitution by string-replacing type names or pre-resolving TypeParam nodes. Operate on IR nodes and let the instantiation pass substitute TypeParam nodes automatically into anything you inject.

Attributes Are Not in WGSL Output

ir::Attribute values are preserved on IR nodes for extension inspection only. They are never rendered into WGSL. Do not rely on them appearing in the final shader source, and do not try to emit WGSL by stuffing text into attribute args.

Extension Types Must Be Visible at the Call Site

The paths in #[wgsl(extensions = [path::ExtA, path::ExtB])] must resolve at the location of the wgsl attribute. Import the extension types or use fully-qualified paths.

Non-WgslExtension Types Are Rejected at Compile Time

The macro generates code that calls Ext::modify_ir. If a listed type does not implement WgslExtension, the error surfaces as a compile-time trait bound failure, not a runtime error.

Don't Rely on WGSL_MODULE Being Mutable

Extensions receive &mut ir::Module, not &mut wgsl_rs::Source. The surrounding Source is not mutable from within an extension. Do all your work through the Module reference.

Trait Is Re-exported at the Crate Root

Import the trait from wgsl_rs, not wgsl_rs::extension:

#![allow(unused)]
fn main() {
use wgsl_rs::WgslExtension;
}

Both paths work, but the crate-root re-export is the documented public path.