Repository: gfx-rs/wgpu (language: rust)

Issue:
WGSL constant values should not be concretized
I think this ought to pass validation, but it fails:

```wgsl
const one = 1;
const_assert one == 1.0;
```

When I run this on 50b71287c, I get:

```
Could not parse WGSL:
error: const_assert failure
  ┌─ const.wgsl:2:14
  │
2 │ const_assert one == 1.0;
  │              ^^^^^^^^^^ evaluates to false
```

This seems to cause WebGPU CTS failures:

```
webgpu:shader,validation,const_assert,const_assert:constant_expression_assert:*
```


Discussion / hints:
cc @sagudev 
`const_assert` works for:
```wgsl
const one = 1.0;
const_assert one == 1.0;
```
and for:
```wgsl
const_assert 1 == 1.0;
```
Now if we have:
```wgsl
fn f() -> i32 {
    const one = 1;
    if (one == 1.0) {
        return 42;
    } else {
        return 35;
    }
}
```
it compiles to:
```wgsl
fn f() -> i32 {
    if false {
        return 42i;
    } else {
        return 35i;
    }
}
```
so I think something is wrong with evaler (specifically how it handles abstract types - I think it's #4400).
The problem is that abstractint is to eagerly converted to i32, then in [`binary_op`](https://github.com/gfx-rs/wgpu/blob/9b36a3e129da04b018257564d5129caff240cb75/naga/src/proc/constant_evaluator.rs#L1796) we return result of `I32(1) == AbstractFloat(1.0)`
WGSL says constants can have abstract types. I don't think Naga implements that.
> WGSL says constants can have abstract types. I don't think Naga implements that.

Indeed, we try to concertize value:

https://github.com/gfx-rs/wgpu/blob/9b36a3e129da04b018257564d5129caff240cb75/naga/src/front/wgsl/lower/mod.rs#L1118

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2779fab13a..160f99a356 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -182,6 +182,7 @@ By @brodycj in [#6924](https://github.com/gfx-rs/wgpu/pull/6924).
 - Error if structs have two fields with the same name. By @SparkyPotato in [#7088](https://github.com/gfx-rs/wgpu/pull/7088).
 - Forward '--keep-coordinate-space' flag to GLSL backend in naga-cli. By @cloone8 in [#7206](https://github.com/gfx-rs/wgpu/pull/7206).
 - Allow template lists to have a trailing comma. By @KentSlaney in [#7142](https://github.com/gfx-rs/wgpu/pull/7142).
+- Allow WGSL const declarations to have abstract types. By @jamienicol in [#7055](https://github.com/gfx-rs/wgpu/pull/7055).
 
 #### General
 
diff --git a/naga/src/compact/mod.rs b/naga/src/compact/mod.rs
index c9a7c93977..f889a8e1b9 100644
--- a/naga/src/compact/mod.rs
+++ b/naga/src/compact/mod.rs
@@ -110,15 +110,18 @@ pub fn compact(module: &mut crate::Module) {
     log::trace!("tracing special types");
     module_tracer.trace_special_types(&module.special_types);
 
-    // We treat all named constants as used by definition.
+    // We treat all named constants as used by definition, unless they have an
+    // abstract type as we do not want those reaching the validator.
     log::trace!("tracing named constants");
     for (handle, constant) in module.constants.iter() {
-        if constant.name.is_some() {
-            log::trace!("tracing constant {:?}", constant.name.as_ref().unwrap());
-            module_tracer.constants_used.insert(handle);
-            module_tracer.types_used.insert(constant.ty);
-            module_tracer.global_expressions_used.insert(constant.init);
+        if constant.name.is_none() || module.types[constant.ty].inner.is_abstract(&module.types) {
+            continue;
         }
+
+        log::trace!("tracing constant {:?}", constant.name.as_ref().unwrap());
+        module_tracer.constants_used.insert(handle);
+        module_tracer.types_used.insert(constant.ty);
+        module_tracer.global_expressions_used.insert(constant.init);
     }
 
     // We treat all named overrides as used by definition.
diff --git a/naga/src/front/wgsl/lower/conversion.rs b/naga/src/front/wgsl/lower/conversion.rs
index f7e767bfb8..f78bb3da27 100644
--- a/naga/src/front/wgsl/lower/conversion.rs
+++ b/naga/src/front/wgsl/lower/conversion.rs
@@ -37,14 +37,7 @@ impl<'source> super::ExpressionContext<'source, '_, '_> {
         // rather than them being misreported as type conversion errors.
         // If the type is an array (of an array, etc) then we must check whether the
         // type of the innermost array's base type is abstract.
-        let mut base_inner = expr_inner;
-        while let crate::TypeInner::Array { base, .. } = *base_inner {
-            base_inner = &types[base].inner;
-        }
-        if !base_inner
-            .scalar()
-            .is_some_and(|scalar| scalar.is_abstract())
-        {
+        if !expr_inner.is_abstract(types) {
             return Ok(expr);
         }
 
diff --git a/naga/src/front/wgsl/lower/mod.rs b/naga/src/front/wgsl/lower/mod.rs
index 70900e0db3..0120707a16 100644
--- a/naga/src/front/wgsl/lower/mod.rs
+++ b/naga/src/front/wgsl/lower/mod.rs
@@ -1029,6 +1029,15 @@ impl SubgroupGather {
     }
 }
 
+/// Whether a declaration accepts abstract types, or concretizes.
+enum AbstractRule {
+    /// This declaration concretizes its initialization expression.
+    Concretize,
+
+    /// This declaration can accept initializers with abstract types.
+    Allow,
+}
+
 pub struct Lowerer<'source, 'temp> {
     index: &'temp Index<'source>,
 }
@@ -1072,8 +1081,13 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
                         v.ty.map(|ast| self.resolve_ast_type(ast, &mut ctx.as_const()))
                             .transpose()?;
 
-                    let (ty, initializer) =
-                        self.type_and_init(v.name, v.init, explicit_ty, &mut ctx.as_override())?;
+                    let (ty, initializer) = self.type_and_init(
+                        v.name,
+                        v.init,
+                        explicit_ty,
+                        AbstractRule::Concretize,
+                        &mut ctx.as_override(),
+                    )?;
 
                     let binding = if let Some(ref binding) = v.binding {
                         Some(crate::ResourceBinding {
@@ -1105,8 +1119,13 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
                         c.ty.map(|ast| self.resolve_ast_type(ast, &mut ectx))
                             .transpose()?;
 
-                    let (ty, init) =
-                        self.type_and_init(c.name, Some(c.init), explicit_ty, &mut ectx)?;
+                    let (ty, init) = self.type_and_init(
+                        c.name,
+                        Some(c.init),
+                        explicit_ty,
+                        AbstractRule::Allow,
+                        &mut ectx,
+                    )?;
                     let init = init.expect("Global const must have init");
 
                     let handle = ctx.module.constants.append(
@@ -1128,7 +1147,13 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
 
                     let mut ectx = ctx.as_override();
 
-                    let (ty, init) = self.type_and_init(o.name, o.init, explicit_ty, &mut ectx)?;
+                    let (ty, init) = self.type_and_init(
+                        o.name,
+                        o.init,
+                        explicit_ty,
+                        AbstractRule::Concretize,
+                        &mut ectx,
+                    )?;
 
                     let id =
                         o.id.map(|id| self.const_u32(id, &mut ctx.as_const()))
@@ -1201,6 +1226,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
         name: ast::Ident<'source>,
         init: Option<Handle<ast::Expression<'source>>>,
         explicit_ty: Option<Handle<crate::Type>>,
+        abstract_rule: AbstractRule,
         ectx: &mut ExpressionContext<'source, '_, '_>,
     ) -> Result<(Handle<crate::Type>, Option<Handle<crate::Expression>>), Error<'source>> {
         let ty;
@@ -1234,9 +1260,12 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
                 initializer = Some(init);
             }
             (Some(init), None) => {
-                let concretized = self.expression(init, ectx)?;
-                ty = ectx.register_type(concretized)?;
-                initializer = Some(concretized);
+                let mut init = self.expression_for_abstract(init, ectx)?;
+                if let AbstractRule::Concretize = abstract_rule {
+                    init = ectx.concretize(init)?;
+                }
+                ty = ectx.register_type(init)?;
+                initializer = Some(init);
             }
             (None, Some(explicit_ty)) => {
                 ty = explicit_ty;
@@ -1480,8 +1509,13 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
                         .transpose()?;
 
                     let mut ectx = ctx.as_expression(block, &mut emitter);
-                    let (ty, initializer) =
-                        self.type_and_init(v.name, v.init, explicit_ty, &mut ectx)?;
+                    let (ty, initializer) = self.type_and_init(
+                        v.name,
+                        v.init,
+                        explicit_ty,
+                        AbstractRule::Concretize,
+                        &mut ectx,
+                    )?;
 
                     let (const_initializer, initializer) = {
                         match initializer {
@@ -1544,6 +1578,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
                         c.name,
                         Some(c.init),
                         explicit_ty,
+                        AbstractRule::Concretize,
                         &mut ectx.as_const(),
                     )?;
                     let init = init.expect("Local const must have init");
diff --git a/naga/src/proc/constant_evaluator.rs b/naga/src/proc/constant_evaluator.rs
index be7c503a01..684b52c565 100644
--- a/naga/src/proc/constant_evaluator.rs
+++ b/naga/src/proc/constant_evaluator.rs
@@ -1717,6 +1717,8 @@ impl<'a> ConstantEvaluator<'a> {
         target: crate::Scalar,
         span: Span,
     ) -> Result<Handle<Expression>, ConstantEvaluatorError> {
+        let expr = self.check_and_get(expr)?;
+
         let Expression::Compose { ty, ref components } = self.expressions[expr] else {
             return self.cast(expr, target, span);
         };
diff --git a/naga/src/proc/type_methods.rs b/naga/src/proc/type_methods.rs
index 351f4c5368..d73b6df10f 100644
--- a/naga/src/proc/type_methods.rs
+++ b/naga/src/proc/type_methods.rs
@@ -281,4 +281,26 @@ impl crate::TypeInner {
             | crate::TypeInner::BindingArray { .. } => None,
         }
     }
+
+    /// Return true if `self` is an abstract type.
+    ///
+    /// Use `types` to look up type handles. This is necessary to
+    /// recognize abstract arrays.
+    pub fn is_abstract(&self, types: &crate::UniqueArena<crate::Type>) -> bool {
+        match *self {
+            crate::TypeInner::Scalar(scalar)
+            | crate::TypeInner::Vector { scalar, .. }
+            | crate::TypeInner::Matrix { scalar, .. }
+            | crate::TypeInner::Atomic(scalar) => scalar.is_abstract(),
+            crate::TypeInner::Array { base, .. } => types[base].inner.is_abstract(types),
+            crate::TypeInner::ValuePointer { .. }
+            | crate::TypeInner::Pointer { .. }
+            | crate::TypeInner::Struct { .. }
+            | crate::TypeInner::Image { .. }
+            | crate::TypeInner::Sampler { .. }
+            | crate::TypeInner::AccelerationStructure
+            | crate::TypeInner::RayQuery
+            | crate::TypeInner::BindingArray { .. } => false,
+        }
+    }
 }


Test patch:
diff --git a/naga/tests/in/wgsl/abstract-types-function-calls.wgsl b/naga/tests/in/wgsl/abstract-types-function-calls.wgsl
index 9c3c28ef06..599a073f89 100644
--- a/naga/tests/in/wgsl/abstract-types-function-calls.wgsl
+++ b/naga/tests/in/wgsl/abstract-types-function-calls.wgsl
@@ -14,25 +14,53 @@ fn func_au(a: array<u32, 2>) {}
 
 fn func_f_i(a: f32, b: i32) {}
 
+const const_af = 0;
+const const_ai = 0;
+const const_vec_af = vec2(0.0);
+const const_vec_ai = vec2(0);
+const const_mat_af = mat2x2(vec2(0.0), vec2(0.0));
+const const_arr_af = array(0.0, 0.0);
+const const_arr_ai = array(0, 0);
+
 fn main() {
     func_f(0.0);
     func_f(0);
     func_i(0);
     func_u(0);
 
+    func_f(const_af);
+    func_f(const_ai);
+    func_i(const_ai);
+    func_u(const_ai);
+
     func_vf(vec2(0.0));
     func_vf(vec2(0));
     func_vi(vec2(0));
     func_vu(vec2(0));
 
+    func_vf(const_vec_af);
+    func_vf(const_vec_ai);
+    func_vi(const_vec_ai);
+    func_vu(const_vec_ai);
+
     func_mf(mat2x2(vec2(0.0), vec2(0.0)));
     func_mf(mat2x2(vec2(0), vec2(0)));
 
+    func_mf(const_mat_af);
+
     func_af(array(0.0, 0.0));
     func_af(array(0, 0));
     func_ai(array(0, 0));
     func_au(array(0, 0));
 
+    func_af(const_arr_af);
+    func_af(const_arr_ai);
+    func_ai(const_arr_ai);
+    func_au(const_arr_ai);
+
     func_f_i(0.0, 0);
     func_f_i(0, 0);
+
+    func_f_i(const_af, const_ai);
+    func_f_i(const_ai, const_ai);
 }
diff --git a/naga/tests/in/wgsl/abstract-types-return.wgsl b/naga/tests/in/wgsl/abstract-types-return.wgsl
index da77c129a0..d1c879f8a7 100644
--- a/naga/tests/in/wgsl/abstract-types-return.wgsl
+++ b/naga/tests/in/wgsl/abstract-types-return.wgsl
@@ -24,3 +24,8 @@ fn return_vec2f32_ai() -> vec2<f32> {
 fn return_arrf32_ai() -> array<f32, 4> {
     return array(1, 1, 1, 1);
 }
+
+const one = 1;
+fn return_const_f32_const_ai() -> f32 {
+    return one;
+}
diff --git a/naga/tests/in/wgsl/const_assert.wgsl b/naga/tests/in/wgsl/const_assert.wgsl
index 23f57fbb1a..667676900f 100644
--- a/naga/tests/in/wgsl/const_assert.wgsl
+++ b/naga/tests/in/wgsl/const_assert.wgsl
@@ -4,8 +4,13 @@ const y = 2;
 const_assert x < y; // valid at module-scope.
 const_assert(y != 0); // parentheses are optional.
 
+// Ensure abstract-typed consts can be compared to different concrete types
+const_assert x == 1i;
+const_assert x > 0u;
+const_assert x < 2.0f;
+
 fn foo() {
   const z = x + y - 2;
   const_assert z > 0; // valid in functions.
   const_assert(z > 0);
-}
\ No newline at end of file
+}
diff --git a/naga/tests/out/glsl/abstract-types-return.main.Compute.glsl b/naga/tests/out/glsl/abstract-types-return.main.Compute.glsl
index 07c75d7c51..4506425876 100644
--- a/naga/tests/out/glsl/abstract-types-return.main.Compute.glsl
+++ b/naga/tests/out/glsl/abstract-types-return.main.Compute.glsl
@@ -30,6 +30,10 @@ float[4] return_arrf32_ai() {
     return float[4](1.0, 1.0, 1.0, 1.0);
 }
 
+float return_const_f32_const_ai() {
+    return 1.0;
+}
+
 void main() {
     return;
 }
diff --git a/naga/tests/out/glsl/constructors.main.Compute.glsl b/naga/tests/out/glsl/constructors.main.Compute.glsl
index cff178f200..ef31b76d9b 100644
--- a/naga/tests/out/glsl/constructors.main.Compute.glsl
+++ b/naga/tests/out/glsl/constructors.main.Compute.glsl
@@ -9,7 +9,6 @@ struct Foo {
     vec4 a;
     int b;
 };
-const vec3 const2_ = vec3(0.0, 1.0, 2.0);
 const mat2x2 const3_ = mat2x2(vec2(0.0, 1.0), vec2(2.0, 3.0));
 const mat2x2 const4_[1] = mat2x2[1](mat2x2(vec2(0.0, 1.0), vec2(2.0, 3.0)));
 const bool cz0_ = false;
@@ -20,7 +19,6 @@ const uvec2 cz4_ = uvec2(0u);
 const mat2x2 cz5_ = mat2x2(0.0);
 const Foo cz6_[3] = Foo[3](Foo(vec4(0.0), 0), Foo(vec4(0.0), 0), Foo(vec4(0.0), 0));
 const Foo cz7_ = Foo(vec4(0.0), 0);
-const int cp3_[4] = int[4](0, 1, 2, 3);
 
 
 void main() {
diff --git a/naga/tests/out/hlsl/abstract-types-return.hlsl b/naga/tests/out/hlsl/abstract-types-return.hlsl
index 77a09e8c9a..0311a1f385 100644
--- a/naga/tests/out/hlsl/abstract-types-return.hlsl
+++ b/naga/tests/out/hlsl/abstract-types-return.hlsl
@@ -35,6 +35,11 @@ ret_return_arrf32_ai return_arrf32_ai()
     return Constructarray4_float_(1.0, 1.0, 1.0, 1.0);
 }
 
+float return_const_f32_const_ai()
+{
+    return 1.0;
+}
+
 [numthreads(1, 1, 1)]
 void main()
 {
diff --git a/naga/tests/out/hlsl/constructors.hlsl b/naga/tests/out/hlsl/constructors.hlsl
index 5cc3702630..e21548b7a1 100644
--- a/naga/tests/out/hlsl/constructors.hlsl
+++ b/naga/tests/out/hlsl/constructors.hlsl
@@ -12,12 +12,6 @@ ret_Constructarray1_float2x2_ Constructarray1_float2x2_(float2x2 arg0) {
     return ret;
 }
 
-typedef int ret_Constructarray4_int_[4];
-ret_Constructarray4_int_ Constructarray4_int_(int arg0, int arg1, int arg2, int arg3) {
-    int ret[4] = { arg0, arg1, arg2, arg3 };
-    return ret;
-}
-
 bool ZeroValuebool() {
     return (bool)0;
 }
@@ -51,7 +45,6 @@ Foo ZeroValueFoo() {
     return (Foo)0;
 }
 
-static const float3 const2_ = float3(0.0, 1.0, 2.0);
 static const float2x2 const3_ = float2x2(float2(0.0, 1.0), float2(2.0, 3.0));
 static const float2x2 const4_[1] = Constructarray1_float2x2_(float2x2(float2(0.0, 1.0), float2(2.0, 3.0)));
 static const bool cz0_ = ZeroValuebool();
@@ -62,7 +55,6 @@ static const uint2 cz4_ = ZeroValueuint2();
 static const float2x2 cz5_ = ZeroValuefloat2x2();
 static const Foo cz6_[3] = ZeroValuearray3_Foo_();
 static const Foo cz7_ = ZeroValueFoo();
-static const int cp3_[4] = Constructarray4_int_(int(0), int(1), int(2), int(3));
 
 Foo ConstructFoo(float4 arg0, int arg1) {
     Foo ret = (Foo)0;
@@ -71,6 +63,12 @@ Foo ConstructFoo(float4 arg0, int arg1) {
     return ret;
 }
 
+typedef int ret_Constructarray4_int_[4];
+ret_Constructarray4_int_ Constructarray4_int_(int arg0, int arg1, int arg2, int arg3) {
+    int ret[4] = { arg0, arg1, arg2, arg3 };
+    return ret;
+}
+
 float2x3 ZeroValuefloat2x3() {
     return (float2x3)0;
 }
diff --git a/naga/tests/out/ir/const_assert.compact.ron b/naga/tests/out/ir/const_assert.compact.ron
index 03c540b601..15fa331fb6 100644
--- a/naga/tests/out/ir/const_assert.compact.ron
+++ b/naga/tests/out/ir/const_assert.compact.ron
@@ -1,36 +1,14 @@
 (
-    types: [
-        (
-            name: None,
-            inner: Scalar((
-                kind: Sint,
-                width: 4,
-            )),
-        ),
-    ],
+    types: [],
     special_types: (
         ray_desc: None,
         ray_intersection: None,
         predeclared_types: {},
     ),
-    constants: [
-        (
-            name: Some("x"),
-            ty: 0,
-            init: 0,
-        ),
-        (
-            name: Some("y"),
-            ty: 0,
-            init: 1,
-        ),
-    ],
+    constants: [],
     overrides: [],
     global_variables: [],
-    global_expressions: [
-        Literal(I32(1)),
-        Literal(I32(2)),
-    ],
+    global_expressions: [],
     functions: [
         (
             name: Some("foo"),
diff --git a/naga/tests/out/ir/const_assert.ron b/naga/tests/out/ir/const_assert.ron
index 03c540b601..15fa331fb6 100644
--- a/naga/tests/out/ir/const_assert.ron
+++ b/naga/tests/out/ir/const_assert.ron
@@ -1,36 +1,14 @@
 (
-    types: [
-        (
-            name: None,
-            inner: Scalar((
-                kind: Sint,
-                width: 4,
-            )),
-        ),
-    ],
+    types: [],
     special_types: (
         ray_desc: None,
         ray_intersection: None,
         predeclared_types: {},
     ),
-    constants: [
-        (
-            name: Some("x"),
-            ty: 0,
-            init: 0,
-        ),
-        (
-            name: Some("y"),
-            ty: 0,
-            init: 1,
-        ),
-    ],
+    constants: [],
     overrides: [],
     global_variables: [],
-    global_expressions: [
-        Literal(I32(1)),
-        Literal(I32(2)),
-    ],
+    global_expressions: [],
     functions: [
         (
             name: Some("foo"),
diff --git a/naga/tests/out/ir/local-const.compact.ron b/naga/tests/out/ir/local-const.compact.ron
index fc3dc81e71..53fa73819a 100644
--- a/naga/tests/out/ir/local-const.compact.ron
+++ b/naga/tests/out/ir/local-const.compact.ron
@@ -38,53 +38,28 @@
         predeclared_types: {},
     ),
     constants: [
-        (
-            name: Some("ga"),
-            ty: 0,
-            init: 0,
-        ),
         (
             name: Some("gb"),
             ty: 0,
-            init: 1,
+            init: 0,
         ),
         (
             name: Some("gc"),
             ty: 1,
-            init: 2,
+            init: 1,
         ),
         (
             name: Some("gd"),
             ty: 2,
-            init: 3,
-        ),
-        (
-            name: Some("ge"),
-            ty: 3,
-            init: 4,
-        ),
-        (
-            name: Some("gf"),
-            ty: 2,
-            init: 5,
+            init: 2,
         ),
     ],
     overrides: [],
     global_variables: [],
     global_expressions: [
-        Literal(I32(4)),
         Literal(I32(4)),
         Literal(U32(4)),
         Literal(F32(4.0)),
-        Compose(
-            ty: 3,
-            components: [
-                0,
-                0,
-                0,
-            ],
-        ),
-        Literal(F32(2.0)),
     ],
     functions: [
         (
@@ -106,12 +81,22 @@
                     ],
                 ),
                 Literal(F32(2.0)),
+                Literal(I32(4)),
                 Constant(0),
                 Constant(1),
                 Constant(2),
-                Constant(3),
-                Constant(4),
-                Constant(5),
+                Literal(I32(4)),
+                Literal(I32(4)),
+                Literal(I32(4)),
+                Compose(
+                    ty: 3,
+                    components: [
+                        10,
+                        11,
+                        12,
+                    ],
+                ),
+                Literal(F32(2.0)),
             ],
             named_expressions: {
                 0: "a",
@@ -124,14 +109,22 @@
                 7: "bg",
                 8: "cg",
                 9: "dg",
-                10: "eg",
-                11: "fg",
+                13: "eg",
+                14: "fg",
             },
             body: [
                 Emit((
                     start: 4,
                     end: 5,
                 )),
+                Emit((
+                    start: 0,
+                    end: 0,
+                )),
+                Emit((
+                    start: 13,
+                    end: 14,
+                )),
                 Return(
                     value: None,
                 ),
diff --git a/naga/tests/out/ir/local-const.ron b/naga/tests/out/ir/local-const.ron
index fc3dc81e71..53fa73819a 100644
--- a/naga/tests/out/ir/local-const.ron
+++ b/naga/tests/out/ir/local-const.ron
@@ -38,53 +38,28 @@
         predeclared_types: {},
     ),
     constants: [
-        (
-            name: Some("ga"),
-            ty: 0,
-            init: 0,
-        ),
         (
             name: Some("gb"),
             ty: 0,
-            init: 1,
+            init: 0,
         ),
         (
             name: Some("gc"),
             ty: 1,
-            init: 2,
+            init: 1,
         ),
         (
             name: Some("gd"),
             ty: 2,
-            init: 3,
-        ),
-        (
-            name: Some("ge"),
-            ty: 3,
-            init: 4,
-        ),
-        (
-            name: Some("gf"),
-            ty: 2,
-            init: 5,
+            init: 2,
         ),
     ],
     overrides: [],
     global_variables: [],
     global_expressions: [
-        Literal(I32(4)),
         Literal(I32(4)),
         Literal(U32(4)),
         Literal(F32(4.0)),
-        Compose(
-            ty: 3,
-            components: [
-                0,
-                0,
-                0,
-            ],
-        ),
-        Literal(F32(2.0)),
     ],
     functions: [
         (
@@ -106,12 +81,22 @@
                     ],
                 ),
                 Literal(F32(2.0)),
+                Literal(I32(4)),
                 Constant(0),
                 Constant(1),
                 Constant(2),
-                Constant(3),
-                Constant(4),
-                Constant(5),
+                Literal(I32(4)),
+                Literal(I32(4)),
+                Literal(I32(4)),
+                Compose(
+                    ty: 3,
+                    components: [
+                        10,
+                        11,
+                        12,
+                    ],
+                ),
+                Literal(F32(2.0)),
             ],
             named_expressions: {
                 0: "a",
@@ -124,14 +109,22 @@
                 7: "bg",
                 8: "cg",
                 9: "dg",
-                10: "eg",
-                11: "fg",
+                13: "eg",
+                14: "fg",
             },
             body: [
                 Emit((
                     start: 4,
                     end: 5,
                 )),
+                Emit((
+                    start: 0,
+                    end: 0,
+                )),
+                Emit((
+                    start: 13,
+                    end: 14,
+                )),
                 Return(
                     value: None,
                 ),
diff --git a/naga/tests/out/msl/abstract-types-const.msl b/naga/tests/out/msl/abstract-types-const.msl
index 16a3e35b9a..35efedb44a 100644
--- a/naga/tests/out/msl/abstract-types-const.msl
+++ b/naga/tests/out/msl/abstract-types-const.msl
@@ -23,20 +23,12 @@ constant metal::float2x2 xmfpafaiaiai = metal::float2x2(metal::float2(1.0, 2.0),
 constant metal::float2x2 xmfpaiafaiai = metal::float2x2(metal::float2(1.0, 2.0), metal::float2(3.0, 4.0));
 constant metal::float2x2 xmfpaiaiafai = metal::float2x2(metal::float2(1.0, 2.0), metal::float2(3.0, 4.0));
 constant metal::float2x2 xmfpaiaiaiaf = metal::float2x2(metal::float2(1.0, 2.0), metal::float2(3.0, 4.0));
-constant metal::float2x2 imfpaiaiaiai = metal::float2x2(metal::float2(1.0, 2.0), metal::float2(3.0, 4.0));
-constant metal::float2x2 imfpafaiaiai = metal::float2x2(metal::float2(1.0, 2.0), metal::float2(3.0, 4.0));
-constant metal::float2x2 imfpafafafaf = metal::float2x2(metal::float2(1.0, 2.0), metal::float2(3.0, 4.0));
-constant metal::int2 ivispai = metal::int2(1);
-constant metal::float2 ivfspaf = metal::float2(1.0);
 constant metal::int2 ivis_ai = metal::int2(1);
 constant metal::uint2 ivus_ai = metal::uint2(1u);
 constant metal::float2 ivfs_ai = metal::float2(1.0);
 constant metal::float2 ivfs_af = metal::float2(1.0);
 constant type_7 iafafaf = type_7 {1.0, 2.0};
 constant type_7 iafaiai = type_7 {1.0, 2.0};
-constant type_7 iafpafaf = type_7 {1.0, 2.0};
-constant type_7 iafpaiaf = type_7 {1.0, 2.0};
-constant type_7 iafpafai = type_7 {1.0, 2.0};
 constant type_7 xafpafaf = type_7 {1.0, 2.0};
 constant S s_f_i_u = S {1.0, 1, 1u};
 constant S s_f_iai = S {1.0, 1, 1u};
diff --git a/naga/tests/out/msl/abstract-types-function-calls.msl b/naga/tests/out/msl/abstract-types-function-calls.msl
index bf62d87a54..88ac95bea9 100644
--- a/naga/tests/out/msl/abstract-types-function-calls.msl
+++ b/naga/tests/out/msl/abstract-types-function-calls.msl
@@ -87,16 +87,31 @@ void main_(
     func_f(0.0);
     func_i(0);
     func_u(0u);
+    func_f(0.0);
+    func_f(0.0);
+    func_i(0);
+    func_u(0u);
+    func_vf(metal::float2(0.0));
+    func_vf(metal::float2(0.0));
+    func_vi(metal::int2(0));
+    func_vu(metal::uint2(0u));
     func_vf(metal::float2(0.0));
     func_vf(metal::float2(0.0));
     func_vi(metal::int2(0));
     func_vu(metal::uint2(0u));
     func_mf(metal::float2x2(metal::float2(0.0), metal::float2(0.0)));
     func_mf(metal::float2x2(metal::float2(0.0), metal::float2(0.0)));
+    func_mf(metal::float2x2(metal::float2(0.0), metal::float2(0.0)));
     func_af(type_7 {0.0, 0.0});
     func_af(type_7 {0.0, 0.0});
     func_ai(type_8 {0, 0});
     func_au(type_9 {0u, 0u});
+    func_af(type_7 {0.0, 0.0});
+    func_af(type_7 {0.0, 0.0});
+    func_ai(type_8 {0, 0});
+    func_au(type_9 {0u, 0u});
+    func_f_i(0.0, 0);
+    func_f_i(0.0, 0);
     func_f_i(0.0, 0);
     func_f_i(0.0, 0);
     return;
diff --git a/naga/tests/out/msl/abstract-types-operators.msl b/naga/tests/out/msl/abstract-types-operators.msl
index 6bb3ba4380..a7a972fdb5 100644
--- a/naga/tests/out/msl/abstract-types-operators.msl
+++ b/naga/tests/out/msl/abstract-types-operators.msl
@@ -37,7 +37,6 @@ constant int shr_iai_u = 0;
 constant uint shr_uaiai = 0u;
 constant uint shr_uai_u = 0u;
 constant int wgpu_4492_ = -2147483648;
-constant int wgpu_4492_2_ = -2147483648;
 
 void runtime_values(
 ) {
diff --git a/naga/tests/out/msl/abstract-types-return.msl b/naga/tests/out/msl/abstract-types-return.msl
index 99072e7473..3d2ee03a67 100644
--- a/naga/tests/out/msl/abstract-types-return.msl
+++ b/naga/tests/out/msl/abstract-types-return.msl
@@ -38,6 +38,11 @@ type_4 return_arrf32_ai(
     return type_4 {1.0, 1.0, 1.0, 1.0};
 }
 
+float return_const_f32_const_ai(
+) {
+    return 1.0;
+}
+
 kernel void main_(
 ) {
     return;
diff --git a/naga/tests/out/msl/constructors.msl b/naga/tests/out/msl/constructors.msl
index 1084d8e8aa..3e2c096227 100644
--- a/naga/tests/out/msl/constructors.msl
+++ b/naga/tests/out/msl/constructors.msl
@@ -8,27 +8,25 @@ struct Foo {
     metal::float4 a;
     int b;
 };
-struct type_6 {
+struct type_5 {
     metal::float2x2 inner[1];
 };
-struct type_10 {
+struct type_9 {
     Foo inner[3];
 };
 struct type_11 {
     int inner[4];
 };
-constant metal::float3 const2_ = metal::float3(0.0, 1.0, 2.0);
 constant metal::float2x2 const3_ = metal::float2x2(metal::float2(0.0, 1.0), metal::float2(2.0, 3.0));
-constant type_6 const4_ = type_6 {metal::float2x2(metal::float2(0.0, 1.0), metal::float2(2.0, 3.0))};
+constant type_5 const4_ = type_5 {metal::float2x2(metal::float2(0.0, 1.0), metal::float2(2.0, 3.0))};
 constant bool cz0_ = bool {};
 constant int cz1_ = int {};
 constant uint cz2_ = uint {};
 constant float cz3_ = float {};
 constant metal::uint2 cz4_ = metal::uint2 {};
 constant metal::float2x2 cz5_ = metal::float2x2 {};
-constant type_10 cz6_ = type_10 {};
+constant type_9 cz6_ = type_9 {};
 constant Foo cz7_ = Foo {};
-constant type_11 cp3_ = type_11 {0, 1, 2, 3};
 
 kernel void main_(
 ) {
diff --git a/naga/tests/out/spv/abstract-types-const.spvasm b/naga/tests/out/spv/abstract-types-const.spvasm
index edebb600ac..af8cfb0283 100644
--- a/naga/tests/out/spv/abstract-types-const.spvasm
+++ b/naga/tests/out/spv/abstract-types-const.spvasm
@@ -16,11 +16,11 @@ OpMemberDecorate %12 2 Offset 8
 %5 = OpTypeFloat 32
 %6 = OpTypeVector %5 2
 %7 = OpTypeMatrix %6 2
-%9 = OpTypeInt 32 1
-%8 = OpTypeVector %9 2
+%8 = OpTypeInt 32 1
+%9 = OpTypeVector %8 2
 %11 = OpConstant  %3  2
 %10 = OpTypeArray %5 %11
-%12 = OpTypeStruct %5 %9 %3
+%12 = OpTypeStruct %5 %8 %3
 %13 = OpTypeVector %5 3
 %14 = OpConstant  %3  42
 %15 = OpConstant  %3  43
@@ -35,12 +35,12 @@ OpMemberDecorate %12 2 Offset 8
 %24 = OpConstant  %5  4.0
 %25 = OpConstantComposite  %6  %23 %24
 %26 = OpConstantComposite  %7  %22 %25
-%27 = OpConstant  %9  1
-%28 = OpConstantComposite  %8  %27 %27
-%29 = OpConstantComposite  %6  %20 %20
-%30 = OpConstant  %3  1
-%31 = OpConstantComposite  %4  %30 %30
+%27 = OpConstant  %8  1
+%28 = OpConstantComposite  %9  %27 %27
+%29 = OpConstant  %3  1
+%30 = OpConstantComposite  %4  %29 %29
+%31 = OpConstantComposite  %6  %20 %20
 %32 = OpConstantComposite  %10  %20 %21
-%33 = OpConstantComposite  %12  %20 %27 %30
+%33 = OpConstantComposite  %12  %20 %27 %29
 %34 = OpConstantComposite  %13  %20 %21 %23
 %35 = OpConstantComposite  %6  %21 %23
\ No newline at end of file
diff --git a/naga/tests/out/spv/abstract-types-function-calls.spvasm b/naga/tests/out/spv/abstract-types-function-calls.spvasm
index 58e064bb4e..29bdf1548a 100644
--- a/naga/tests/out/spv/abstract-types-function-calls.spvasm
+++ b/naga/tests/out/spv/abstract-types-function-calls.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.1
 ; Generator: rspirv
-; Bound: 100
+; Bound: 115
 OpCapability Shader
 OpCapability Linkage
 %1 = OpExtInstImport "GLSL.std.450"
@@ -129,17 +129,32 @@ OpBranch %83
 %85 = OpFunctionCall  %2  %16 %73
 %86 = OpFunctionCall  %2  %21 %74
 %87 = OpFunctionCall  %2  %26 %75
-%88 = OpFunctionCall  %2  %31 %76
-%89 = OpFunctionCall  %2  %31 %76
-%90 = OpFunctionCall  %2  %36 %77
-%91 = OpFunctionCall  %2  %41 %78
-%92 = OpFunctionCall  %2  %46 %79
-%93 = OpFunctionCall  %2  %46 %79
-%94 = OpFunctionCall  %2  %51 %80
-%95 = OpFunctionCall  %2  %51 %80
-%96 = OpFunctionCall  %2  %56 %81
-%97 = OpFunctionCall  %2  %61 %82
-%98 = OpFunctionCall  %2  %67 %73 %74
-%99 = OpFunctionCall  %2  %67 %73 %74
+%88 = OpFunctionCall  %2  %16 %73
+%89 = OpFunctionCall  %2  %16 %73
+%90 = OpFunctionCall  %2  %21 %74
+%91 = OpFunctionCall  %2  %26 %75
+%92 = OpFunctionCall  %2  %31 %76
+%93 = OpFunctionCall  %2  %31 %76
+%94 = OpFunctionCall  %2  %36 %77
+%95 = OpFunctionCall  %2  %41 %78
+%96 = OpFunctionCall  %2  %31 %76
+%97 = OpFunctionCall  %2  %31 %76
+%98 = OpFunctionCall  %2  %36 %77
+%99 = OpFunctionCall  %2  %41 %78
+%100 = OpFunctionCall  %2  %46 %79
+%101 = OpFunctionCall  %2  %46 %79
+%102 = OpFunctionCall  %2  %46 %79
+%103 = OpFunctionCall  %2  %51 %80
+%104 = OpFunctionCall  %2  %51 %80
+%105 = OpFunctionCall  %2  %56 %81
+%106 = OpFunctionCall  %2  %61 %82
+%107 = OpFunctionCall  %2  %51 %80
+%108 = OpFunctionCall  %2  %51 %80
+%109 = OpFunctionCall  %2  %56 %81
+%110 = OpFunctionCall  %2  %61 %82
+%111 = OpFunctionCall  %2  %67 %73 %74
+%112 = OpFunctionCall  %2  %67 %73 %74
+%113 = OpFunctionCall  %2  %67 %73 %74
+%114 = OpFunctionCall  %2  %67 %73 %74
 OpReturn
 OpFunctionEnd
\ No newline at end of file
diff --git a/naga/tests/out/spv/abstract-types-return.spvasm b/naga/tests/out/spv/abstract-types-return.spvasm
index 8ce671adfc..4341b27b2f 100644
--- a/naga/tests/out/spv/abstract-types-return.spvasm
+++ b/naga/tests/out/spv/abstract-types-return.spvasm
@@ -1,12 +1,12 @@
 ; SPIR-V
 ; Version: 1.1
 ; Generator: rspirv
-; Bound: 41
+; Bound: 44
 OpCapability Shader
 %1 = OpExtInstImport "GLSL.std.450"
 OpMemoryModel Logical GLSL450
-OpEntryPoint GLCompute %38 "main"
-OpExecutionMode %38 LocalSize 1 1 1
+OpEntryPoint GLCompute %41 "main"
+OpExecutionMode %41 LocalSize 1 1 1
 OpDecorate %7 ArrayStride 4
 %2 = OpTypeVoid
 %3 = OpTypeInt 32 1
@@ -25,7 +25,7 @@ OpDecorate %7 ArrayStride 4
 %30 = OpConstantComposite  %6  %22 %22
 %34 = OpTypeFunction %7
 %35 = OpConstantComposite  %7  %22 %22 %22 %22
-%39 = OpTypeFunction %2
+%42 = OpTypeFunction %2
 %10 = OpFunction  %3  None %11
 %9 = OpLabel
 OpBranch %13
@@ -62,9 +62,15 @@ OpBranch %36
 %36 = OpLabel
 OpReturnValue %35
 OpFunctionEnd
-%38 = OpFunction  %2  None %39
+%38 = OpFunction  %5  None %21
 %37 = OpLabel
-OpBranch %40
+OpBranch %39
+%39 = OpLabel
+OpReturnValue %22
+OpFunctionEnd
+%41 = OpFunction  %2  None %42
 %40 = OpLabel
+OpBranch %43
+%43 = OpLabel
 OpReturn
 OpFunctionEnd
\ No newline at end of file
diff --git a/naga/tests/out/spv/constructors.spvasm b/naga/tests/out/spv/constructors.spvasm
index ec83d04822..4aa6a6f663 100644
--- a/naga/tests/out/spv/constructors.spvasm
+++ b/naga/tests/out/spv/constructors.spvasm
@@ -1,84 +1,83 @@
 ; SPIR-V
 ; Version: 1.1
 ; Generator: rspirv
-; Bound: 68
+; Bound: 67
 OpCapability Shader
 %1 = OpExtInstImport "GLSL.std.450"
 OpMemoryModel Logical GLSL450
-OpEntryPoint GLCompute %44 "main"
-OpExecutionMode %44 LocalSize 1 1 1
+OpEntryPoint GLCompute %38 "main"
+OpExecutionMode %38 LocalSize 1 1 1
 OpMemberDecorate %6 0 Offset 0
 OpMemberDecorate %6 1 Offset 16
-OpDecorate %10 ArrayStride 16
-OpDecorate %15 ArrayStride 32
+OpDecorate %9 ArrayStride 16
+OpDecorate %14 ArrayStride 32
 OpDecorate %17 ArrayStride 4
 %2 = OpTypeVoid
 %3 = OpTypeFloat 32
 %4 = OpTypeVector %3 4
 %5 = OpTypeInt 32 1
 %6 = OpTypeStruct %4 %5
-%7 = OpTypeVector %3 3
-%9 = OpTypeVector %3 2
-%8 = OpTypeMatrix %9 2
-%12 = OpTypeInt 32 0
-%11 = OpConstant  %12  1
-%10 = OpTypeArray %8 %11
-%13 = OpTypeBool
-%14 = OpTypeVector %12 2
-%16 = OpConstant  %12  3
-%15 = OpTypeArray %6 %16
-%18 = OpConstant  %12  4
+%8 = OpTypeVector %3 2
+%7 = OpTypeMatrix %8 2
+%11 = OpTypeInt 32 0
+%10 = OpConstant  %11  1
+%9 = OpTypeArray %7 %10
+%12 = OpTypeBool
+%13 = OpTypeVector %11 2
+%15 = OpConstant  %11  3
+%14 = OpTypeArray %6 %15
+%16 = OpTypeMatrix %4 4
+%18 = OpConstant  %11  4
 %17 = OpTypeArray %5 %18
-%19 = OpTypeMatrix %4 4
-%20 = OpTypeMatrix %7 2
+%20 = OpTypeVector %3 3
+%19 = OpTypeMatrix %20 2
 %21 = OpConstant  %3  0.0
 %22 = OpConstant  %3  1.0
 %23 = OpConstant  %3  2.0
-%24 = OpConstantComposite  %7  %21 %22 %23
-%25 = OpConstant  %3  3.0
-%26 = OpConstantComposite  %9  %21 %22
-%27 = OpConstantComposite  %9  %23 %25
-%28 = OpConstantComposite  %8  %26 %27
-%29 = OpConstantComposite  %10  %28
-%30 = OpConstantNull  %13
-%31 = OpConstantNull  %5
-%32 = OpConstantNull  %12
-%33 = OpConstantNull  %3
-%34 = OpConstantNull  %14
-%35 = OpConstantNull  %8
-%36 = OpConstantNull  %15
-%37 = OpConstantNull  %6
-%38 = OpConstant  %5  0
-%39 = OpConstant  %5  1
-%40 = OpConstant  %5  2
-%41 = OpConstant  %5  3
-%42 = OpConstantComposite  %17  %38 %39 %40 %41
-%45 = OpTypeFunction %2
-%46 = OpConstantComposite  %4  %22 %22 %22 %22
-%47 = OpConstantComposite  %6  %46 %39
-%48 = OpConstantComposite  %9  %22 %21
-%49 = OpConstantComposite  %8  %48 %26
-%50 = OpConstantComposite  %4  %22 %21 %21 %21
-%51 = OpConstantComposite  %4  %21 %22 %21 %21
-%52 = OpConstantComposite  %4  %21 %21 %22 %21
-%53 = OpConstantComposite  %4  %21 %21 %21 %22
-%54 = OpConstantComposite  %19  %50 %51 %52 %53
-%55 = OpConstant  %12  0
-%56 = OpConstantComposite  %14  %55 %55
-%57 = OpConstantComposite  %9  %21 %21
-%58 = OpConstantComposite  %8  %57 %57
-%59 = OpConstantFalse  %13
-%60 = OpConstantComposite  %14  %55 %55
-%61 = OpConstantComposite  %7  %21 %21 %21
-%62 = OpConstantComposite  %20  %61 %61
-%63 = OpConstantNull  %20
-%65 = OpTypePointer Function %6
-%66 = OpConstantNull  %6
-%44 = OpFunction  %2  None %45
-%43 = OpLabel
-%64 = OpVariable  %65  Function %66
-OpBranch %67
-%67 = OpLabel
-OpStore %64 %47
+%24 = OpConstant  %3  3.0
+%25 = OpConstantComposite  %8  %21 %22
+%26 = OpConstantComposite  %8  %23 %24
+%27 = OpConstantComposite  %7  %25 %26
+%28 = OpConstantComposite  %9  %27
+%29 = OpConstantNull  %12
+%30 = OpConstantNull  %5
+%31 = OpConstantNull  %11
+%32 = OpConstantNull  %3
+%33 = OpConstantNull  %13
+%34 = OpConstantNull  %7
+%35 = OpConstantNull  %14
+%36 = OpConstantNull  %6
+%39 = OpTypeFunction %2
+%40 = OpConstantComposite  %4  %22 %22 %22 %22
+%41 = OpConstant  %5  1
+%42 = OpConstantComposite  %6  %40 %41
+%43 = OpConstantComposite  %8  %22 %21
+%44 = OpConstantComposite  %7  %43 %25
+%45 = OpConstantComposite  %4  %22 %21 %21 %21
+%46 = OpConstantComposite  %4  %21 %22 %21 %21
+%47 = OpConstantComposite  %4  %21 %21 %22 %21
+%48 = OpConstantComposite  %4  %21 %21 %21 %22
+%49 = OpConstantComposite  %16  %45 %46 %47 %48
+%50 = OpConstant  %11  0
+%51 = OpConstantComposite  %13  %50 %50
+%52 = OpConstantComposite  %8  %21 %21
+%53 = OpConstantComposite  %7  %52 %52
+%54 = OpConstant  %5  0
+%55 = OpConstant  %5  2
+%56 = OpConstant  %5  3
+%57 = OpConstantComposite  %17  %54 %41 %55 %56
+%58 = OpConstantFalse  %12
+%59 = OpConstantComposite  %13  %50 %50
+%60 = OpConstantComposite  %20  %21 %21 %21
+%61 = OpConstantComposite  %19  %60 %60
+%62 = OpConstantNull  %19
+%64 = OpTypePointer Function %6
+%65 = OpConstantNull  %6
+%38 = OpFunction  %2  None %39
+%37 = OpLabel
+%63 = OpVariable  %64  Function %65
+OpBranch %66
+%66 = OpLabel
+OpStore %63 %42
 OpReturn
 OpFunctionEnd
\ No newline at end of file
diff --git a/naga/tests/out/wgsl/abstract-types-const.wgsl b/naga/tests/out/wgsl/abstract-types-const.wgsl
index 195247bbbc..649740f8c8 100644
--- a/naga/tests/out/wgsl/abstract-types-const.wgsl
+++ b/naga/tests/out/wgsl/abstract-types-const.wgsl
@@ -15,20 +15,12 @@ const xmfpafaiaiai: mat2x2<f32> = mat2x2<f32>(vec2<f32>(1f, 2f), vec2<f32>(3f, 4
 const xmfpaiafaiai: mat2x2<f32> = mat2x2<f32>(vec2<f32>(1f, 2f), vec2<f32>(3f, 4f));
 const xmfpaiaiafai: mat2x2<f32> = mat2x2<f32>(vec2<f32>(1f, 2f), vec2<f32>(3f, 4f));
 const xmfpaiaiaiaf: mat2x2<f32> = mat2x2<f32>(vec2<f32>(1f, 2f), vec2<f32>(3f, 4f));
-const imfpaiaiaiai: mat2x2<f32> = mat2x2<f32>(vec2<f32>(1f, 2f), vec2<f32>(3f, 4f));
-const imfpafaiaiai: mat2x2<f32> = mat2x2<f32>(vec2<f32>(1f, 2f), vec2<f32>(3f, 4f));
-const imfpafafafaf: mat2x2<f32> = mat2x2<f32>(vec2<f32>(1f, 2f), vec2<f32>(3f, 4f));
-const ivispai: vec2<i32> = vec2(1i);
-const ivfspaf: vec2<f32> = vec2(1f);
 const ivis_ai: vec2<i32> = vec2(1i);
 const ivus_ai: vec2<u32> = vec2(1u);
 const ivfs_ai: vec2<f32> = vec2(1f);
 const ivfs_af: vec2<f32> = vec2(1f);
 const iafafaf: array<f32, 2> = array<f32, 2>(1f, 2f);
 const iafaiai: array<f32, 2> = array<f32, 2>(1f, 2f);
-const iafpafaf: array<f32, 2> = array<f32, 2>(1f, 2f);
-const iafpaiaf: array<f32, 2> = array<f32, 2>(1f, 2f);
-const iafpafai: array<f32, 2> = array<f32, 2>(1f, 2f);
 const xafpafaf: array<f32, 2> = array<f32, 2>(1f, 2f);
 const s_f_i_u: S = S(1f, 1i, 1u);
 const s_f_iai: S = S(1f, 1i, 1u);
diff --git a/naga/tests/out/wgsl/abstract-types-function-calls.wgsl b/naga/tests/out/wgsl/abstract-types-function-calls.wgsl
index 419125bc6b..1bc290cd39 100644
--- a/naga/tests/out/wgsl/abstract-types-function-calls.wgsl
+++ b/naga/tests/out/wgsl/abstract-types-function-calls.wgsl
@@ -47,16 +47,31 @@ fn main() {
     func_f(0f);
     func_i(0i);
     func_u(0u);
+    func_f(0f);
+    func_f(0f);
+    func_i(0i);
+    func_u(0u);
+    func_vf(vec2(0f));
+    func_vf(vec2(0f));
+    func_vi(vec2(0i));
+    func_vu(vec2(0u));
     func_vf(vec2(0f));
     func_vf(vec2(0f));
     func_vi(vec2(0i));
     func_vu(vec2(0u));
     func_mf(mat2x2<f32>(vec2(0f), vec2(0f)));
     func_mf(mat2x2<f32>(vec2(0f), vec2(0f)));
+    func_mf(mat2x2<f32>(vec2(0f), vec2(0f)));
     func_af(array<f32, 2>(0f, 0f));
     func_af(array<f32, 2>(0f, 0f));
     func_ai(array<i32, 2>(0i, 0i));
     func_au(array<u32, 2>(0u, 0u));
+    func_af(array<f32, 2>(0f, 0f));
+    func_af(array<f32, 2>(0f, 0f));
+    func_ai(array<i32, 2>(0i, 0i));
+    func_au(array<u32, 2>(0u, 0u));
+    func_f_i(0f, 0i);
+    func_f_i(0f, 0i);
     func_f_i(0f, 0i);
     func_f_i(0f, 0i);
     return;
diff --git a/naga/tests/out/wgsl/abstract-types-operators.wgsl b/naga/tests/out/wgsl/abstract-types-operators.wgsl
index 6b8ffceb14..d86477de0b 100644
--- a/naga/tests/out/wgsl/abstract-types-operators.wgsl
+++ b/naga/tests/out/wgsl/abstract-types-operators.wgsl
@@ -28,7 +28,6 @@ const shr_iai_u: i32 = 0i;
 const shr_uaiai: u32 = 0u;
 const shr_uai_u: u32 = 0u;
 const wgpu_4492_: i32 = i32(-2147483648);
-const wgpu_4492_2_: i32 = i32(-2147483648);
 
 var<workgroup> a: array<u32, 64>;
 
diff --git a/naga/tests/out/wgsl/abstract-types-return.wgsl b/naga/tests/out/wgsl/abstract-types-return.wgsl
index c25a217dac..6c5b60224b 100644
--- a/naga/tests/out/wgsl/abstract-types-return.wgsl
+++ b/naga/tests/out/wgsl/abstract-types-return.wgsl
@@ -22,6 +22,10 @@ fn return_arrf32_ai() -> array<f32, 4> {
     return array<f32, 4>(1f, 1f, 1f, 1f);
 }
 
+fn return_const_f32_const_ai() -> f32 {
+    return 1f;
+}
+
 @compute @workgroup_size(1, 1, 1) 
 fn main() {
     return;
diff --git a/naga/tests/out/wgsl/const_assert.wgsl b/naga/tests/out/wgsl/const_assert.wgsl
index fe1c1c02f4..6271a6de8f 100644
--- a/naga/tests/out/wgsl/const_assert.wgsl
+++ b/naga/tests/out/wgsl/const_assert.wgsl
@@ -1,6 +1,3 @@
-const x: i32 = 1i;
-const y: i32 = 2i;
-
 fn foo() {
     return;
 }
diff --git a/naga/tests/out/wgsl/constructors.wgsl b/naga/tests/out/wgsl/constructors.wgsl
index 622903d7eb..f053e1f6ef 100644
--- a/naga/tests/out/wgsl/constructors.wgsl
+++ b/naga/tests/out/wgsl/constructors.wgsl
@@ -3,7 +3,6 @@ struct Foo {
     b: i32,
 }
 
-const const2_: vec3<f32> = vec3<f32>(0f, 1f, 2f);
 const const3_: mat2x2<f32> = mat2x2<f32>(vec2<f32>(0f, 1f), vec2<f32>(2f, 3f));
 const const4_: array<mat2x2<f32>, 1> = array<mat2x2<f32>, 1>(mat2x2<f32>(vec2<f32>(0f, 1f), vec2<f32>(2f, 3f)));
 const cz0_: bool = bool();
@@ -14,7 +13,6 @@ const cz4_: vec2<u32> = vec2<u32>();
 const cz5_: mat2x2<f32> = mat2x2<f32>();
 const cz6_: array<Foo, 3> = array<Foo, 3>();
 const cz7_: Foo = Foo();
-const cp3_: array<i32, 4> = array<i32, 4>(0i, 1i, 2i, 3i);
 
 @compute @workgroup_size(1, 1, 1) 
 fn main() {
diff --git a/naga/tests/out/wgsl/local-const.wgsl b/naga/tests/out/wgsl/local-const.wgsl
index 06e52a9277..535a1bfb14 100644
--- a/naga/tests/out/wgsl/local-const.wgsl
+++ b/naga/tests/out/wgsl/local-const.wgsl
@@ -1,12 +1,10 @@
-const ga: i32 = 4i;
 const gb: i32 = 4i;
 const gc: u32 = 4u;
 const gd: f32 = 4f;
-const ge: vec3<i32> = vec3<i32>(4i, 4i, 4i);
-const gf: f32 = 2f;
 
 fn const_in_fn() {
     const e = vec3<i32>(4i, 4i, 4i);
+    const eg = vec3<i32>(4i, 4i, 4i);
     return;
 }