Repository: gfx-rs/wgpu
Pull request #6328 (2024-09-26 05:06:10)

[naga] Handle phony statements properly by treating them as named expressions
**Connections**
Alternative to https://github.com/gfx-rs/wgpu/pull/6308 that fixes https://github.com/gfx-rs/wgpu/issues/6095

**Description**
Currently phony statements get removed when compacting, we bypass this by making them named expressions with `phony` name.

**Testing**
New tests added and [CTS run in servo](https://github.com/sagudev/servo/actions/runs/11045854357/job/30685772542).

<!-- 
Thanks for filing! The codeowners file will automatically request reviews from the appropriate teams.

After you get a review and have addressed any comments, please explicitly re-request a review from the
person(s) who reviewed your changes. This will make sure it gets re-added to their review queue - you're no bothering us!
-->

**Checklist**

- [x] Run `cargo fmt`.
- [x] Run `cargo clippy`. If applicable, add:
  - [ ] `--target wasm32-unknown-unknown`
  - [ ] `--target wasm32-unknown-emscripten`
- [x] Run `cargo xtask test` to run tests.
- [ ] Add change to `CHANGELOG.md`. See simple instructions inside file.



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 894da6ddc..239b1f7d9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -142,6 +142,7 @@ By @bradwerth [#6216](https://github.com/gfx-rs/wgpu/pull/6216).
 ### Documentation
 
 - Removed some OpenGL and Vulkan references from `wgpu-types` documentation. Fixed Storage texel types in examples. By @Nelarius in [#6271](https://github.com/gfx-rs/wgpu/pull/6271)
+- Used `wgpu::include_wgsl!(…)` more in examples and tests. By @ErichDonGubler in [#6326](https://github.com/gfx-rs/wgpu/pull/6326).
 
 ### Dependency Updates
 
diff --git a/examples/src/boids/mod.rs b/examples/src/boids/mod.rs
index c527be96d..6335bed81 100644
--- a/examples/src/boids/mod.rs
+++ b/examples/src/boids/mod.rs
@@ -2,7 +2,7 @@
 // adapted from https://github.com/austinEng/webgpu-samples/blob/master/src/examples/computeBoids.ts
 
 use nanorand::{Rng, WyRand};
-use std::{borrow::Cow, mem::size_of};
+use std::mem::size_of;
 use wgpu::util::DeviceExt;
 
 // number of boid particles to simulate
@@ -43,14 +43,8 @@ impl crate::framework::Example for Example {
         device: &wgpu::Device,
         _queue: &wgpu::Queue,
     ) -> Self {
-        let compute_shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-            label: None,
-            source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("compute.wgsl"))),
-        });
-        let draw_shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-            label: None,
-            source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("draw.wgsl"))),
-        });
+        let compute_shader = device.create_shader_module(wgpu::include_wgsl!("compute.wgsl"));
+        let draw_shader = device.create_shader_module(wgpu::include_wgsl!("draw.wgsl"));
 
         // buffer for simulation parameters uniform
 
diff --git a/examples/src/conservative_raster/mod.rs b/examples/src/conservative_raster/mod.rs
index 46fb8742a..681c45c83 100644
--- a/examples/src/conservative_raster/mod.rs
+++ b/examples/src/conservative_raster/mod.rs
@@ -1,5 +1,3 @@
-use std::borrow::Cow;
-
 const RENDER_TARGET_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Rgba8UnormSrgb;
 
 struct Example {
@@ -83,12 +81,8 @@ impl crate::framework::Example for Example {
                 push_constant_ranges: &[],
             });
 
-        let shader_triangle_and_lines = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-            label: None,
-            source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!(
-                "triangle_and_lines.wgsl"
-            ))),
-        });
+        let shader_triangle_and_lines =
+            device.create_shader_module(wgpu::include_wgsl!("triangle_and_lines.wgsl"));
 
         let pipeline_triangle_conservative =
             device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
@@ -203,10 +197,7 @@ impl crate::framework::Example for Example {
                 bind_group_layouts: &[&bind_group_layout],
                 push_constant_ranges: &[],
             });
