Support pattern matching (destructuring) in let bindings
- Dominant language
- Rust
- Stars
- 61
- Forks
- 4
- Avg merge
- 1d 21h
- Merged PRs (30d)
- 9
Description
## Summary
Support struct destructuring patterns in `let` bindings within `#[wgsl]` modules. Since WGSL has no native destructuring syntax, the proc macro should desugar patterns into a series of individual `let` (or `var`) bindings that access each field.
## Motivation
Currently, attempting to destructure a struct in a let binding:
```rust
let MyStruct { x, y } = some_expr;
```
produces the error: `"Unsupported pattern in let binding: '...'"` (from `parse.rs` line ~1856). Users coming from Rust expect destructuring to work, and desugaring it is straightforward since WGSL supports field access.
## Proposed Behavior
A destructuring let binding like:
```rust
let MyStruct { x, y, z } = compute_point();
```
would expand to WGSL equivalent of:
```wgsl
let _tmp = compute_point();
let x = _tmp.x;
let y = _tmp.y;
let z = _tmp.z;
```
### Mutable destructuring
```rust
let mut MyStruct { x, y } = some_expr;
```
would expand to:
```wgsl
let _tmp = some_expr;
var x = _tmp.x;
var y = _tmp.y;
```
### Field renaming
```rust
let MyStruct { x: px, y: py } = some_expr;
```
would expand to:
```wgsl
let _tmp = some_expr;
let px = _tmp.x;
let py = _tmp.y;
```
### Nested destructuring (stretch goal)
```rust
let Outer { inner: Inner { a, b }, c } = expr;
```
could expand to:
```wgsl
let _tmp = expr;
let _tmp_inner = _tmp.inner;
let a = _tmp_inner.a;
let b = _tmp_inner.b;
let c = _tmp.c;
```
## Implementation Notes
The key code locations are:
- **Parsing**: `crates/wgsl-rs-macros/src/parse.rs` ~line 1816 — the `ident_mut_ty` function inside `TryFrom<&syn::Local> for Local` currently only handles `Pat::Ident` and `Pat::Type`. Would need to handle `Pat::Struct` (and potentially `Pat::Tuple` for tuple-like access).
- **AST**: The `Local` struct (`parse.rs` ~line 1796) holds a single `ident`. Two possible approaches:
1. **Desugar during parsing**: Convert a destructuring `syn::Local` into multiple `Stmt::Local` nodes in the AST, so code generation stays unchanged.
2. **Expand during code gen**: Add a new `Stmt` variant (e.g., `Stmt::Destructure`) and expand it in `formatter.rs`.
Option 1 (desugar during parsing) is likely simpler and keeps the `Local` type and code gen untouched.
- **Code gen**: `crates/wgsl-rs-macros/src/code_gen/formatter.rs` ~line 990 — `GenerateCode for Local`. If desugaring happens at parse time, no changes needed here.
- **Temp variable naming**: The generated temporary variable (e.g., `_tmp`) must use a unique/hygienic name to avoid collisions. A counter or span-based naming scheme could work.
## Scope
- **In scope**: Struct field destructuring (`Pat::Struct`), field renaming, mutable bindings
- **Stretch**: Nested destructuring, partial destructuring with `..` (rest pattern)
- **Out of scope**: Tuple destructuring (WGSL doesn't have tuples), refutable patterns, let-else
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.