sem::StructType remove symbol()

The name now lives on the ast::Struct. Use that instead.

Bug: tint:724
Change-Id: I4ee5e9b29973e468edd8df8c5448816b36f0fca6
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/48384
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/inspector/inspector.cc b/src/inspector/inspector.cc
index 6889416..213fc88 100644
--- a/src/inspector/inspector.cc
+++ b/src/inspector/inspector.cc
@@ -398,7 +398,7 @@
     auto* sem = program_->Sem().Get(str);
     if (!sem) {
       error_ = "Missing semantic information for structure " +
-               program_->Symbols().NameFor(str->symbol());
+               program_->Symbols().NameFor(str->impl()->name());
       continue;
     }
 
@@ -614,7 +614,7 @@
     auto* sem = program_->Sem().Get(str);
     if (!sem) {
       error_ = "Missing semantic information for structure " +
-               program_->Symbols().NameFor(str->symbol());
+               program_->Symbols().NameFor(str->impl()->name());
       continue;
     }
 
diff --git a/src/inspector/inspector_test.cc b/src/inspector/inspector_test.cc
index 68f0683..15a9539 100644
--- a/src/inspector/inspector_test.cc
+++ b/src/inspector/inspector_test.cc
@@ -227,7 +227,7 @@
 
     auto sym = Sym(name);
     auto* str = create<ast::Struct>(sym, members, decos);
-    auto* str_ty = ty.struct_(sym, str);
+    auto* str_ty = ty.struct_(str);
     AST().AddConstructedType(str_ty);
     return str_ty;
   }
@@ -1829,7 +1829,7 @@
       ast::StructMemberList{Member(StructMemberName(0, ty.i32()), ty.i32())},
       decos);
 
-  auto* foo_type = ty.struct_("foo_type", str);
+  auto* foo_type = ty.struct_(str);
   AddUniformBuffer("foo_ub", foo_type, 0, 0);
 
   MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}});
diff --git a/src/program_builder.h b/src/program_builder.h
index 3e518fc..d8651a9 100644
--- a/src/program_builder.h
+++ b/src/program_builder.h
@@ -556,13 +556,10 @@
       return pointer(Of<T>(), storage_class);
     }
 
-    /// @param name the struct name
     /// @param impl the struct implementation
     /// @returns a struct pointer
-    template <typename NAME>
-    sem::StructType* struct_(NAME&& name, ast::Struct* impl) const {
-      return builder->create<sem::StructType>(
-          builder->Sym(std::forward<NAME>(name)), impl);
+    sem::StructType* struct_(ast::Struct* impl) const {
+      return builder->create<sem::StructType>(impl);
     }
 
    private:
@@ -1188,7 +1185,7 @@
     auto sym = Sym(std::forward<NAME>(name));
     auto* impl = create<ast::Struct>(source, sym, std::move(members),
                                      std::move(decorations));
-    auto* type = ty.struct_(sym, impl);
+    auto* type = ty.struct_(impl);
     AST().AddConstructedType(type);
     return type;
   }
@@ -1206,7 +1203,7 @@
     auto sym = Sym(std::forward<NAME>(name));
     auto* impl =
         create<ast::Struct>(sym, std::move(members), std::move(decorations));
-    auto* type = ty.struct_(sym, impl);
+    auto* type = ty.struct_(impl);
     AST().AddConstructedType(type);
     return type;
   }
diff --git a/src/reader/spirv/parser_impl.cc b/src/reader/spirv/parser_impl.cc
index e22c749..36d1bf9 100644
--- a/src/reader/spirv/parser_impl.cc
+++ b/src/reader/spirv/parser_impl.cc
@@ -948,8 +948,7 @@
   auto sym = builder_.Symbols().Register(name);
   auto* ast_struct = create<ast::Struct>(Source{}, sym, std::move(ast_members),
                                          std::move(ast_struct_decorations));