-            let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-                label: None,
-                source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("upscale.wgsl"))),
-            });
+            let shader = device.create_shader_module(wgpu::include_wgsl!("upscale.wgsl"));
             (
                 device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
                     label: Some("Upscale"),
diff --git a/examples/src/cube/mod.rs b/examples/src/cube/mod.rs
index 78dc06e06..bc7504411 100644
--- a/examples/src/cube/mod.rs
+++ b/examples/src/cube/mod.rs
@@ -1,5 +1,5 @@
 use bytemuck::{Pod, Zeroable};
-use std::{borrow::Cow, f32::consts, mem::size_of};
+use std::{f32::consts, mem::size_of};
 use wgpu::util::DeviceExt;
 
 #[repr(C)]
@@ -216,10 +216,7 @@ impl crate::framework::Example for Example {
             label: None,
         });
 
-        let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-            label: None,
-            source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
-        });
+        let shader = device.create_shader_module(wgpu::include_wgsl!("shader.wgsl"));
 
         let vertex_buffers = [wgpu::VertexBufferLayout {
             array_stride: vertex_size as wgpu::BufferAddress,
diff --git a/examples/src/hello_compute/mod.rs b/examples/src/hello_compute/mod.rs
index e53f49fa4..35cfcfbab 100644
--- a/examples/src/hello_compute/mod.rs
+++ b/examples/src/hello_compute/mod.rs
@@ -1,4 +1,4 @@
-use std::{borrow::Cow, mem::size_of_val, str::FromStr};
+use std::{mem::size_of_val, str::FromStr};
 use wgpu::util::DeviceExt;
 
 // Indicates a u32 overflow in an intermediate Collatz value
@@ -66,10 +66,7 @@ async fn execute_gpu_inner(
     numbers: &[u32],
 ) -> Option<Vec<u32>> {
     // Loads the shader from WGSL
-    let cs_module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-        label: None,
-        source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
-    });
+    let cs_module = device.create_shader_module(wgpu::include_wgsl!("shader.wgsl"));
 
     // Gets the size in bytes of the buffer.
     let size = size_of_val(numbers) as wgpu::BufferAddress;
diff --git a/examples/src/hello_synchronization/mod.rs b/examples/src/hello_synchronization/mod.rs
index fad5d7a9d..b186c2bf0 100644
--- a/examples/src/hello_synchronization/mod.rs
+++ b/examples/src/hello_synchronization/mod.rs
@@ -56,10 +56,7 @@ async fn execute(
     let mut local_patient_workgroup_results = vec![0u32; result_vec_size];
     let mut local_hasty_workgroup_results = local_patient_workgroup_results.clone();
 
-    let shaders_module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-        label: None,
-        source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed(include_str!("shaders.wgsl"))),
-    });
+    let shaders_module = device.create_shader_module(wgpu::include_wgsl!("shaders.wgsl"));
 
     let storage_buffer = device.create_buffer(&wgpu::BufferDescriptor {
         label: None,
diff --git a/examples/src/hello_workgroups/mod.rs b/examples/src/hello_workgroups/mod.rs
index 7a653cf3e..38c88a692 100644
--- a/examples/src/hello_workgroups/mod.rs
+++ b/examples/src/hello_workgroups/mod.rs
@@ -41,10 +41,7 @@ async fn run() {
         .await
         .unwrap();
 
-    let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-        label: None,
-        source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed(include_str!("shader.wgsl"))),
-    });
+    let shader = device.create_shader_module(wgpu::include_wgsl!("shader.wgsl"));
 
     let storage_buffer_a = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
         label: None,
diff --git a/examples/src/mipmap/mod.rs b/examples/src/mipmap/mod.rs
index 179970ad7..edfcf2223 100644
--- a/examples/src/mipmap/mod.rs
+++ b/examples/src/mipmap/mod.rs
@@ -1,5 +1,5 @@
 use bytemuck::{Pod, Zeroable};
-use std::{borrow::Cow, f32::consts, mem::size_of};
+use std::{f32::consts, mem::size_of};
 use wgpu::util::DeviceExt;
 
 const TEXTURE_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Rgba8UnormSrgb;
@@ -81,10 +81,7 @@ impl Example {
         query_sets: &Option<QuerySets>,
         mip_count: u32,
     ) {
-        let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-            label: None,
-            source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("blit.wgsl"))),
-        });
+        let shader = device.create_shader_module(wgpu::include_wgsl!("blit.wgsl"));
 
         let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
             label: Some("blit"),
@@ -281,10 +278,7 @@ impl crate::framework::Example for Example {
         });
 
         // Create the render pipeline
