pub(crate) fn dedup_var_declarations(src: &str) -> StringExpand description
Walk the source for var <NAME>: <TYPE> [= INIT]; declarations; the
first time a NAME appears in the current scope, keep it; every later
declaration of the same NAME in the same scope becomes a plain
assignment (NAME = INIT;) or — if it had no initialiser — is dropped
entirely.
HLSL allows float3 ret1 = ret1; to shadow a previous declaration
(or just redundantly redeclare it); WGSL rejects with
redefinition of ret1. The presets that hit this are typically
older MD2 user-shader idioms.
Scope tracking matters here. A flat seen set is wrong: a global
var tmp: f32; plus a function-local var tmp: f32; inside a helper
would drop the inner decl while the helper’s body still referenced
tmp, which then failed naga as no definition in scope for identifier: tmp. We push a fresh seen set on every { and pop
on the matching }, so each scope dedups independently.