-
-  auto* result = builder_.create<sem::StructType>(sym, ast_struct);
+  auto* result = builder_.create<sem::StructType>(ast_struct);
   id_to_type_[type_id] = result;
   if (num_non_writable_members == members.size()) {
     read_only_struct_types_.insert(result);
diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc
index 6db1b7e..6ce0278 100644
--- a/src/reader/wgsl/parser_impl.cc
+++ b/src/reader/wgsl/parser_impl.cc
@@ -339,8 +339,8 @@
       if (!expect("struct declaration", Token::Type::kSemicolon))
         return Failure::kErrored;
 
-      register_constructed(builder_.Symbols().NameFor(str.value->symbol()),
-                           str.value);
+      register_constructed(
+          builder_.Symbols().NameFor(str.value->impl()->name()), str.value);
       builder_.AST().AddConstructedType(str.value);
       return true;
     }
@@ -1135,9 +1135,8 @@
     return Failure::kErrored;
 
   auto sym = builder_.Symbols().Register(name.value);
-  return create<sem::StructType>(
-      sym, create<ast::Struct>(source, sym, std::move(body.value),
-                               std::move(decos)));
+  return create<sem::StructType>(create<ast::Struct>(
+      source, sym, std::move(body.value), std::move(decos)));
 }
 
 // struct_body_decl
diff --git a/src/reader/wgsl/parser_impl_global_decl_test.cc b/src/reader/wgsl/parser_impl_global_decl_test.cc
index 385d3ec..551605e 100644
--- a/src/reader/wgsl/parser_impl_global_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_global_decl_test.cc
@@ -104,7 +104,7 @@
   ASSERT_EQ(program.AST().ConstructedTypes().size(), 2u);
   ASSERT_TRUE(program.AST().ConstructedTypes()[0]->Is<sem::StructType>());
   auto* str = program.AST().ConstructedTypes()[0]->As<sem::StructType>();
-  EXPECT_EQ(str->symbol(), program.Symbols().Get("A"));
+  EXPECT_EQ(str->impl()->name(), program.Symbols().Get("A"));
 
   ASSERT_TRUE(program.AST().ConstructedTypes()[1]->Is<sem::Alias>());
   auto* alias = program.AST().ConstructedTypes()[1]->As<sem::Alias>();
@@ -168,7 +168,7 @@
   ASSERT_TRUE(t->Is<sem::StructType>());
 
   auto* str = t->As<sem::StructType>();
-  EXPECT_EQ(str->symbol(), program.Symbols().Get("A"));
+  EXPECT_EQ(str->impl()->name(), program.Symbols().Get("A"));
   EXPECT_EQ(str->impl()->members().size(), 2u);
 }
 
@@ -186,7 +186,7 @@
   ASSERT_TRUE(t->Is<sem::StructType>());
 
   auto* str = t->As<sem::StructType>();
-  EXPECT_EQ(str->symbol(), program.Symbols().Get("A"));
+  EXPECT_EQ(str->impl()->name(), program.Symbols().Get("A"));
   EXPECT_EQ(str->impl()->members().size(), 1u);
   EXPECT_FALSE(str->IsBlockDecorated());
 
@@ -213,7 +213,7 @@
   ASSERT_TRUE(t->Is<sem::StructType>());
 
   auto* str = t->As<sem::StructType>();
-  EXPECT_EQ(str->symbol(), program.Symbols().Get("A"));
+  EXPECT_EQ(str->impl()->name(), program.Symbols().Get("A"));
   EXPECT_EQ(str->impl()->members().size(), 1u);
   EXPECT_TRUE(str->IsBlockDecorated());
 }
diff --git a/src/reader/wgsl/parser_impl_struct_decl_test.cc b/src/reader/wgsl/parser_impl_struct_decl_test.cc
index 869baa2..fad7874 100644
--- a/src/reader/wgsl/parser_impl_struct_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_struct_decl_test.cc
@@ -36,7 +36,7 @@
   EXPECT_FALSE(s.errored);
   EXPECT_TRUE(s.matched);
   ASSERT_NE(s.value, nullptr);