-        let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-            label: None,
-            source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("draw.wgsl"))),
-        });
+        let shader = device.create_shader_module(wgpu::include_wgsl!("draw.wgsl"));
 
         let draw_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
             label: Some("draw"),
diff --git a/examples/src/msaa_line/mod.rs b/examples/src/msaa_line/mod.rs
index 431fe02ba..1f49b90f4 100644
--- a/examples/src/msaa_line/mod.rs
+++ b/examples/src/msaa_line/mod.rs
@@ -7,7 +7,7 @@
 //! *   Set the primitive_topology to PrimitiveTopology::LineList.
 //! *   Vertices and Indices describe the two points that make up a line.
 
-use std::{borrow::Cow, iter, mem::size_of};
+use std::{iter, mem::size_of};
 
 use bytemuck::{Pod, Zeroable};
 use wgpu::util::DeviceExt;
@@ -156,10 +156,7 @@ impl crate::framework::Example for Example {
 
         let sample_count = max_sample_count;
 
-        let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-            label: None,
-            source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
-        });
+        let shader = device.create_shader_module(wgpu::include_wgsl!("shader.wgsl"));
 
         let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
             label: None,
diff --git a/examples/src/render_to_texture/mod.rs b/examples/src/render_to_texture/mod.rs
index 1d6f488d5..529525498 100644
--- a/examples/src/render_to_texture/mod.rs
+++ b/examples/src/render_to_texture/mod.rs
@@ -28,10 +28,7 @@ async fn run(_path: Option<String>) {
         .await
         .unwrap();
 
-    let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-        label: None,
-        source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed(include_str!("shader.wgsl"))),
-    });
+    let shader = device.create_shader_module(wgpu::include_wgsl!("shader.wgsl"));
 
     let render_target = device.create_texture(&wgpu::TextureDescriptor {
         label: None,
diff --git a/examples/src/repeated_compute/mod.rs b/examples/src/repeated_compute/mod.rs
index 83dcd4099..7c9ff766d 100644
--- a/examples/src/repeated_compute/mod.rs
+++ b/examples/src/repeated_compute/mod.rs
@@ -180,12 +180,7 @@ impl WgpuContext {
             .unwrap();
 
         // Our shader, kindly compiled with Naga.
-        let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-            label: None,
-            source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed(include_str!(
-                "shader.wgsl"
-            ))),
-        });
+        let shader = device.create_shader_module(wgpu::include_wgsl!("shader.wgsl"));
 
         // This is where the GPU will read from and write to.
         let storage_buffer = device.create_buffer(&wgpu::BufferDescriptor {
diff --git a/examples/src/shadow/mod.rs b/examples/src/shadow/mod.rs
index a7edcce7e..0960a49f2 100644
--- a/examples/src/shadow/mod.rs
+++ b/examples/src/shadow/mod.rs
@@ -1,4 +1,4 @@
-use std::{borrow::Cow, f32::consts, iter, mem::size_of, ops::Range, sync::Arc};
+use std::{f32::consts, iter, mem::size_of, ops::Range, sync::Arc};
 
 use bytemuck::{Pod, Zeroable};
 use wgpu::util::{align_to, DeviceExt};
@@ -447,10 +447,7 @@ impl crate::framework::Example for Example {
             attributes: &vertex_attr,
         };
 
-        let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-            label: None,
-            source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
-        });
+        let shader = device.create_shader_module(wgpu::include_wgsl!("shader.wgsl"));
 
         let shadow_pass = {
             let uniform_size = size_of::<GlobalUniforms>() as wgpu::BufferAddress;
diff --git a/examples/src/skybox/mod.rs b/examples/src/skybox/mod.rs
index 82e58ef6d..ae3164379 100644
--- a/examples/src/skybox/mod.rs
+++ b/examples/src/skybox/mod.rs
@@ -1,5 +1,5 @@
 use bytemuck::{Pod, Zeroable};
-use std::{borrow::Cow, f32::consts, mem::size_of};
+use std::{f32::consts, mem::size_of};
 use wgpu::{util::DeviceExt, AstcBlock, AstcChannel};
 
 const IMAGE_SIZE: u32 = 256;
@@ -168,10 +168,7 @@ impl crate::framework::Example for Example {
         });
 
         // Create the render pipeline
