Skip to content

Commit 106916d

Browse files
committed
Keep cached WGSL alias redirects live
1 parent 33d0822 commit 106916d

6 files changed

Lines changed: 63 additions & 2 deletions

File tree

bevy_wgsl_parity_test.mbt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,38 @@ test "naga_oil parity: import-only Bevy mesh root tree-shakes to empty" {
8585
debug_inspect(source.trim().length(), content="0")
8686
}
8787

88+
///|
89+
test "naga_oil parity: Bevy PBR fragment resolves aliased clustered lights" {
90+
let source = bevy_parity_compose(
91+
"bevy_pbr/src/render/pbr.wgsl",
92+
bevy_parity_forward_defines(),
93+
)
94+
debug_inspect(
95+
source.contains("view_bindings::clustered_lights"),
96+
content="false",
97+
)
98+
debug_inspect(
99+
source.contains("view_bindings__clustered_lights"),
100+
content="true",
101+
)
102+
}
103+
104+
///|
105+
test "naga_oil parity: Bevy PBR functions resolves local view bindings alias" {
106+
let source = bevy_parity_compose(
107+
"bevy_pbr/src/render/pbr_functions.wgsl",
108+
bevy_parity_forward_defines(),
109+
)
110+
debug_inspect(
111+
source.contains("view_bindings::clustered_lights"),
112+
content="false",
113+
)
114+
debug_inspect(
115+
source.contains("view_bindings__clustered_lights"),
116+
content="true",
117+
)
118+
}
119+
88120
///|
89121
test "naga_oil parity: Bevy lighting keeps tree-shaken alias const targets live" {
90122
let composer = @compose.Composer::default()

compose/import_graph.mbt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,10 +425,19 @@ fn collect_wgsl_live_alias_redirects(
425425
for scoped_redirect in alias_redirects {
426426
let redirect = scoped_redirect.redirect
427427
let to_name = redirect.to_name.trim().to_owned()
428+
let source_contains_cached_alias = if scoped_redirect.scope ==
429+
CachedQualifiedAliasReference {
430+
wgsl_semantic_source_contains_reference_path(source, redirect.from_name) catch {
431+
error => raise composer_error_from_wgsl_parse_error(error)
432+
}
433+
} else {
434+
false
435+
}
428436
if to_name != "" &&
429437
(
430438
declared_names.contains(to_name) ||
431-
scoped_redirect.scope == UnqualifiedItemBinding
439+
scoped_redirect.scope == UnqualifiedItemBinding ||
440+
source_contains_cached_alias
432441
) {
433442
live_redirects.push(redirect)
434443
}

compose/modules.mbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ fn collect_wgsl_cached_import_redirects(
9999
let scope = if alias_name == "" {
100100
UnqualifiedItemBinding
101101
} else {
102-
QualifiedAliasReference
102+
CachedQualifiedAliasReference
103103
}
104104
redirects.push(WgslScopedAliasRedirect::{
105105
redirect: WgslSymbolRedirect::{ from_name, to_name: imported_name },

compose/session.mbt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ priv struct WgslComposeSession {
131131
///|
132132
priv enum WgslAliasRedirectScope {
133133
QualifiedAliasReference
134+
CachedQualifiedAliasReference
134135
UnqualifiedItemBinding
135136
} derive(Eq)
136137

docs/moon_wgsl-issue-tracker.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ Last updated: 2026-05-05
123123
| `WGSL-108` | Architecture risk review | Semantic rewrite still used source-span copy-and-replace in rename/writeback/virtual override paths, so identifier correctness depended on raw source slicing even after AST analysis found the nodes. | `DONE` | Replaced semantic source splices with AST-scoped token rewrites in `analysis` and `virtual_overrides`; writeback sanitizer now inherits the same token emitter through `WgslRenamePlan`. Verified with `moon test --target js`, `moon test --target js README.mbt.md`, `moon check --target all --deny-warn`, `moon info`, `moon ide analyze`, and `tools/check_preprocess_parity.sh` on 2026-05-05. |
124124
| `WGSL-109` | Architecture risk review | Preprocess and compose still have necessary source-preserving text emission for naga_oil parity, but those paths are not documented as an explicit boundary and can be mistaken for semantic rewrite logic. | `DONE` | Centralized preprocessing and compose source-preserving output behind typed emission actions (`WgslPreprocessEmitAction`, `WgslComposeSourceEmitAction`) so raw `original_text`/blanking behavior is isolated from semantic rewrite packages. Verified with `moon test --target js` on 2026-05-05. |
125125
| `WGSL-110` | Architecture risk review | Source maps and catalogs now use final prepared WGSL, which fixed runtime alias leakage, but precise mapping back to original dependency files requires a separate origin graph instead of raw source catalogs. | `DONE` | Added `WgslSourceOriginEntry` and `PreparedWgslSource.source_origins`, recorded declaration origins during AST-driven compose/import extraction, and changed export source maps to use the origin graph while keeping `source_catalog` tied to final prepared WGSL. Verified with `moon test --target js` on 2026-05-05. |
126+
| `WGSL-111` | GitHub issue #8 latest comment | `moon_wgsl 0.7.2` still failed mgstudio's real Bevy PBR fragment path with `failed to resolve shader import: view_bindings::clustered_lights`. The missing case was a cached qualified alias import: one `mesh_view_bindings as view_bindings` import emitted the declarations, while a later module reused only cached redirects, and the live-redirect filter dropped them because the target declarations were not local to that later module. | `DONE` | Added a dedicated `CachedQualifiedAliasReference` scope and kept cached alias redirects when the current AST references the alias path. Added regressions for real `bevy_pbr/src/render/pbr.wgsl` and address-of alias member references. Verified with `moon test --target js`, `moon test --target js README.mbt.md`, `moon check --target all --deny-warn`, and `tools/check_preprocess_parity.sh` on 2026-05-05. |
126127

127128
## Current work queue
128129

semantic/semantic_graph_wbtest.mbt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,24 @@ test "semantic alias graph resolves global binding member access" {
2828
debug_inspect(requested_paths.join(","), content="\"clustered_lights\"")
2929
}
3030

31+
///|
32+
test "semantic reference matcher includes address-of alias member access" {
33+
let source =
34+
#|fn point_light(light_id: u32) -> u32 {
35+
#| let light = &view_bindings::clustered_lights.data[light_id];
36+
#| return (*light).flags;
37+
#|}
38+
#|
39+
debug_inspect(
40+
wgsl_semantic_source_contains_reference_path(
41+
source, "view_bindings::clustered_lights",
42+
) catch {
43+
_ => abort("expected semantic matcher to parse valid WGSL")
44+
},
45+
content="true",
46+
)
47+
}
48+
3149
///|
3250
test "semantic alias graph resolves nested module alias paths" {
3351
let source =

0 commit comments

Comments
 (0)