-  ASSERT_EQ(s->symbol(), p->builder().Symbols().Register("S"));
+  ASSERT_EQ(s->impl()->name(), p->builder().Symbols().Register("S"));
   ASSERT_EQ(s->impl()->members().size(), 2u);
   EXPECT_EQ(s->impl()->members()[0]->symbol(),
             p->builder().Symbols().Register("a"));
@@ -60,7 +60,7 @@
   EXPECT_FALSE(s.errored);
   EXPECT_TRUE(s.matched);
   ASSERT_NE(s.value, nullptr);
-  ASSERT_EQ(s->symbol(), p->builder().Symbols().Register("B"));
+  ASSERT_EQ(s->impl()->name(), p->builder().Symbols().Register("B"));
   ASSERT_EQ(s->impl()->members().size(), 2u);
   EXPECT_EQ(s->impl()->members()[0]->symbol(),
             p->builder().Symbols().Register("a"));
@@ -87,7 +87,7 @@
   EXPECT_FALSE(s.errored);
   EXPECT_TRUE(s.matched);
   ASSERT_NE(s.value, nullptr);
-  ASSERT_EQ(s->symbol(), p->builder().Symbols().Register("S"));
+  ASSERT_EQ(s->impl()->name(), p->builder().Symbols().Register("S"));
   ASSERT_EQ(s->impl()->members().size(), 2u);
   EXPECT_EQ(s->impl()->members()[0]->symbol(),
             p->builder().Symbols().Register("a"));
