Expand description
Pass: lower chained assignment in local-decl init position.
HLSL accepts T x = y = expr; (and deeper chains like
T x = y = z = expr;), evaluating right-to-left. WGSL has no
assignment expression — var x: T = (y = expr); is rejected at parse.
The corpus shape that hits this is a Martin/Rovastar idiom found in
~8 / 2 000 random presets:
float2 ruv = uv = 0.5 + (uv-0.5)*(1+(rc.y*0.05));Rewrite: lift the inner assignments out as statements that run before the decl, then initialise the decl from the leftmost LHS:
uv = 0.5 + (uv-0.5)*(1+(rc.y*0.05)); float2 ruv = uv;Detection runs on the AST produced by crate::parse::parse_hlsl.
The parser already lowers the chain into a sequence of synthetic
Stmt::Assigns followed by the Stmt::LocalDecl; here we just
recognise that the synthetic assigns’ spans sit after the decl’s
span in source order (whereas a hand-written
uv = 0.5; float2 ruv = uv; has the assign’s span before the
decl’s). One edit replaces the original chained source with the
lowered statements; the existing trailing ; is preserved.
Functions§
- count_
preceding_ 🔒synthetic - How many
Stmt::Assigns immediately before indexiare synthetic chained-init lowerings — identified by a span that starts after the LocalDecl’s span starts (i.e. the assignment text sits inside the chainedT x = y = …;block, but the AST lifted it ahead of the decl). - descend 🔒
- emit_
chain_ 🔒edit - rewrite_
chained_ 🔒assign_ inits - slice 🔒
- walk_
block 🔒