Module chained_init

Module chained_init 

Source
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 index i are synthetic chained-init lowerings — identified by a span that starts after the LocalDecl’s span starts (i.e. the assignment text sits inside the chained T x = y = …; block, but the AST lifted it ahead of the decl).
descend 🔒
emit_chain_edit 🔒
rewrite_chained_assign_inits 🔒
slice 🔒
walk_block 🔒