diff --git a/src/reader/wgsl/parser_impl_type_alias_test.cc b/src/reader/wgsl/parser_impl_type_alias_test.cc
index 2cda3c3..f798a4b 100644
--- a/src/reader/wgsl/parser_impl_type_alias_test.cc
+++ b/src/reader/wgsl/parser_impl_type_alias_test.cc
@@ -38,8 +38,8 @@
 TEST_F(ParserImplTest, TypeDecl_ParsesStruct_Ident) {
   auto p = parser("type a = B");
 
-  sem::StructType str(p->builder().Symbols().Get("B"), {});
-  p->register_constructed("B", &str);
+  auto* str = Structure(p->builder().Symbols().Register("B"), {});
+  p->register_constructed("B", str);
 
   auto t = p->type_alias();
   EXPECT_FALSE(p->has_error());
@@ -52,8 +52,8 @@
   ASSERT_TRUE(alias->type()->Is<sem::StructType>());
 
   auto* s = alias->type()->As<sem::StructType>();
-  EXPECT_EQ(s->symbol(), p->builder().Symbols().Get("B"));
-  EXPECT_EQ(s->symbol(), p->builder().Symbols().Get("B"));
+  EXPECT_EQ(s->impl()->name(), p->builder().Symbols().Get("B"));
+  EXPECT_EQ(s->impl()->name(), p->builder().Symbols().Get("B"));
 }
 
 TEST_F(ParserImplTest, TypeDecl_MissingIdent) {
diff --git a/src/reader/wgsl/parser_impl_variable_ident_decl_test.cc b/src/reader/wgsl/parser_impl_variable_ident_decl_test.cc
index 6719ade..f1dfa4b 100644
--- a/src/reader/wgsl/parser_impl_variable_ident_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_variable_ident_decl_test.cc
@@ -116,7 +116,7 @@
   decos.push_back(block_deco);
 
   auto* str = create<ast::Struct>(Sym("S"), members, decos);
-  auto* s = ty.struct_("S", str);
+  auto* s = ty.struct_(str);
 
   p->register_constructed("S", s);
 
@@ -141,7 +141,7 @@
   decos.push_back(block_deco);
 
   auto* str = create<ast::Struct>(Sym("S"), members, decos);
-  auto* s = ty.struct_("S", str);
+  auto* s = ty.struct_(str);
 
   p->register_constructed("S", s);
 
@@ -166,7 +166,7 @@
   decos.push_back(block_deco);
 
   auto* str = create<ast::Struct>(Sym("S"), members, decos);
-  auto* s = ty.struct_("S", str);
+  auto* s = ty.struct_(str);
 
   p->register_constructed("S", s);
 
@@ -188,7 +188,7 @@
   decos.push_back(block_deco);
 
   auto* str = create<ast::Struct>(Sym("S"), members, decos);
-  auto* s = ty.struct_("S", str);
+  auto* s = ty.struct_(str);
 
   p->register_constructed("S", s);
 
@@ -226,7 +226,7 @@
   decos.push_back(block_deco);
 
   auto* str = create<ast::Struct>(Sym("S"), members, decos);
-  auto* s = ty.struct_("S", str);
+  auto* s = ty.struct_(str);
 
   p->register_constructed("S", s);
 
diff --git a/src/resolver/decoration_validation_test.cc b/src/resolver/decoration_validation_test.cc
index b60a95d..a58f544 100644
--- a/src/resolver/decoration_validation_test.cc
+++ b/src/resolver/decoration_validation_test.cc
@@ -133,7 +133,7 @@
   auto* s = create<ast::Struct>(
       Sym("mystruct"), members,
       ast::DecorationList{create<ast::StructBlockDecoration>()});
-  auto* s_ty = ty.struct_("mystruct", s);
+  auto* s_ty = ty.struct_(s);
   AST().AddConstructedType(s_ty);
 
   WrapInFunction();
@@ -170,7 +170,7 @@
   auto* s = create<ast::Struct>(Sym("mystruct"), ast::StructMemberList{},
                                 ast::DecorationList{createDecoration(
                                     Source{{12, 34}}, *this, params.kind)});
-  auto* s_ty = ty.struct_("mystruct", s);
+  auto* s_ty = ty.struct_(s);
   AST().AddConstructedType(s_ty);
 
   WrapInFunction();
@@ -210,7 +210,7 @@
                  createDecoration(Source{{12, 34}}, *this, params.kind)})};
   auto* s =
       create<ast::Struct>(Sym("mystruct"), members, ast::DecorationList{});
-  auto* s_ty = ty.struct_("mystruct", s);
+  auto* s_ty = ty.struct_(s);
   AST().AddConstructedType(s_ty);
 
   WrapInFunction();
diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc
index 424c73e..dfcb456 100644
--- a/src/resolver/resolver.cc
+++ b/src/resolver/resolver.cc
@@ -2009,12 +2009,12 @@
           return false;
         }
         if (!st->IsBlockDecorated()) {
-          diagnostics_.add_error("v-0015",
-                                 "a struct containing a runtime-sized array "
-                                 "requires the [[block]] attribute: '" +
-                                     builder_->Symbols().NameFor(st->symbol()) +
-                                     "'",
-                                 member->source());
+          diagnostics_.add_error(
+              "v-0015",
+              "a struct containing a runtime-sized array "
+              "requires the [[block]] attribute: '" +
+                  builder_->Symbols().NameFor(st->impl()->name()) + "'",
+              member->source());
           return false;
         }
 
diff --git a/src/resolver/resolver_test.cc b/src/resolver/resolver_test.cc
index 23bede2..028d51a 100644
--- a/src/resolver/resolver_test.cc
+++ b/src/resolver/resolver_test.cc
@@ -894,7 +894,7 @@
                             Member("second_member", ty.f32())},
       ast::DecorationList{});
 
-  auto* st = ty.struct_("S", strct);
+  auto* st = ty.struct_(strct);
   Global("my_struct", st, ast::StorageClass::kInput);
 
   auto* mem = MemberAccessor("my_struct", "second_member");
