tint: Implement constant expression structures

Bug: tint:1611
Change-Id: Id04c31ade297a68e7e2941efafbd812ba631fc41
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/95946
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/writer/hlsl/generator_impl.cc b/src/tint/writer/hlsl/generator_impl.cc
index c9861a1..0a6a196 100644
--- a/src/tint/writer/hlsl/generator_impl.cc
+++ b/src/tint/writer/hlsl/generator_impl.cc
@@ -1142,11 +1142,7 @@
                                              call->Arguments().size() == 1 &&
                                              ctor->Parameters()[0]->Type()->is_scalar();
 
-    auto it = structure_builders_.find(As<sem::Struct>(type));
-    if (it != structure_builders_.end()) {
-        out << it->second << "(";
-        brackets = false;
-    } else if (brackets) {
+    if (brackets) {
         out << "{";
     } else {
         if (!EmitType(out, type, ast::StorageClass::kNone, ast::Access::kReadWrite, "")) {
@@ -3219,6 +3215,30 @@
 
             return true;
         },
+        [&](const sem::Struct* s) {
+            if (constant->AllZero()) {
+                out << "(";
+                if (!EmitType(out, s, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
+                    return false;
+                }
+                out << ")0";
+                return true;
+            }
+
+            out << "{";
+            TINT_DEFER(out << "}");
+
+            for (size_t i = 0; i < s->Members().size(); i++) {
+                if (i > 0) {
+                    out << ", ";
+                }
+                if (!EmitConstant(out, constant->Index(i))) {
+                    return false;
+                }
+            }
+
+            return true;
+        },
         [&](Default) {
             diagnostics_.add_error(
                 diag::System::Writer,