-        let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-            label: None,
-            source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
-        });
+        let shader = device.create_shader_module(wgpu::include_wgsl!("shader.wgsl"));
 
         let camera = Camera {
             screen_size: (config.width, config.height),
diff --git a/examples/src/srgb_blend/mod.rs b/examples/src/srgb_blend/mod.rs
index 822d95d3c..198483d54 100644
--- a/examples/src/srgb_blend/mod.rs
+++ b/examples/src/srgb_blend/mod.rs
@@ -1,5 +1,5 @@
 use bytemuck::{Pod, Zeroable};
-use std::{borrow::Cow, mem};
+use std::mem;
 use wgpu::util::DeviceExt;
 
 #[repr(C)]
@@ -103,10 +103,7 @@ impl<const SRGB: bool> crate::framework::Example for Example<SRGB> {
             label: None,
         });
 
-        let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-            label: None,
-            source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
-        });
+        let shader = device.create_shader_module(wgpu::include_wgsl!("shader.wgsl"));
 
         let vertex_buffers = [wgpu::VertexBufferLayout {
             array_stride: vertex_size as wgpu::BufferAddress,
diff --git a/examples/src/stencil_triangles/mod.rs b/examples/src/stencil_triangles/mod.rs
index bb433af11..fcd37f813 100644
--- a/examples/src/stencil_triangles/mod.rs
+++ b/examples/src/stencil_triangles/mod.rs
@@ -1,5 +1,4 @@
 use bytemuck::{Pod, Zeroable};
-use std::borrow::Cow;
 use std::mem::size_of;
 use wgpu::util::DeviceExt;
 
@@ -53,10 +52,7 @@ impl crate::framework::Example for Example {
             push_constant_ranges: &[],
         });
 
-        let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-            label: None,
-            source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
-        });
+        let shader = device.create_shader_module(wgpu::include_wgsl!("shader.wgsl"));
 
         let vertex_buffers = [wgpu::VertexBufferLayout {
             array_stride: vertex_size as wgpu::BufferAddress,
diff --git a/examples/src/storage_texture/mod.rs b/examples/src/storage_texture/mod.rs
index a68758419..a394fe9e0 100644
--- a/examples/src/storage_texture/mod.rs
+++ b/examples/src/storage_texture/mod.rs
@@ -44,10 +44,7 @@ async fn run(_path: Option<String>) {
         .await
         .unwrap();
 
-    let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-        label: None,
-        source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed(include_str!("shader.wgsl"))),
-    });
+    let shader = device.create_shader_module(wgpu::include_wgsl!("shader.wgsl"));
 
     let storage_texture = device.create_texture(&wgpu::TextureDescriptor {
         label: None,
diff --git a/examples/src/timestamp_queries/mod.rs b/examples/src/timestamp_queries/mod.rs
index a253938a3..eb78630e2 100644
--- a/examples/src/timestamp_queries/mod.rs
+++ b/examples/src/timestamp_queries/mod.rs
@@ -239,10 +239,7 @@ fn submit_render_and_compute_pass_with_queries(
         device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
 
     let mut queries = Queries::new(device, QueryResults::NUM_QUERIES);
-    let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-        label: None,
-        source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed(include_str!("shader.wgsl"))),
-    });
+    let shader = device.create_shader_module(wgpu::include_wgsl!("shader.wgsl"));
 
     if device
         .features()
diff --git a/examples/src/uniform_values/mod.rs b/examples/src/uniform_values/mod.rs
index 1ef58de09..a5c1e14c5 100644
--- a/examples/src/uniform_values/mod.rs
+++ b/examples/src/uniform_values/mod.rs
@@ -122,12 +122,7 @@ impl WgpuContext {
             .await
             .unwrap();
 
-        let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-            label: None,
-            source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed(include_str!(
-                "shader.wgsl"
-            ))),
-        });
+        let shader = device.create_shader_module(wgpu::include_wgsl!("shader.wgsl"));
 
         // (2)
         let uniform_buffer = device.create_buffer(&wgpu::BufferDescriptor {
diff --git a/examples/src/water/mod.rs b/examples/src/water/mod.rs
index 505f5707e..52acbef37 100644
--- a/examples/src/water/mod.rs
+++ b/examples/src/water/mod.rs
@@ -3,7 +3,7 @@ mod point_gen;
 use bytemuck::{Pod, Zeroable};
 use glam::Vec3;
 use nanorand::{Rng, WyRand};
-use std::{borrow::Cow, f32::consts, iter, mem::size_of};
+use std::{f32::consts, iter, mem::size_of};
 use wgpu::util::DeviceExt;
 
 ///
@@ -493,14 +493,8 @@ impl crate::framework::Example for Example {
         });
 
         // Upload/compile them to GPU code.
-        let terrain_module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-            label: Some("terrain"),
-            source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("terrain.wgsl"))),
-        });
-        let water_module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-            label: Some("water"),
-            source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("water.wgsl"))),
-        });
+        let terrain_module = device.create_shader_module(wgpu::include_wgsl!("terrain.wgsl"));
+        let water_module = device.create_shader_module(wgpu::include_wgsl!("water.wgsl"));
 
         // Create the render pipelines. These describe how the data will flow through the GPU, and what
         // constraints and modifiers it will have.