@@ -924,7 +924,7 @@
                             Member("second_member", ty.f32())},
       ast::DecorationList{});
 
-  auto* st = ty.struct_("alias", strct);
+  auto* st = ty.struct_(strct);
   auto* alias = ty.alias("alias", st);
   Global("my_struct", alias, ast::StorageClass::kInput);
 
@@ -1004,14 +1004,14 @@
   auto* strctB = create<ast::Struct>(
       Sym("B"), ast::StructMemberList{Member("foo", ty.vec4<f32>())},
       ast::DecorationList{});
-  auto* stB = ty.struct_("B", strctB);
+  auto* stB = ty.struct_(strctB);
 
   sem::Vector vecB(stB, 3);
   auto* strctA =
       create<ast::Struct>(Sym("A"), ast::StructMemberList{Member("mem", &vecB)},
                           ast::DecorationList{});
 
-  auto* stA = ty.struct_("A", strctA);
+  auto* stA = ty.struct_(strctA);
   Global("c", stA, ast::StorageClass::kInput);
 
   auto* mem = MemberAccessor(
@@ -1035,7 +1035,7 @@
                             Member("second_member", ty.f32())},
       ast::DecorationList{});
 
-  auto* st = ty.struct_("S", strct);
+  auto* st = ty.struct_(strct);
   Global("my_struct", st, ast::StorageClass::kInput);
 
   auto* expr = Add(MemberAccessor("my_struct", "first_member"),
diff --git a/src/resolver/type_validation_test.cc b/src/resolver/type_validation_test.cc
index 49aeb13..b8de796 100644
--- a/src/resolver/type_validation_test.cc
+++ b/src/resolver/type_validation_test.cc
@@ -320,7 +320,7 @@
                                                 Member("rt", ty.array<f32>())},
                           decos);
 
-  auto* struct_type = ty.struct_("Foo", st);
+  auto* struct_type = ty.struct_(st);
   AST().AddConstructedType(struct_type);
 
   WrapInFunction();
@@ -341,7 +341,7 @@
                             Member(Source{{12, 34}}, "rt", ty.array<f32>())},
       decos);
 
-  auto* struct_type = ty.struct_("Foo", st);
+  auto* struct_type = ty.struct_(st);
   AST().AddConstructedType(struct_type);
 
   WrapInFunction();
@@ -366,7 +366,7 @@
   auto* st = create<ast::Struct>(
       Sym("Foo"), ast::StructMemberList{rt, Member("vf", ty.f32())}, decos);
 
-  auto* struct_type = ty.struct_("Foo", st);
+  auto* struct_type = ty.struct_(st);
 
   AST().AddConstructedType(struct_type);
 
@@ -445,7 +445,7 @@
                             Member("a", ty.u32())},
       decos);
 
-  auto* struct_type = ty.struct_("s", st);
+  auto* struct_type = ty.struct_(st);
   AST().AddConstructedType(struct_type);
 
   WrapInFunction();
@@ -473,7 +473,7 @@
       Sym("s"),
       ast::StructMemberList{Member("a", ty.u32()), Member("b", alias)}, decos);
 
-  auto* struct_type = ty.struct_("s", st);
+  auto* struct_type = ty.struct_(st);
   AST().AddConstructedType(struct_type);
 
   WrapInFunction();
diff --git a/src/sem/struct_type.cc b/src/sem/struct_type.cc
index 1079b16..403d421 100644
--- a/src/sem/struct_type.cc
+++ b/src/sem/struct_type.cc
@@ -23,26 +23,24 @@
 namespace tint {
 namespace sem {
 
-StructType::StructType(const Symbol& sym, ast::Struct* impl)
-    : symbol_(sym), struct_(impl) {}
+StructType::StructType(ast::Struct* impl) : struct_(impl) {}
 
 StructType::StructType(StructType&&) = default;
 
 StructType::~StructType() = default;
 
 std::string StructType::type_name() const {
-  return "__struct_" + symbol_.to_str();
+  return impl()->type_name();
 }
 
 std::string StructType::FriendlyName(const SymbolTable& symbols) const {
-  return symbols.NameFor(symbol_);
+  return impl()->FriendlyName(symbols);
 }
 
 StructType* StructType::Clone(CloneContext* ctx) const {
   // Clone arguments outside of create() call to have deterministic ordering
-  auto sym = ctx->Clone(symbol());
   auto* str = ctx->Clone(impl());
-  return ctx->dst->create<StructType>(sym, str);
+  return ctx->dst->create<StructType>(str);
 }
 
 }  // namespace sem
diff --git a/src/sem/struct_type.h b/src/sem/struct_type.h
index 67857d5..6165b5e 100644
--- a/src/sem/struct_type.h
+++ b/src/sem/struct_type.h
@@ -27,16 +27,12 @@
 class StructType : public Castable<StructType, Type> {
  public:
   /// Constructor
-  /// @param sym the symbol representing the struct
   /// @param impl the struct data
-  StructType(const Symbol& sym, ast::Struct* impl);
+  explicit StructType(ast::Struct* impl);
   /// Move constructor
   StructType(StructType&&);
   ~StructType() override;
 
-  /// @returns the struct symbol
-  const Symbol& symbol() const { return symbol_; }
-
   /// @returns true if the struct has a block decoration
   bool IsBlockDecorated() const { return struct_->IsBlockDecorated(); }
 
@@ -57,7 +53,6 @@
   StructType* Clone(CloneContext* ctx) const override;
 
  private:
-  Symbol const symbol_;
   ast::Struct* const struct_;
 
   uint64_t LargestMemberBaseAlignment(MemoryLayout mem_layout) const;
diff --git a/src/sem/struct_type_test.cc b/src/sem/struct_type_test.cc
index 0571c88..1e36821 100644
--- a/src/sem/struct_type_test.cc
+++ b/src/sem/struct_type_test.cc
@@ -27,7 +27,7 @@
   auto* impl =
       create<ast::Struct>(name, ast::StructMemberList{}, ast::DecorationList{});
   auto* ptr = impl;
-  auto* s = ty.struct_(name, impl);
+  auto* s = ty.struct_(impl);
   EXPECT_EQ(s->impl(), ptr);
 }
 
@@ -35,7 +35,7 @@
   auto name = Sym("S");
   auto* impl =
       create<ast::Struct>(name, ast::StructMemberList{}, ast::DecorationList{});
-  auto* s = ty.struct_(name, impl);
+  auto* s = ty.struct_(impl);
   sem::Type* ty = s;
   EXPECT_FALSE(ty->Is<AccessControl>());
   EXPECT_FALSE(ty->Is<Alias>());
@@ -56,7 +56,7 @@
   auto name = Sym("my_struct");
   auto* impl =
       create<ast::Struct>(name, ast::StructMemberList{}, ast::DecorationList{});
-  auto* s = ty.struct_(name, impl);
+  auto* s = ty.struct_(impl);
   EXPECT_EQ(s->type_name(), "__struct_$1");
 }
 
@@ -64,7 +64,7 @@
   auto name = Sym("my_struct");
   auto* impl =
       create<ast::Struct>(name, ast::StructMemberList{}, ast::DecorationList{});
-  auto* s = ty.struct_(name, impl);
+  auto* s = ty.struct_(impl);
   EXPECT_EQ(s->FriendlyName(Symbols()), "my_struct");
 }
 
diff --git a/src/transform/canonicalize_entry_point_io.cc b/src/transform/canonicalize_entry_point_io.cc
index 55b86d1..7e0e9b8 100644
--- a/src/transform/canonicalize_entry_point_io.cc
+++ b/src/transform/canonicalize_entry_point_io.cc
@@ -81,11 +81,11 @@
       }
 
       // Redeclare the struct.