diff --git a/naga/src/front/wgsl/lower/mod.rs b/naga/src/front/wgsl/lower/mod.rs
index 7586f98dc..78e81350b 100644
--- a/naga/src/front/wgsl/lower/mod.rs
+++ b/naga/src/front/wgsl/lower/mod.rs
@@ -1778,12 +1778,14 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
 
                 return Ok(());
             }
-            ast::StatementKind::Ignore(expr) => {
+            ast::StatementKind::Phony(expr) => {
                 let mut emitter = Emitter::default();
                 emitter.start(&ctx.function.expressions);
 
-                let _ = self.expression(expr, &mut ctx.as_expression(block, &mut emitter))?;
+                let value = self.expression(expr, &mut ctx.as_expression(block, &mut emitter))?;
                 block.extend(emitter.finish(&ctx.function.expressions));
+                ctx.named_expressions
+                    .insert(value, ("phony".to_string(), stmt.span));
                 return Ok(());
             }
         };
diff --git a/naga/src/front/wgsl/parse/ast.rs b/naga/src/front/wgsl/parse/ast.rs
index c4a798411..4307ca3d9 100644
--- a/naga/src/front/wgsl/parse/ast.rs
+++ b/naga/src/front/wgsl/parse/ast.rs
@@ -284,7 +284,7 @@ pub enum StatementKind<'a> {
     },
     Increment(Handle<Expression<'a>>),
     Decrement(Handle<Expression<'a>>),
-    Ignore(Handle<Expression<'a>>),
+    Phony(Handle<Expression<'a>>),
     ConstAssert(Handle<Expression<'a>>),
 }
 
diff --git a/naga/src/front/wgsl/parse/mod.rs b/naga/src/front/wgsl/parse/mod.rs
index 0157aa3a7..3b1d60620 100644
--- a/naga/src/front/wgsl/parse/mod.rs
+++ b/naga/src/front/wgsl/parse/mod.rs
@@ -1696,7 +1696,7 @@ impl Parser {
                         let expr = self.general_expression(lexer, ctx)?;
                         lexer.expect(Token::Separator(';'))?;
 
-                        ast::StatementKind::Ignore(expr)
+                        ast::StatementKind::Phony(expr)
                     }
                     "let" => {
                         let _ = lexer.next();


Test patch:
diff --git a/naga/tests/in/phony_assignment.ron b/naga/tests/in/phony_assignment.ron
new file mode 100644
index 000000000..39679b87b
--- /dev/null
+++ b/naga/tests/in/phony_assignment.ron
@@ -0,0 +1,2 @@
+(
+)
\ No newline at end of file
diff --git a/naga/tests/in/phony_assignment.wgsl b/naga/tests/in/phony_assignment.wgsl
new file mode 100644
index 000000000..716a387b0
--- /dev/null
+++ b/naga/tests/in/phony_assignment.wgsl
@@ -0,0 +1,18 @@
+@group(0) @binding(0) var<uniform> binding: f32;
+
+fn five() -> i32 {
+  return 5;
+}
+
+@compute @workgroup_size(1) fn main(
+  @builtin(global_invocation_id) id: vec3<u32>
+) {
+    _ = binding;
+    _ = binding;
+    let a = 5;
+    _ = a;
+    _ = five();
+    let b = five();
+    // check for name collision
+    let phony = binding;
+}
\ No newline at end of file
diff --git a/naga/tests/out/glsl/phony_assignment.main.Compute.glsl b/naga/tests/out/glsl/phony_assignment.main.Compute.glsl
new file mode 100644
index 000000000..6118e9b4a
--- /dev/null
+++ b/naga/tests/out/glsl/phony_assignment.main.Compute.glsl
@@ -0,0 +1,23 @@
+#version 310 es
+
+precision highp float;
+precision highp int;
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+
+uniform type_block_0Compute { float _group_0_binding_0_cs; };
+
+
+int five() {
+    return 5;
+}
+
+void main() {
+    uvec3 id = gl_GlobalInvocationID;
+    float phony = _group_0_binding_0_cs;
+    float phony_1 = _group_0_binding_0_cs;
+    int _e6 = five();
+    int _e7 = five();
+    float phony_2 = _group_0_binding_0_cs;
+}
+
diff --git a/naga/tests/out/hlsl/phony_assignment.hlsl b/naga/tests/out/hlsl/phony_assignment.hlsl
new file mode 100644
index 000000000..f448290e0
--- /dev/null
+++ b/naga/tests/out/hlsl/phony_assignment.hlsl
@@ -0,0 +1,16 @@
+cbuffer binding : register(b0) { float binding; }
+
+int five()
+{
+    return 5;
+}
+
+[numthreads(1, 1, 1)]
+void main(uint3 id : SV_DispatchThreadID)
+{
+    float phony = binding;
+    float phony_1 = binding;
+    const int _e6 = five();
+    const int _e7 = five();
+    float phony_2 = binding;
+}
diff --git a/naga/tests/out/hlsl/phony_assignment.ron b/naga/tests/out/hlsl/phony_assignment.ron
new file mode 100644
index 000000000..a07b03300
--- /dev/null
+++ b/naga/tests/out/hlsl/phony_assignment.ron
@@ -0,0 +1,12 @@
+(
+    vertex:[
+    ],
+    fragment:[
+    ],
+    compute:[
+        (
+            entry_point:"main",
+            target_profile:"cs_5_1",
+        ),
+    ],
+)
diff --git a/naga/tests/out/msl/phony_assignment.msl b/naga/tests/out/msl/phony_assignment.msl
new file mode 100644
index 000000000..daad57190
--- /dev/null
+++ b/naga/tests/out/msl/phony_assignment.msl
@@ -0,0 +1,24 @@
+// language: metal1.0
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using metal::uint;
+
+
+int five(
+) {
+    return 5;
+}
+
+struct main_Input {
+};
+kernel void main_(
+  metal::uint3 id [[thread_position_in_grid]]
+, constant float& binding [[user(fake0)]]
+) {
+    float phony = binding;
+    float phony_1 = binding;
+    int _e6 = five();
+    int _e7 = five();
+    float phony_2 = binding;
+}
diff --git a/naga/tests/out/spv/phony_assignment.spvasm b/naga/tests/out/spv/phony_assignment.spvasm
new file mode 100644
index 000000000..842618390
--- /dev/null
+++ b/naga/tests/out/spv/phony_assignment.spvasm
@@ -0,0 +1,48 @@
+; SPIR-V
+; Version: 1.1
+; Generator: rspirv
+; Bound: 30
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %19 "main" %16
+OpExecutionMode %19 LocalSize 1 1 1
+OpDecorate %7 DescriptorSet 0
+OpDecorate %7 Binding 0
+OpDecorate %8 Block
+OpMemberDecorate %8 0 Offset 0
+OpDecorate %16 BuiltIn GlobalInvocationId
+%2 = OpTypeVoid
+%3 = OpTypeFloat 32
+%4 = OpTypeInt 32 1
+%6 = OpTypeInt 32 0
+%5 = OpTypeVector %6 3
+%8 = OpTypeStruct %3
+%9 = OpTypePointer Uniform %8
+%7 = OpVariable  %9  Uniform
+%12 = OpTypeFunction %4
+%13 = OpConstant  %4  5
+%17 = OpTypePointer Input %5
+%16 = OpVariable  %17  Input
+%20 = OpTypeFunction %2
+%21 = OpTypePointer Uniform %3
+%22 = OpConstant  %6  0
+%11 = OpFunction  %4  None %12
+%10 = OpLabel
+OpBranch %14
+%14 = OpLabel
+OpReturnValue %13
+OpFunctionEnd
+%19 = OpFunction  %2  None %20
+%15 = OpLabel
+%18 = OpLoad  %5  %16
+%23 = OpAccessChain  %21  %7 %22
+OpBranch %24
+%24 = OpLabel
+%25 = OpLoad  %3  %23
+%26 = OpLoad  %3  %23
+%27 = OpFunctionCall  %4  %11
+%28 = OpFunctionCall  %4  %11
+%29 = OpLoad  %3  %23
+OpReturn
+OpFunctionEnd
\ No newline at end of file
diff --git a/naga/tests/out/wgsl/phony_assignment.wgsl b/naga/tests/out/wgsl/phony_assignment.wgsl
new file mode 100644
index 000000000..60987a15c
--- /dev/null
+++ b/naga/tests/out/wgsl/phony_assignment.wgsl
@@ -0,0 +1,15 @@
+@group(0) @binding(0) 
+var<uniform> binding: f32;
+
+fn five() -> i32 {
+    return 5i;
+}
+
+@compute @workgroup_size(1, 1, 1) 
+fn main(@builtin(global_invocation_id) id: vec3<u32>) {
+    let phony = binding;
+    let phony_1 = binding;
+    let _e6 = five();
+    let _e7 = five();
+    let phony_2 = binding;
+}
diff --git a/naga/tests/snapshots.rs b/naga/tests/snapshots.rs
index 936203986..596e4cea1 100644
--- a/naga/tests/snapshots.rs
+++ b/naga/tests/snapshots.rs
@@ -928,6 +928,10 @@ fn convert_wgsl() {
             "cross",
             Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
         ),
+        (
+            "phony_assignment",
+            Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
+        ),
     ];
 
     for &(name, targets) in inputs.iter() {
diff --git a/tests/tests/occlusion_query/mod.rs b/tests/tests/occlusion_query/mod.rs
index 20c7fff82..2cedab029 100644
--- a/tests/tests/occlusion_query/mod.rs
+++ b/tests/tests/occlusion_query/mod.rs
@@ -1,4 +1,4 @@
-use std::{borrow::Cow, mem::size_of};
+use std::mem::size_of;
 use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, TestParameters};
 
 #[gpu_test]
@@ -25,10 +25,7 @@ static OCCLUSION_QUERY: GpuTestConfiguration = GpuTestConfiguration::new()
         // Setup pipeline using a simple shader with hardcoded vertices
         let shader = ctx
             .device
-            .create_shader_module(wgpu::ShaderModuleDescriptor {
-                label: Some("Shader module"),
-                source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
-            });
+            .create_shader_module(wgpu::include_wgsl!("shader.wgsl"));
         let pipeline = ctx
             .device
             .create_render_pipeline(&wgpu::RenderPipelineDescriptor {
diff --git a/tests/tests/partially_bounded_arrays/mod.rs b/tests/tests/partially_bounded_arrays/mod.rs
index 4e6d6fc09..eefec6c3f 100644
--- a/tests/tests/partially_bounded_arrays/mod.rs
+++ b/tests/tests/partially_bounded_arrays/mod.rs
@@ -1,4 +1,4 @@
-use std::{borrow::Cow, num::NonZeroU32};
+use std::num::NonZeroU32;
 
 use wgpu_test::{gpu_test, image::ReadbackBuffers, GpuTestConfiguration, TestParameters};
 
@@ -53,10 +53,7 @@ static PARTIALLY_BOUNDED_ARRAY: GpuTestConfiguration = GpuTestConfiguration::new
             }],
         });
 
-        let cs_module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-            label: None,
-            source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
-        });
+        let cs_module = device.create_shader_module(wgpu::include_wgsl!("shader.wgsl"));
 
         let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
             label: Some("main"),
diff --git a/tests/tests/subgroup_operations/mod.rs b/tests/tests/subgroup_operations/mod.rs
index f874a6bac..973d82422 100644
--- a/tests/tests/subgroup_operations/mod.rs
+++ b/tests/tests/subgroup_operations/mod.rs
@@ -1,4 +1,4 @@
-use std::{borrow::Cow, mem::size_of, num::NonZeroU64};
+use std::{mem::size_of, num::NonZeroU64};
 
 use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters};
 
@@ -56,10 +56,7 @@ static SUBGROUP_OPERATIONS: GpuTestConfiguration = GpuTestConfiguration::new()
             }],
         });
 
-        let cs_module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-            label: None,
-            source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
-        });
+        let cs_module = device.create_shader_module(wgpu::include_wgsl!("shader.wgsl"));
 
         let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
             label: Some("main"),