-      auto new_struct_name = ctx.Clone(struct_ty->symbol());
-      auto* new_struct = ctx.dst->create<sem::StructType>(
-          new_struct_name, ctx.dst->create<ast::Struct>(
-                               new_struct_name, new_struct_members,
-                               ctx.Clone(struct_ty->impl()->decorations())));
+      auto new_struct_name = ctx.Clone(struct_ty->impl()->name());
+      auto* new_struct =
+          ctx.dst->create<sem::StructType>(ctx.dst->create<ast::Struct>(
+              new_struct_name, new_struct_members,
+              ctx.Clone(struct_ty->impl()->decorations())));
       ctx.Replace(struct_ty, new_struct);
     }
   }
@@ -176,10 +176,9 @@
 
       // Create the new struct type.
       auto in_struct_name = ctx.dst->Symbols().New();
-      auto* in_struct = ctx.dst->create<sem::StructType>(
-          in_struct_name,
-          ctx.dst->create<ast::Struct>(in_struct_name, new_struct_members,
-                                       ast::DecorationList{}));
+      auto* in_struct =
+          ctx.dst->create<sem::StructType>(ctx.dst->create<ast::Struct>(
+              in_struct_name, new_struct_members, ast::DecorationList{}));
       ctx.InsertBefore(ctx.src->AST().GlobalDeclarations(), func, in_struct);
 
       // Create a new function parameter using this struct type.
@@ -223,10 +222,9 @@
 
       // Create the new struct type.
       auto out_struct_name = ctx.dst->Symbols().New();
-      auto* out_struct = ctx.dst->create<sem::StructType>(
-          out_struct_name,
-          ctx.dst->create<ast::Struct>(out_struct_name, new_struct_members,
-                                       ast::DecorationList{}));
+      auto* out_struct =
+          ctx.dst->create<sem::StructType>(ctx.dst->create<ast::Struct>(
+              out_struct_name, new_struct_members, ast::DecorationList{}));
       ctx.InsertBefore(ctx.src->AST().GlobalDeclarations(), func, out_struct);
       new_ret_type = out_struct;
 
diff --git a/src/transform/spirv.cc b/src/transform/spirv.cc
index 09d7324..4061482 100644
--- a/src/transform/spirv.cc
+++ b/src/transform/spirv.cc
@@ -126,11 +126,11 @@
       }
 
       // Redeclare the struct.
-      auto new_struct_name = ctx.Clone(struct_ty->symbol());
-      auto* new_struct = ctx.dst->create<sem::StructType>(
-          new_struct_name, ctx.dst->create<ast::Struct>(
-                               new_struct_name, new_struct_members,
-                               ctx.Clone(struct_ty->impl()->decorations())));
+      auto new_struct_name = ctx.Clone(struct_ty->impl()->name());
+      auto* new_struct =
+          ctx.dst->create<sem::StructType>(ctx.dst->create<ast::Struct>(
+              new_struct_name, new_struct_members,
+              ctx.Clone(struct_ty->impl()->decorations())));
       ctx.Replace(struct_ty, new_struct);
     }
   }
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc
index 52cc06a..109b40a 100644
--- a/src/writer/hlsl/generator_impl.cc
+++ b/src/writer/hlsl/generator_impl.cc
@@ -221,7 +221,8 @@
     out << " " << builder_.Symbols().NameFor(alias->symbol()) << ";"
         << std::endl;
   } else if (auto* str = ty->As<sem::StructType>()) {
-    if (!EmitStructType(out, str, builder_.Symbols().NameFor(str->symbol()))) {
+    if (!EmitStructType(out, str,
+                        builder_.Symbols().NameFor(str->impl()->name()))) {
       return false;
     }
   } else {
@@ -1709,8 +1710,9 @@
 
     auto* type = var->Type()->UnwrapIfNeeded();
     if (auto* strct = type->As<sem::StructType>()) {
-      out << "ConstantBuffer<" << builder_.Symbols().NameFor(strct->symbol())
-          << "> " << builder_.Symbols().NameFor(decl->symbol())
+      out << "ConstantBuffer<"
+          << builder_.Symbols().NameFor(strct->impl()->name()) << "> "
+          << builder_.Symbols().NameFor(decl->symbol())
           << RegisterAndSpace('b', binding_point) << ";" << std::endl;
     } else {
       // TODO(dsinclair): There is outstanding spec work to require all uniform
@@ -2450,7 +2452,7 @@
     }
     out << "State";
   } else if (auto* str = type->As<sem::StructType>()) {
-    out << builder_.Symbols().NameFor(str->symbol());
+    out << builder_.Symbols().NameFor(str->impl()->name());
   } else if (auto* tex = type->As<sem::Texture>()) {
     auto* storage = tex->As<sem::StorageTexture>();
     auto* multism = tex->As<sem::MultisampledTexture>();
diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc
index 018d453..2af17d7 100644
--- a/src/writer/msl/generator_impl.cc
+++ b/src/writer/msl/generator_impl.cc
@@ -1950,7 +1950,7 @@
   } else if (auto* str = type->As<sem::StructType>()) {
     // The struct type emits as just the name. The declaration would be emitted
     // as part of emitting the constructed types.
-    out_ << program_->Symbols().NameFor(str->symbol());
+    out_ << program_->Symbols().NameFor(str->impl()->name());
   } else if (auto* tex = type->As<sem::Texture>()) {
     if (tex->Is<sem::DepthTexture>()) {
       out_ << "depth";
@@ -2046,7 +2046,7 @@
   // TODO(dsinclair): Block decoration?
   // if (str->impl()->decoration() != ast::Decoration::kNone) {
   // }
-  out_ << "struct " << program_->Symbols().NameFor(str->symbol()) << " {"
+  out_ << "struct " << program_->Symbols().NameFor(str->impl()->name()) << " {"
        << std::endl;
 
   auto* sem_str = program_->Sem().Get(str);
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc
index 610f9b5..8a401a0 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -3150,11 +3150,10 @@
   auto struct_id = result.to_i();
   auto* impl = struct_type->impl();
 
-  if (struct_type->symbol().IsValid()) {
-    push_debug(
-        spv::Op::OpName,
-        {Operand::Int(struct_id),
-         Operand::String(builder_.Symbols().NameFor(struct_type->symbol()))});
+  if (struct_type->impl()->name().IsValid()) {
+    push_debug(spv::Op::OpName, {Operand::Int(struct_id),
+                                 Operand::String(builder_.Symbols().NameFor(
+                                     struct_type->impl()->name()))});
   }
 
   OperandList ops;
diff --git a/src/writer/wgsl/generator_impl.cc b/src/writer/wgsl/generator_impl.cc
index 4f4dfaf..101d5da 100644
--- a/src/writer/wgsl/generator_impl.cc
+++ b/src/writer/wgsl/generator_impl.cc
@@ -433,7 +433,7 @@
   } else if (auto* str = type->As<sem::StructType>()) {
     // The struct, as a type, is just the name. We should have already emitted
     // the declaration through a call to |EmitStructType| earlier.
-    out_ << program_->Symbols().NameFor(str->symbol());
+    out_ << program_->Symbols().NameFor(str->impl()->name());
   } else if (auto* texture = type->As<sem::Texture>()) {
     out_ << "texture_";
     if (texture->Is<sem::DepthTexture>()) {
@@ -518,7 +518,7 @@
     program_->to_str(deco, out_, 0);
     out_ << "]]" << std::endl;
   }
-  out_ << "struct " << program_->Symbols().NameFor(str->symbol()) << " {"
+  out_ << "struct " << program_->Symbols().NameFor(str->impl()->name()) << " {"
        << std::endl;
 
   auto add_padding = [&](uint32_t size) {