瀏覽代碼

Track an interface type, not an interface ID, on an associated entity. (#4188)

This prepares us for modeling associated entities of parameterized
interfaces.

We don't use the interface parameters when type-checking `impl`s or uses
of interface members yet, but we do now check interface arguments during
`impl` lookup.
Richard Smith 1 年之前
父節點
當前提交
8a8c227163
共有 73 個文件被更改,包括 729 次插入166 次删除
  1. 2 2
      toolchain/check/context.cpp
  2. 1 1
      toolchain/check/context.h
  3. 2 2
      toolchain/check/eval.cpp
  4. 7 5
      toolchain/check/impl.cpp
  5. 3 16
      toolchain/check/import_ref.cpp
  6. 5 1
      toolchain/check/interface.cpp
  7. 10 12
      toolchain/check/member_access.cpp
  8. 1 1
      toolchain/check/testdata/function/builtin/method.carbon
  9. 2 2
      toolchain/check/testdata/function/builtin/no_prelude/call_from_operator.carbon
  10. 2 2
      toolchain/check/testdata/impl/compound.carbon
  11. 1 1
      toolchain/check/testdata/impl/extend_impl.carbon
  12. 1 1
      toolchain/check/testdata/impl/fail_call_invalid.carbon
  13. 2 2
      toolchain/check/testdata/impl/fail_extend_impl_forall.carbon
  14. 1 1
      toolchain/check/testdata/impl/fail_impl_as_scope.carbon
  15. 1 1
      toolchain/check/testdata/impl/fail_impl_bad_assoc_const.carbon
  16. 3 3
      toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon
  17. 1 1
      toolchain/check/testdata/impl/fail_todo_impl_assoc_const.carbon
  18. 1 1
      toolchain/check/testdata/impl/impl_as.carbon
  19. 1 1
      toolchain/check/testdata/impl/impl_forall.carbon
  20. 1 1
      toolchain/check/testdata/impl/lookup/alias.carbon
  21. 1 1
      toolchain/check/testdata/impl/lookup/fail_alias_impl_not_found.carbon
  22. 1 1
      toolchain/check/testdata/impl/lookup/fail_todo_undefined_impl.carbon
  23. 2 2
      toolchain/check/testdata/impl/lookup/import.carbon
  24. 1 1
      toolchain/check/testdata/impl/lookup/instance_method.carbon
  25. 2 2
      toolchain/check/testdata/impl/lookup/no_prelude/import.carbon
  26. 1 1
      toolchain/check/testdata/impl/no_prelude/basic.carbon
  27. 2 2
      toolchain/check/testdata/impl/no_prelude/import_self.carbon
  28. 571 0
      toolchain/check/testdata/impl/no_prelude/interface_args.carbon
  29. 1 1
      toolchain/check/testdata/impl/no_prelude/self_in_class.carbon
  30. 2 2
      toolchain/check/testdata/impl/no_prelude/self_in_signature.carbon
  31. 1 1
      toolchain/check/testdata/index/fail_negative_indexing.carbon
  32. 2 2
      toolchain/check/testdata/interface/assoc_const.carbon
  33. 1 1
      toolchain/check/testdata/interface/fail_assoc_const_bad_default.carbon
  34. 2 2
      toolchain/check/testdata/interface/fail_todo_assoc_const_default.carbon
  35. 2 2
      toolchain/check/testdata/interface/fail_todo_define_default_fn_inline.carbon
  36. 2 2
      toolchain/check/testdata/interface/fail_todo_define_default_fn_out_of_line.carbon
  37. 1 1
      toolchain/check/testdata/interface/no_prelude/basic.carbon
  38. 1 1
      toolchain/check/testdata/interface/no_prelude/default_fn.carbon
  39. 1 1
      toolchain/check/testdata/interface/no_prelude/fail_lookup_undefined.carbon
  40. 2 2
      toolchain/check/testdata/interface/no_prelude/fail_member_lookup.carbon
  41. 1 1
      toolchain/check/testdata/interface/no_prelude/fail_redeclare_member.carbon
  42. 1 1
      toolchain/check/testdata/interface/no_prelude/fail_todo_facet_lookup.carbon
  43. 2 2
      toolchain/check/testdata/interface/no_prelude/fail_todo_generic_default_fn.carbon
  44. 2 2
      toolchain/check/testdata/interface/no_prelude/fail_todo_modifiers.carbon
  45. 2 2
      toolchain/check/testdata/interface/no_prelude/generic.carbon
  46. 3 3
      toolchain/check/testdata/interface/no_prelude/generic_binding_after_assoc_const.carbon
  47. 4 4
      toolchain/check/testdata/interface/no_prelude/generic_import.carbon
  48. 8 8
      toolchain/check/testdata/interface/no_prelude/import.carbon
  49. 1 1
      toolchain/check/testdata/interface/no_prelude/self.carbon
  50. 4 4
      toolchain/check/testdata/interface/todo_define_not_default.carbon
  51. 1 1
      toolchain/check/testdata/operators/builtin/fail_type_mismatch_once.carbon
  52. 1 1
      toolchain/check/testdata/operators/builtin/fail_unimplemented_op.carbon
  53. 2 2
      toolchain/check/testdata/operators/overloaded/add.carbon
  54. 2 2
      toolchain/check/testdata/operators/overloaded/bit_and.carbon
  55. 1 1
      toolchain/check/testdata/operators/overloaded/bit_complement.carbon
  56. 2 2
      toolchain/check/testdata/operators/overloaded/bit_or.carbon
  57. 2 2
      toolchain/check/testdata/operators/overloaded/bit_xor.carbon
  58. 1 1
      toolchain/check/testdata/operators/overloaded/dec.carbon
  59. 2 2
      toolchain/check/testdata/operators/overloaded/div.carbon
  60. 6 6
      toolchain/check/testdata/operators/overloaded/eq.carbon
  61. 2 2
      toolchain/check/testdata/operators/overloaded/fail_assign_non_ref.carbon
  62. 4 4
      toolchain/check/testdata/operators/overloaded/fail_no_impl.carbon
  63. 2 2
      toolchain/check/testdata/operators/overloaded/fail_no_impl_for_arg.carbon
  64. 1 1
      toolchain/check/testdata/operators/overloaded/inc.carbon
  65. 2 2
      toolchain/check/testdata/operators/overloaded/left_shift.carbon
  66. 2 2
      toolchain/check/testdata/operators/overloaded/mod.carbon
  67. 2 2
      toolchain/check/testdata/operators/overloaded/mul.carbon
  68. 1 1
      toolchain/check/testdata/operators/overloaded/negate.carbon
  69. 8 8
      toolchain/check/testdata/operators/overloaded/ordered.carbon
  70. 2 2
      toolchain/check/testdata/operators/overloaded/right_shift.carbon
  71. 2 2
      toolchain/check/testdata/operators/overloaded/sub.carbon
  72. 5 4
      toolchain/sem_ir/file.cpp
  73. 1 1
      toolchain/sem_ir/typed_insts.h

+ 2 - 2
toolchain/check/context.cpp

@@ -1071,10 +1071,10 @@ auto Context::GetTupleType(llvm::ArrayRef<SemIR::TypeId> type_ids)
                                        type_blocks().AddCanonical(type_ids));
 }
 
-auto Context::GetAssociatedEntityType(SemIR::InterfaceId interface_id,
+auto Context::GetAssociatedEntityType(SemIR::TypeId interface_type_id,
                                       SemIR::TypeId entity_type_id)
     -> SemIR::TypeId {
-  return GetTypeImpl<SemIR::AssociatedEntityType>(*this, interface_id,
+  return GetTypeImpl<SemIR::AssociatedEntityType>(*this, interface_type_id,
                                                   entity_type_id);
 }
 

+ 1 - 1
toolchain/check/context.h

@@ -284,7 +284,7 @@ class Context {
   // TODO: Consider moving these `Get*Type` functions to a separate class.
 
   // Gets the type for the name of an associated entity.
-  auto GetAssociatedEntityType(SemIR::InterfaceId interface_id,
+  auto GetAssociatedEntityType(SemIR::TypeId interface_type_id,
                                SemIR::TypeId entity_type_id) -> SemIR::TypeId;
 
   // Gets a builtin type. The returned type will be complete.

+ 2 - 2
toolchain/check/eval.cpp

@@ -1190,10 +1190,10 @@ auto TryEvalInstInContext(EvalContext& eval_context, SemIR::InstId inst_id,
     case SemIR::AssociatedEntity::Kind:
       return RebuildIfFieldsAreConstant(eval_context, inst,
                                         &SemIR::AssociatedEntity::type_id);
-
     case SemIR::AssociatedEntityType::Kind:
       return RebuildIfFieldsAreConstant(
-          eval_context, inst, &SemIR::AssociatedEntityType::entity_type_id);
+          eval_context, inst, &SemIR::AssociatedEntityType::interface_type_id,
+          &SemIR::AssociatedEntityType::entity_type_id);
     case SemIR::BoundMethod::Kind:
       return RebuildIfFieldsAreConstant(
           eval_context, inst, &SemIR::BoundMethod::type_id,

+ 7 - 5
toolchain/check/impl.cpp

@@ -63,16 +63,17 @@ static auto CheckAssociatedFunctionImplementation(
 
 // Builds a witness that the specified impl implements the given interface.
 static auto BuildInterfaceWitness(
-    Context& context, const SemIR::Impl& impl, SemIR::InterfaceId interface_id,
+    Context& context, const SemIR::Impl& impl,
+    SemIR::InterfaceType interface_type,
     llvm::SmallVectorImpl<SemIR::InstId>& used_decl_ids) -> SemIR::InstId {
-  const auto& interface = context.interfaces().Get(interface_id);
+  const auto& interface = context.interfaces().Get(interface_type.interface_id);
   if (!interface.is_defined()) {
     CARBON_DIAGNOSTIC(ImplOfUndefinedInterface, Error,
                       "Implementation of undefined interface {0}.",
                       SemIR::NameId);
     auto builder = context.emitter().Build(
         impl.definition_id, ImplOfUndefinedInterface, interface.name_id);
-    context.NoteUndefinedInterface(interface_id, builder);
+    context.NoteUndefinedInterface(interface_type.interface_id, builder);
     builder.Emit();
     return SemIR::InstId::BuiltinError;
   }
@@ -85,6 +86,7 @@ static auto BuildInterfaceWitness(
   table.reserve(assoc_entities.size());
 
   // Substitute `Self` with the impl's self type when associated functions.
+  // TODO: Also substitute the arguments from interface_type.specific_id.
   auto self_bind =
       context.insts().GetAs<SemIR::BindSymbolicName>(interface.self_param_id);
   Substitution substitutions[1] = {
@@ -160,8 +162,8 @@ auto BuildImplWitness(Context& context, SemIR::ImplId impl_id)
 
   llvm::SmallVector<SemIR::InstId> used_decl_ids;
 
-  auto witness_id = BuildInterfaceWitness(
-      context, impl, interface_type->interface_id, used_decl_ids);
+  auto witness_id =
+      BuildInterfaceWitness(context, impl, *interface_type, used_decl_ids);
 
   // TODO: Diagnose if any declarations in the impl are not in used_decl_ids.
 

+ 3 - 16
toolchain/check/import_ref.cpp

@@ -1059,28 +1059,15 @@ class ImportRefResolver {
 
     auto initial_work = work_stack_.size();
     auto entity_type_const_id = GetLocalConstantId(inst.entity_type_id);
-    auto interface_inst_id = GetLocalConstantInstId(
-        import_ir_.interfaces().Get(inst.interface_id).decl_id);
+    auto interface_inst_id = GetLocalConstantId(inst.interface_type_id);
     if (HasNewWork(initial_work)) {
       return ResolveResult::Retry();
     }
 
-    // TODO: Track an interface type, not an interface ID, on
-    // AssociatedEntityType.
-    auto interface_inst = context_.insts().Get(interface_inst_id);
-    SemIR::InterfaceId interface_id = SemIR::InterfaceId::Invalid;
-    if (interface_inst.Is<SemIR::InterfaceType>()) {
-      interface_id = interface_inst.As<SemIR::InterfaceType>().interface_id;
-    } else {
-      interface_id =
-          context_.types()
-              .GetAs<SemIR::GenericInterfaceType>(interface_inst.type_id())
-              .interface_id;
-    }
-
     return ResolveAs<SemIR::AssociatedEntityType>(
         {.type_id = SemIR::TypeId::TypeType,
-         .interface_id = interface_id,
+         .interface_type_id =
+             context_.GetTypeIdForTypeConstant(interface_inst_id),
          .entity_type_id =
              context_.GetTypeIdForTypeConstant(entity_type_const_id)});
   }

+ 5 - 1
toolchain/check/interface.cpp

@@ -21,6 +21,10 @@ auto BuildAssociatedEntity(Context& context, SemIR::InterfaceId interface_id,
     return SemIR::InstId::BuiltinError;
   }
 
+  // The interface type is the type of `Self`.
+  auto self_type_id =
+      context.insts().Get(interface_info.self_param_id).type_id();
+
   // Register this declaration as declaring an associated entity.
   auto index = SemIR::ElementIndex(
       context.args_type_info_stack().PeekCurrentBlockContents().size());
@@ -29,7 +33,7 @@ auto BuildAssociatedEntity(Context& context, SemIR::InterfaceId interface_id,
   // Name lookup for the declaration's name should name the associated entity,
   // not the declaration itself.
   auto type_id = context.GetAssociatedEntityType(
-      interface_id, context.insts().Get(decl_id).type_id());
+      self_type_id, context.insts().Get(decl_id).type_id());
   return context.AddInst<SemIR::AssociatedEntity>(
       context.insts().GetLocId(decl_id),
       {.type_id = type_id, .index = index, .decl_id = decl_id});

+ 10 - 12
toolchain/check/member_access.cpp

@@ -128,7 +128,7 @@ static auto ScopeNeedsImplLookup(Context& context, LookupScope scope) -> bool {
 // Returns an invalid InstId if no matching impl is found.
 static auto LookupInterfaceWitness(Context& context,
                                    SemIR::ConstantId type_const_id,
-                                   SemIR::InterfaceId interface_id)
+                                   SemIR::TypeId interface_type_id)
     -> SemIR::InstId {
   // TODO: Add a better impl lookup system. At the very least, we should only be
   // considering impls that are for the same interface we're querying. We can
@@ -138,16 +138,11 @@ static auto LookupInterfaceWitness(Context& context,
             context.types().GetConstantId(impl.self_id), type_const_id)) {
       continue;
     }
-    auto interface_type =
-        context.types().TryGetAs<SemIR::InterfaceType>(impl.constraint_id);
-    if (!interface_type) {
+    if (impl.constraint_id != interface_type_id) {
       // TODO: An impl of a constraint type should be treated as implementing
       // the constraint's interfaces.
       continue;
     }
-    if (interface_type->interface_id != interface_id) {
-      continue;
-    }
     if (!impl.witness_id.is_valid()) {
       // TODO: Diagnose if the impl isn't defined yet?
       return SemIR::InstId::Invalid;
@@ -164,9 +159,11 @@ static auto PerformImplLookup(Context& context, Parse::NodeId node_id,
                               SemIR::ConstantId type_const_id,
                               SemIR::AssociatedEntityType assoc_type,
                               SemIR::InstId member_id) -> SemIR::InstId {
-  auto& interface = context.interfaces().Get(assoc_type.interface_id);
-  auto witness_id =
-      LookupInterfaceWitness(context, type_const_id, assoc_type.interface_id);
+  auto interface_type =
+      context.types().GetAs<SemIR::InterfaceType>(assoc_type.interface_type_id);
+  auto& interface = context.interfaces().Get(interface_type.interface_id);
+  auto witness_id = LookupInterfaceWitness(context, type_const_id,
+                                           assoc_type.interface_type_id);
   if (!witness_id.is_valid()) {
     CARBON_DIAGNOSTIC(MissingImplInMemberAccess, Error,
                       "Cannot access member of interface {0} in type {1} "
@@ -194,6 +191,7 @@ static auto PerformImplLookup(Context& context, Parse::NodeId node_id,
   }
 
   // Substitute into the type declared in the interface.
+  // TODO: Also substitute the arguments from interface_type.specific_id.
   auto self_param =
       context.insts().GetAs<SemIR::BindSymbolicName>(interface.self_param_id);
   Substitution substitutions[1] = {
@@ -252,8 +250,8 @@ static auto LookupMemberNameInScope(Context& context, Parse::NodeId node_id,
   // TODO: We need to do this as part of searching extended scopes, because a
   // lookup that finds an associated entity and also finds the corresponding
   // impl member is not supposed to be treated as ambiguous.
-  if (auto assoc_type = context.types().TryGetAs<SemIR::AssociatedEntityType>(
-          inst.type_id())) {
+  if (auto assoc_type =
+          context.types().TryGetAs<SemIR::AssociatedEntityType>(type_id)) {
     if (ScopeNeedsImplLookup(context, lookup_scope)) {
       member_id = PerformImplLookup(context, node_id, name_scope_const_id,
                                     *assoc_type, member_id);

+ 1 - 1
toolchain/check/testdata/function/builtin/method.carbon

@@ -26,7 +26,7 @@ var arr: [i32; 1.(I.F)(2)];
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @I, %F.type.1 [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type.1 [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @I.%F.decl [template]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]

+ 2 - 2
toolchain/check/testdata/function/builtin/no_prelude/call_from_operator.carbon

@@ -40,7 +40,7 @@ var arr: [i32; 1 + 2] = (3, 4, 3 + 4);
 // CHECK:STDOUT:   %Self: %.2 = bind_symbolic_name Self 0 [symbolic]
 // CHECK:STDOUT:   %Op.type: type = fn_type @Op [template]
 // CHECK:STDOUT:   %Op: %Op.type = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @Add, %Op.type [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.2, %Op.type [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @Add.%Op.decl [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -108,7 +108,7 @@ var arr: [i32; 1 + 2] = (3, 4, 3 + 4);
 // CHECK:STDOUT:   %.3: <witness> = interface_witness (%Op.1) [template]
 // CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
 // CHECK:STDOUT:   %.5: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.6: type = assoc_entity_type @Add, %Op.type.2 [template]
+// CHECK:STDOUT:   %.6: type = assoc_entity_type %.2, %Op.type.2 [template]
 // CHECK:STDOUT:   %.7: %.6 = assoc_entity element0, imports.%import_ref.6 [template]
 // CHECK:STDOUT:   %.8: <bound method> = bound_method %.4, %Op.1 [template]
 // CHECK:STDOUT:   %.9: i32 = int_literal 3 [template]

+ 2 - 2
toolchain/check/testdata/impl/compound.carbon

@@ -42,11 +42,11 @@ fn InstanceCallIndirect(p: i32*) {
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @Simple, %F.type.1 [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type.1 [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @Simple.%F.decl [template]
 // CHECK:STDOUT:   %G.type.1: type = fn_type @G.1 [template]
 // CHECK:STDOUT:   %G.1: %G.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.5: type = assoc_entity_type @Simple, %G.type.1 [template]
+// CHECK:STDOUT:   %.5: type = assoc_entity_type %.1, %G.type.1 [template]
 // CHECK:STDOUT:   %.6: %.5 = assoc_entity element1, @Simple.%G.decl [template]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]

+ 1 - 1
toolchain/check/testdata/impl/extend_impl.carbon

@@ -31,7 +31,7 @@ fn G(c: C) {
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @HasF, %F.type.1 [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type.1 [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @HasF.%F.decl [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %F.type.2: type = fn_type @F.2 [template]

+ 1 - 1
toolchain/check/testdata/impl/fail_call_invalid.carbon

@@ -31,7 +31,7 @@ fn InstanceCall(n: i32) {
 // CHECK:STDOUT:   %G.type.1: type = fn_type @G.1 [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %G.1: %G.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @Simple, %G.type.1 [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %G.type.1 [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @Simple.%G.decl [template]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]

+ 2 - 2
toolchain/check/testdata/impl/fail_extend_impl_forall.carbon

@@ -32,7 +32,7 @@ class C {
 // CHECK:STDOUT:   %Self: %.2 = bind_symbolic_name Self 1 [symbolic]
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1, @GenericInterface(%T) [symbolic]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [symbolic]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @GenericInterface, %F.type.1 [symbolic]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.2, %F.type.1 [symbolic]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @GenericInterface.%F.decl [symbolic]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %F.type.2: type = fn_type @F.2 [template]
@@ -75,7 +75,7 @@ class C {
 // CHECK:STDOUT:   %Self.2: %.2 = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self)]
 // CHECK:STDOUT:   %F.type: type = fn_type @F.1, @GenericInterface(%T) [symbolic = %F.type (constants.%F.type.1)]
 // CHECK:STDOUT:   %F: @GenericInterface.%F.type (%F.type.1) = struct_value () [symbolic = %F (constants.%F.1)]
-// CHECK:STDOUT:   %.2: type = assoc_entity_type @GenericInterface, @GenericInterface.%F.type (%F.type.1) [symbolic = %.2 (constants.%.3)]
+// CHECK:STDOUT:   %.2: type = assoc_entity_type @GenericInterface.%.1 (%.2), @GenericInterface.%F.type (%F.type.1) [symbolic = %.2 (constants.%.3)]
 // CHECK:STDOUT:   %.3: @GenericInterface.%.2 (%.3) = assoc_entity element0, %F.decl [symbolic = %.3 (constants.%.4)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {

+ 1 - 1
toolchain/check/testdata/impl/fail_impl_as_scope.carbon

@@ -27,7 +27,7 @@ impl as Simple {
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @Simple, %F.type.1 [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type.1 [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @Simple.%F.decl [template]
 // CHECK:STDOUT:   %F.type.2: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.2: %F.type.2 = struct_value () [template]

+ 1 - 1
toolchain/check/testdata/impl/fail_impl_bad_assoc_const.carbon

@@ -20,7 +20,7 @@ impl bool as I {}
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %.1: type = interface_type @I [template]
 // CHECK:STDOUT:   %Self: %.1 = bind_symbolic_name Self 0 [symbolic]
-// CHECK:STDOUT:   %.2: type = assoc_entity_type @I, type [template]
+// CHECK:STDOUT:   %.2: type = assoc_entity_type %.1, type [template]
 // CHECK:STDOUT:   %.3: %.2 = assoc_entity element0, @I.%T [template]
 // CHECK:STDOUT:   %Bool.type: type = fn_type @Bool [template]
 // CHECK:STDOUT:   %.4: type = tuple_type () [template]

+ 3 - 3
toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon

@@ -221,7 +221,7 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @I, %F.type.1 [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type.1 [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @I.%F.decl [template]
 // CHECK:STDOUT:   %NoF: type = class_type @NoF [template]
 // CHECK:STDOUT:   %.5: type = struct_type {} [template]
@@ -245,7 +245,7 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT:   %Self.2: %.6 = bind_symbolic_name Self 0 [symbolic]
 // CHECK:STDOUT:   %F.type.5: type = fn_type @F.5 [template]
 // CHECK:STDOUT:   %F.6: %F.type.5 = struct_value () [template]
-// CHECK:STDOUT:   %.7: type = assoc_entity_type @J, %F.type.5 [template]
+// CHECK:STDOUT:   %.7: type = assoc_entity_type %.6, %F.type.5 [template]
 // CHECK:STDOUT:   %.8: %.7 = assoc_entity element0, @J.%F.decl [template]
 // CHECK:STDOUT:   %FMissingParam: type = class_type @FMissingParam [template]
 // CHECK:STDOUT:   %F.type.6: type = fn_type @F.6 [template]
@@ -280,7 +280,7 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT:   %.15: type = array_type %.14, %Self.3 [symbolic]
 // CHECK:STDOUT:   %F.type.13: type = fn_type @F.13 [template]
 // CHECK:STDOUT:   %F.14: %F.type.13 = struct_value () [template]
-// CHECK:STDOUT:   %.16: type = assoc_entity_type @SelfNested, %F.type.13 [template]
+// CHECK:STDOUT:   %.16: type = assoc_entity_type %.9, %F.type.13 [template]
 // CHECK:STDOUT:   %.17: %.16 = assoc_entity element0, @SelfNested.%F.decl [template]
 // CHECK:STDOUT:   %SelfNestedBadParam: type = class_type @SelfNestedBadParam [template]
 // CHECK:STDOUT:   %.18: type = ptr_type %SelfNestedBadParam [template]

+ 1 - 1
toolchain/check/testdata/impl/fail_todo_impl_assoc_const.carbon

@@ -20,7 +20,7 @@ impl bool as I where .T = bool {}
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %.1: type = interface_type @I [template]
 // CHECK:STDOUT:   %Self: %.1 = bind_symbolic_name Self 0 [symbolic]
-// CHECK:STDOUT:   %.2: type = assoc_entity_type @I, type [template]
+// CHECK:STDOUT:   %.2: type = assoc_entity_type %.1, type [template]
 // CHECK:STDOUT:   %.3: %.2 = assoc_entity element0, @I.%T [template]
 // CHECK:STDOUT:   %Bool.type: type = fn_type @Bool [template]
 // CHECK:STDOUT:   %.4: type = tuple_type () [template]

+ 1 - 1
toolchain/check/testdata/impl/impl_as.carbon

@@ -29,7 +29,7 @@ class C {
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @Simple, %F.type.1 [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type.1 [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @Simple.%F.decl [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %F.type.2: type = fn_type @F.2 [template]

+ 1 - 1
toolchain/check/testdata/impl/impl_forall.carbon

@@ -24,7 +24,7 @@ impl forall [T:! type] T as Simple {
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @Simple, %F.type.1 [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type.1 [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @Simple.%F.decl [template]
 // CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic]
 // CHECK:STDOUT:   %F.type.2: type = fn_type @F.2 [template]

+ 1 - 1
toolchain/check/testdata/impl/lookup/alias.carbon

@@ -33,7 +33,7 @@ fn G(c: C) {
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @HasF, %F.type.1 [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type.1 [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @HasF.%F.decl [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %.5: type = struct_type {} [template]

+ 1 - 1
toolchain/check/testdata/impl/lookup/fail_alias_impl_not_found.carbon

@@ -36,7 +36,7 @@ fn F(c: C) {
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @I, %F.type.1 [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type.1 [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @I.%F.decl [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %.5: type = struct_type {} [template]

+ 1 - 1
toolchain/check/testdata/impl/lookup/fail_todo_undefined_impl.carbon

@@ -36,7 +36,7 @@ impl C as I {
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @I, %F.type.1 [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type.1 [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @I.%F.decl [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %.5: type = struct_type {} [template]

+ 2 - 2
toolchain/check/testdata/impl/lookup/import.carbon

@@ -38,7 +38,7 @@ fn G(c: Impl.C) {
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @HasF, %F.type.1 [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type.1 [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @HasF.%F.decl [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %.5: type = struct_type {} [template]
@@ -124,7 +124,7 @@ fn G(c: Impl.C) {
 // CHECK:STDOUT:   %.4: type = ptr_type %.1 [template]
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.5: type = assoc_entity_type @HasF, %F.type.1 [template]
+// CHECK:STDOUT:   %.5: type = assoc_entity_type %.2, %F.type.1 [template]
 // CHECK:STDOUT:   %.6: %.5 = assoc_entity element0, imports.%import_ref.8 [template]
 // CHECK:STDOUT:   %F.type.2: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.2: %F.type.2 = struct_value () [template]

+ 1 - 1
toolchain/check/testdata/impl/lookup/instance_method.carbon

@@ -35,7 +35,7 @@ fn F(c: C) -> i32 {
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @I, %F.type.1 [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type.1 [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @I.%F.decl [template]
 // CHECK:STDOUT:   %F.type.2: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.2: %F.type.2 = struct_value () [template]

+ 2 - 2
toolchain/check/testdata/impl/lookup/no_prelude/import.carbon

@@ -38,7 +38,7 @@ fn G(c: Impl.C) {
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @HasF, %F.type.1 [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type.1 [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @HasF.%F.decl [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %.5: type = struct_type {} [template]
@@ -110,7 +110,7 @@ fn G(c: Impl.C) {
 // CHECK:STDOUT:   %.4: type = ptr_type %.1 [template]
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.5: type = assoc_entity_type @HasF, %F.type.1 [template]
+// CHECK:STDOUT:   %.5: type = assoc_entity_type %.2, %F.type.1 [template]
 // CHECK:STDOUT:   %.6: %.5 = assoc_entity element0, imports.%import_ref.8 [template]
 // CHECK:STDOUT:   %F.type.2: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.2: %F.type.2 = struct_value () [template]

+ 1 - 1
toolchain/check/testdata/impl/no_prelude/basic.carbon

@@ -26,7 +26,7 @@ impl C as Simple {
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @Simple, %F.type.1 [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type.1 [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @Simple.%F.decl [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %.5: type = struct_type {} [template]

+ 2 - 2
toolchain/check/testdata/impl/no_prelude/import_self.carbon

@@ -38,7 +38,7 @@ fn F(x: (), y: ()) -> () {
 // CHECK:STDOUT:   %Op.type: type = fn_type @Op [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %Op: %Op.type = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @Add, %Op.type [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %Op.type [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @Add.%Op.decl [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -99,7 +99,7 @@ fn F(x: (), y: ()) -> () {
 // CHECK:STDOUT:   %tuple: %.1 = tuple_value () [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.4: type = assoc_entity_type @Add, %Op.type.2 [template]
+// CHECK:STDOUT:   %.4: type = assoc_entity_type %.2, %Op.type.2 [template]
 // CHECK:STDOUT:   %.5: %.4 = assoc_entity element0, imports.%import_ref.5 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 571 - 0
toolchain/check/testdata/impl/no_prelude/interface_args.carbon

@@ -0,0 +1,571 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// AUTOUPDATE
+// TIP: To test this file alone, run:
+// TIP:   bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/impl/no_prelude/interface_args.carbon
+// TIP: To dump output, run:
+// TIP:   bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/no_prelude/interface_args.carbon
+
+// --- action.carbon
+
+library "action";
+
+interface Action(T:! type) {
+  fn Op();
+}
+
+class A {}
+class B {}
+class C {}
+
+impl A as Action(B) {
+  fn Op() {}
+}
+
+// --- action.impl.carbon
+
+impl library "action";
+
+fn F(a: A) { a.(Action(B).Op)(); }
+
+// --- fail_action.impl.carbon
+
+impl library "action";
+
+// CHECK:STDERR: fail_action.impl.carbon:[[@LINE+4]]:14: ERROR: Cannot access member of interface Action in type A that does not implement that interface.
+// CHECK:STDERR: fn G(a: A) { a.(Action(C).Op)(); }
+// CHECK:STDERR:              ^~~~~~~~~~~~~~~~
+// CHECK:STDERR:
+fn G(a: A) { a.(Action(C).Op)(); }
+
+// --- fail_todo_factory.carbon
+
+library "fail_todo_factory";
+
+interface Factory(T:! type) {
+  fn Make() -> T;
+}
+
+class A {}
+class B {}
+
+impl A as Factory(B) {
+  // CHECK:STDERR: fail_todo_factory.carbon:[[@LINE+6]]:3: ERROR: Function redeclaration differs because return type is `B`.
+  // CHECK:STDERR:   fn Make() -> B;
+  // CHECK:STDERR:   ^~~~~~~~~~~~~~~
+  // CHECK:STDERR: fail_todo_factory.carbon:[[@LINE-10]]:3: Previously declared with return type `T`.
+  // CHECK:STDERR:   fn Make() -> T;
+  // CHECK:STDERR:   ^~~~~~~~~~~~~~~
+  fn Make() -> B;
+}
+
+// CHECK:STDOUT: --- action.carbon
+// CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic]
+// CHECK:STDOUT:   %Action.type: type = generic_interface_type @Action [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %Action: %Action.type = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = interface_type @Action, @Action(%T) [symbolic]
+// CHECK:STDOUT:   %Self: %.2 = bind_symbolic_name Self 1 [symbolic]
+// CHECK:STDOUT:   %Op.type.1: type = fn_type @Op.1, @Action(%T) [symbolic]
+// CHECK:STDOUT:   %Op.1: %Op.type.1 = struct_value () [symbolic]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.2, %Op.type.1 [symbolic]
+// CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @Action.%Op.decl [symbolic]
+// CHECK:STDOUT:   %A: type = class_type @A [template]
+// CHECK:STDOUT:   %.5: type = struct_type {} [template]
+// CHECK:STDOUT:   %B: type = class_type @B [template]
+// CHECK:STDOUT:   %C: type = class_type @C [template]
+// CHECK:STDOUT:   %.6: type = interface_type @Action, @Action(%B) [template]
+// CHECK:STDOUT:   %Op.type.2: type = fn_type @Op.2 [template]
+// CHECK:STDOUT:   %Op.2: %Op.type.2 = struct_value () [template]
+// CHECK:STDOUT:   %.7: <witness> = interface_witness (%Op.2) [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: file {
+// CHECK:STDOUT:   package: <namespace> = namespace [template] {
+// CHECK:STDOUT:     .Action = %Action.decl
+// CHECK:STDOUT:     .A = %A.decl
+// CHECK:STDOUT:     .B = %B.decl
+// CHECK:STDOUT:     .C = %C.decl
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Action.decl: %Action.type = interface_decl @Action [template = constants.%Action] {
+// CHECK:STDOUT:     %T.loc4_18.1: type = param T
+// CHECK:STDOUT:     %T.loc4_18.2: type = bind_symbolic_name T 0, %T.loc4_18.1 [symbolic = @Action.%T (constants.%T)]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %A.decl: type = class_decl @A [template = constants.%A] {}
+// CHECK:STDOUT:   %B.decl: type = class_decl @B [template = constants.%B] {}
+// CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
+// CHECK:STDOUT:   %.loc12_19.1: type = value_of_initializer %.loc12_17 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc12_19.2: type = converted %.loc12_17, %.loc12_19.1 [template = constants.%.6]
+// CHECK:STDOUT:   impl_decl @impl {
+// CHECK:STDOUT:     %A.ref: type = name_ref A, %A.decl [template = constants.%A]
+// CHECK:STDOUT:     %Action.ref: %Action.type = name_ref Action, %Action.decl [template = constants.%Action]
+// CHECK:STDOUT:     %B.ref: type = name_ref B, %B.decl [template = constants.%B]
+// CHECK:STDOUT:     %.loc12_17: init type = call %Action.ref(%B.ref) [template = constants.%.6]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic interface @Action(file.%T.loc4_18.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1: type = interface_type @Action, @Action(%T) [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:   %Self.2: %.2 = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self)]
+// CHECK:STDOUT:   %Op.type: type = fn_type @Op.1, @Action(%T) [symbolic = %Op.type (constants.%Op.type.1)]
+// CHECK:STDOUT:   %Op: @Action.%Op.type (%Op.type.1) = struct_value () [symbolic = %Op (constants.%Op.1)]
+// CHECK:STDOUT:   %.2: type = assoc_entity_type @Action.%.1 (%.2), @Action.%Op.type (%Op.type.1) [symbolic = %.2 (constants.%.3)]
+// CHECK:STDOUT:   %.3: @Action.%.2 (%.3) = assoc_entity element0, %Op.decl [symbolic = %.3 (constants.%.4)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   interface {
+// CHECK:STDOUT:     %Self.1: @Action.%.1 (%.2) = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self)]
+// CHECK:STDOUT:     %Op.decl: @Action.%Op.type (%Op.type.1) = fn_decl @Op.1 [symbolic = %Op (constants.%Op.1)] {}
+// CHECK:STDOUT:     %.loc5: @Action.%.2 (%.3) = assoc_entity element0, %Op.decl [symbolic = %.3 (constants.%.4)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = %Self.1
+// CHECK:STDOUT:     .Op = %.loc5
+// CHECK:STDOUT:     witness = (%Op.decl)
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: impl @impl: %A as %.6 {
+// CHECK:STDOUT:   %Op.decl: %Op.type.2 = fn_decl @Op.2 [template = constants.%Op.2] {}
+// CHECK:STDOUT:   %.1: <witness> = interface_witness (%Op.decl) [template = constants.%.7]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Op = %Op.decl
+// CHECK:STDOUT:   witness = %.1
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: class @A {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%A
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: class @B {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%B
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: class @C {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @Op.1(file.%T.loc4_18.2: type, @Action.%Self.1: @Action.%.1 (%.2)) {
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn();
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Op.2() {
+// CHECK:STDOUT: !entry:
+// CHECK:STDOUT:   return
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Action(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Op.1(constants.%T, constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Action(@Action.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Action(constants.%B) {
+// CHECK:STDOUT:   %T => constants.%B
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: --- action.impl.carbon
+// CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %A: type = class_type @A [template]
+// CHECK:STDOUT:   %.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %B: type = class_type @B [template]
+// CHECK:STDOUT:   %Action.type: type = generic_interface_type @Action [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %Action: %Action.type = struct_value () [template]
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic]
+// CHECK:STDOUT:   %.3: type = interface_type @Action, @Action(%T) [symbolic]
+// CHECK:STDOUT:   %Self: %.3 = bind_symbolic_name Self 1 [symbolic]
+// CHECK:STDOUT:   %Op.type.1: type = fn_type @Op.1 [template]
+// CHECK:STDOUT:   %Op.1: %Op.type.1 = struct_value () [template]
+// CHECK:STDOUT:   %Op.type.2: type = fn_type @Op.1, @Action(%T) [symbolic]
+// CHECK:STDOUT:   %.4: type = assoc_entity_type %.3, %Op.type.2 [symbolic]
+// CHECK:STDOUT:   %.5: %.4 = assoc_entity element0, imports.%import_ref.7 [symbolic]
+// CHECK:STDOUT:   %Op.2: %Op.type.2 = struct_value () [symbolic]
+// CHECK:STDOUT:   %.6: type = interface_type @Action, @Action(%B) [template]
+// CHECK:STDOUT:   %F.type: type = fn_type @F [template]
+// CHECK:STDOUT:   %F: %F.type = struct_value () [template]
+// CHECK:STDOUT:   %.7: type = ptr_type %.1 [template]
+// CHECK:STDOUT:   %Op.type.3: type = fn_type @Op.1, @Action(%B) [template]
+// CHECK:STDOUT:   %Op.3: %Op.type.3 = struct_value () [template]
+// CHECK:STDOUT:   %.8: type = assoc_entity_type %.6, %Op.type.3 [template]
+// CHECK:STDOUT:   %.9: %.8 = assoc_entity element0, imports.%import_ref.7 [template]
+// CHECK:STDOUT:   %.10: %.4 = assoc_entity element0, imports.%import_ref.12 [symbolic]
+// CHECK:STDOUT:   %Op.type.4: type = fn_type @Op.2 [template]
+// CHECK:STDOUT:   %Op.4: %Op.type.4 = struct_value () [template]
+// CHECK:STDOUT:   %.11: <witness> = interface_witness (%Op.4) [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT:   %import_ref.1: %Action.type = import_ref Main//action, inst+4, loaded [template = constants.%Action]
+// CHECK:STDOUT:   %import_ref.2: type = import_ref Main//action, inst+24, loaded [template = constants.%A]
+// CHECK:STDOUT:   %import_ref.3: type = import_ref Main//action, inst+27, loaded [template = constants.%B]
+// CHECK:STDOUT:   %import_ref.4 = import_ref Main//action, inst+29, unloaded
+// CHECK:STDOUT:   %import_ref.5 = import_ref Main//action, inst+25, unloaded
+// CHECK:STDOUT:   %import_ref.6 = import_ref Main//action, inst+28, unloaded
+// CHECK:STDOUT:   %import_ref.7 = import_ref Main//action, inst+12, unloaded
+// CHECK:STDOUT:   %import_ref.8 = import_ref Main//action, inst+10, unloaded
+// CHECK:STDOUT:   %import_ref.9: @Action.%.2 (%.4) = import_ref Main//action, inst+16, loaded [symbolic = @Action.%.3 (constants.%.10)]
+// CHECK:STDOUT:   %import_ref.10 = import_ref Main//action, inst+12, unloaded
+// CHECK:STDOUT:   %import_ref.11: <witness> = import_ref Main//action, inst+42, loaded [template = constants.%.11]
+// CHECK:STDOUT:   %import_ref.12 = import_ref Main//action, inst+12, unloaded
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: file {
+// CHECK:STDOUT:   package: <namespace> = namespace [template] {
+// CHECK:STDOUT:     .Action = imports.%import_ref.1
+// CHECK:STDOUT:     .A = imports.%import_ref.2
+// CHECK:STDOUT:     .B = imports.%import_ref.3
+// CHECK:STDOUT:     .C = imports.%import_ref.4
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %default.import.loc2_6.1 = import <invalid>
+// CHECK:STDOUT:   %default.import.loc2_6.2 = import <invalid>
+// CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
+// CHECK:STDOUT:     %A.ref: type = name_ref A, imports.%import_ref.2 [template = constants.%A]
+// CHECK:STDOUT:     %a.loc4_6.1: %A = param a
+// CHECK:STDOUT:     @F.%a: %A = bind_name a, %a.loc4_6.1
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic interface @Action(constants.%T: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1: type = interface_type @Action, @Action(%T) [symbolic = %.1 (constants.%.3)]
+// CHECK:STDOUT:   %Self: %.3 = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self)]
+// CHECK:STDOUT:   %Op.type: type = fn_type @Op.1, @Action(%T) [symbolic = %Op.type (constants.%Op.type.2)]
+// CHECK:STDOUT:   %Op: @Action.%Op.type (%Op.type.2) = struct_value () [symbolic = %Op (constants.%Op.2)]
+// CHECK:STDOUT:   %.2: type = assoc_entity_type @Action.%.1 (%.3), @Action.%Op.type (%Op.type.2) [symbolic = %.2 (constants.%.4)]
+// CHECK:STDOUT:   %.3: @Action.%.2 (%.4) = assoc_entity element0, imports.%import_ref.7 [symbolic = %.3 (constants.%.5)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   interface {
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = imports.%import_ref.8
+// CHECK:STDOUT:     .Op = imports.%import_ref.9
+// CHECK:STDOUT:     witness = (imports.%import_ref.10)
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: impl @impl: %A as %.6;
+// CHECK:STDOUT:
+// CHECK:STDOUT: class @A {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = imports.%import_ref.5
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: class @B {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = imports.%import_ref.6
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @Op.1(constants.%T: type, constants.%Self: %.3) {
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn();
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @F(%a: %A) {
+// CHECK:STDOUT: !entry:
+// CHECK:STDOUT:   %a.ref: %A = name_ref a, %a
+// CHECK:STDOUT:   %Action.ref: %Action.type = name_ref Action, imports.%import_ref.1 [template = constants.%Action]
+// CHECK:STDOUT:   %B.ref: type = name_ref B, imports.%import_ref.3 [template = constants.%B]
+// CHECK:STDOUT:   %.loc4_23: init type = call %Action.ref(%B.ref) [template = constants.%.6]
+// CHECK:STDOUT:   %.loc4_26: %.8 = specific_constant imports.%import_ref.9, @Action(constants.%B) [template = constants.%.9]
+// CHECK:STDOUT:   %Op.ref: %.8 = name_ref Op, %.loc4_26 [template = constants.%.9]
+// CHECK:STDOUT:   %.1: %Op.type.3 = interface_witness_access imports.%import_ref.11, element0 [template = constants.%Op.4]
+// CHECK:STDOUT:   %Op.call: init %.2 = call %.1()
+// CHECK:STDOUT:   return
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Op.2();
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Action(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Action(@Action.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Action(constants.%B) {
+// CHECK:STDOUT:   %T => constants.%B
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1 => constants.%.6
+// CHECK:STDOUT:   %Self => constants.%Self
+// CHECK:STDOUT:   %Op.type => constants.%Op.type.3
+// CHECK:STDOUT:   %Op => constants.%Op.3
+// CHECK:STDOUT:   %.2 => constants.%.8
+// CHECK:STDOUT:   %.3 => constants.%.9
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: --- fail_action.impl.carbon
+// CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %A: type = class_type @A [template]
+// CHECK:STDOUT:   %.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %B: type = class_type @B [template]
+// CHECK:STDOUT:   %Action.type: type = generic_interface_type @Action [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %Action: %Action.type = struct_value () [template]
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic]
+// CHECK:STDOUT:   %.3: type = interface_type @Action, @Action(%T) [symbolic]
+// CHECK:STDOUT:   %Self: %.3 = bind_symbolic_name Self 1 [symbolic]
+// CHECK:STDOUT:   %Op.type.1: type = fn_type @Op [template]
+// CHECK:STDOUT:   %Op.1: %Op.type.1 = struct_value () [template]
+// CHECK:STDOUT:   %Op.type.2: type = fn_type @Op, @Action(%T) [symbolic]
+// CHECK:STDOUT:   %.4: type = assoc_entity_type %.3, %Op.type.2 [symbolic]
+// CHECK:STDOUT:   %.5: %.4 = assoc_entity element0, imports.%import_ref.7 [symbolic]
+// CHECK:STDOUT:   %Op.2: %Op.type.2 = struct_value () [symbolic]
+// CHECK:STDOUT:   %.6: type = interface_type @Action, @Action(%B) [template]
+// CHECK:STDOUT:   %G.type: type = fn_type @G [template]
+// CHECK:STDOUT:   %G: %G.type = struct_value () [template]
+// CHECK:STDOUT:   %.7: type = ptr_type %.1 [template]
+// CHECK:STDOUT:   %C: type = class_type @C [template]
+// CHECK:STDOUT:   %.8: type = interface_type @Action, @Action(%C) [template]
+// CHECK:STDOUT:   %Op.type.3: type = fn_type @Op, @Action(%C) [template]
+// CHECK:STDOUT:   %Op.3: %Op.type.3 = struct_value () [template]
+// CHECK:STDOUT:   %.9: type = assoc_entity_type %.8, %Op.type.3 [template]
+// CHECK:STDOUT:   %.10: %.9 = assoc_entity element0, imports.%import_ref.7 [template]
+// CHECK:STDOUT:   %.11: %.4 = assoc_entity element0, imports.%import_ref.13 [symbolic]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT:   %import_ref.1: %Action.type = import_ref Main//action, inst+4, loaded [template = constants.%Action]
+// CHECK:STDOUT:   %import_ref.2: type = import_ref Main//action, inst+24, loaded [template = constants.%A]
+// CHECK:STDOUT:   %import_ref.3 = import_ref Main//action, inst+27, unloaded
+// CHECK:STDOUT:   %import_ref.4: type = import_ref Main//action, inst+29, loaded [template = constants.%C]
+// CHECK:STDOUT:   %import_ref.5 = import_ref Main//action, inst+25, unloaded
+// CHECK:STDOUT:   %import_ref.6 = import_ref Main//action, inst+28, unloaded
+// CHECK:STDOUT:   %import_ref.7 = import_ref Main//action, inst+12, unloaded
+// CHECK:STDOUT:   %import_ref.8 = import_ref Main//action, inst+10, unloaded
+// CHECK:STDOUT:   %import_ref.9: @Action.%.2 (%.4) = import_ref Main//action, inst+16, loaded [symbolic = @Action.%.3 (constants.%.11)]
+// CHECK:STDOUT:   %import_ref.10 = import_ref Main//action, inst+12, unloaded
+// CHECK:STDOUT:   %import_ref.11 = import_ref Main//action, inst+42, unloaded
+// CHECK:STDOUT:   %import_ref.12 = import_ref Main//action, inst+30, unloaded
+// CHECK:STDOUT:   %import_ref.13 = import_ref Main//action, inst+12, unloaded
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: file {
+// CHECK:STDOUT:   package: <namespace> = namespace [template] {
+// CHECK:STDOUT:     .Action = imports.%import_ref.1
+// CHECK:STDOUT:     .A = imports.%import_ref.2
+// CHECK:STDOUT:     .B = imports.%import_ref.3
+// CHECK:STDOUT:     .C = imports.%import_ref.4
+// CHECK:STDOUT:     .G = %G.decl
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %default.import.loc2_6.1 = import <invalid>
+// CHECK:STDOUT:   %default.import.loc2_6.2 = import <invalid>
+// CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [template = constants.%G] {
+// CHECK:STDOUT:     %A.ref: type = name_ref A, imports.%import_ref.2 [template = constants.%A]
+// CHECK:STDOUT:     %a.loc8_6.1: %A = param a
+// CHECK:STDOUT:     @G.%a: %A = bind_name a, %a.loc8_6.1
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic interface @Action(constants.%T: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1: type = interface_type @Action, @Action(%T) [symbolic = %.1 (constants.%.3)]
+// CHECK:STDOUT:   %Self: %.3 = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self)]
+// CHECK:STDOUT:   %Op.type: type = fn_type @Op, @Action(%T) [symbolic = %Op.type (constants.%Op.type.2)]
+// CHECK:STDOUT:   %Op: @Action.%Op.type (%Op.type.2) = struct_value () [symbolic = %Op (constants.%Op.2)]
+// CHECK:STDOUT:   %.2: type = assoc_entity_type @Action.%.1 (%.3), @Action.%Op.type (%Op.type.2) [symbolic = %.2 (constants.%.4)]
+// CHECK:STDOUT:   %.3: @Action.%.2 (%.4) = assoc_entity element0, imports.%import_ref.7 [symbolic = %.3 (constants.%.5)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   interface {
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = imports.%import_ref.8
+// CHECK:STDOUT:     .Op = imports.%import_ref.9
+// CHECK:STDOUT:     witness = (imports.%import_ref.10)
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: impl @impl: %A as %.6;
+// CHECK:STDOUT:
+// CHECK:STDOUT: class @A {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = imports.%import_ref.5
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: class @B {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = imports.%import_ref.6
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: class @C {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = imports.%import_ref.12
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @Op(constants.%T: type, constants.%Self: %.3) {
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn();
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @G(%a: %A) {
+// CHECK:STDOUT: !entry:
+// CHECK:STDOUT:   %a.ref: %A = name_ref a, %a
+// CHECK:STDOUT:   %Action.ref: %Action.type = name_ref Action, imports.%import_ref.1 [template = constants.%Action]
+// CHECK:STDOUT:   %C.ref: type = name_ref C, imports.%import_ref.4 [template = constants.%C]
+// CHECK:STDOUT:   %.loc8_23: init type = call %Action.ref(%C.ref) [template = constants.%.8]
+// CHECK:STDOUT:   %.loc8_26: %.9 = specific_constant imports.%import_ref.9, @Action(constants.%C) [template = constants.%.10]
+// CHECK:STDOUT:   %Op.ref: %.9 = name_ref Op, %.loc8_26 [template = constants.%.10]
+// CHECK:STDOUT:   return
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Action(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Action(@Action.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Action(constants.%B) {
+// CHECK:STDOUT:   %T => constants.%B
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Action(constants.%C) {
+// CHECK:STDOUT:   %T => constants.%C
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1 => constants.%.8
+// CHECK:STDOUT:   %Self => constants.%Self
+// CHECK:STDOUT:   %Op.type => constants.%Op.type.3
+// CHECK:STDOUT:   %Op => constants.%Op.3
+// CHECK:STDOUT:   %.2 => constants.%.9
+// CHECK:STDOUT:   %.3 => constants.%.10
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: --- fail_todo_factory.carbon
+// CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic]
+// CHECK:STDOUT:   %Factory.type: type = generic_interface_type @Factory [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %Factory: %Factory.type = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = interface_type @Factory, @Factory(%T) [symbolic]
+// CHECK:STDOUT:   %Self: %.2 = bind_symbolic_name Self 1 [symbolic]
+// CHECK:STDOUT:   %Make.type.1: type = fn_type @Make.1, @Factory(%T) [symbolic]
+// CHECK:STDOUT:   %Make.1: %Make.type.1 = struct_value () [symbolic]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.2, %Make.type.1 [symbolic]
+// CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @Factory.%Make.decl [symbolic]
+// CHECK:STDOUT:   %A: type = class_type @A [template]
+// CHECK:STDOUT:   %.5: type = struct_type {} [template]
+// CHECK:STDOUT:   %B: type = class_type @B [template]
+// CHECK:STDOUT:   %.6: type = interface_type @Factory, @Factory(%B) [template]
+// CHECK:STDOUT:   %Make.type.2: type = fn_type @Make.2 [template]
+// CHECK:STDOUT:   %Make.2: %Make.type.2 = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: file {
+// CHECK:STDOUT:   package: <namespace> = namespace [template] {
+// CHECK:STDOUT:     .Factory = %Factory.decl
+// CHECK:STDOUT:     .A = %A.decl
+// CHECK:STDOUT:     .B = %B.decl
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Factory.decl: %Factory.type = interface_decl @Factory [template = constants.%Factory] {
+// CHECK:STDOUT:     %T.loc4_19.1: type = param T
+// CHECK:STDOUT:     %T.loc4_19.2: type = bind_symbolic_name T 0, %T.loc4_19.1 [symbolic = @Factory.%T (constants.%T)]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %A.decl: type = class_decl @A [template = constants.%A] {}
+// CHECK:STDOUT:   %B.decl: type = class_decl @B [template = constants.%B] {}
+// CHECK:STDOUT:   %.loc11_20.1: type = value_of_initializer %.loc11_18 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc11_20.2: type = converted %.loc11_18, %.loc11_20.1 [template = constants.%.6]
+// CHECK:STDOUT:   impl_decl @impl {
+// CHECK:STDOUT:     %A.ref: type = name_ref A, %A.decl [template = constants.%A]
+// CHECK:STDOUT:     %Factory.ref: %Factory.type = name_ref Factory, %Factory.decl [template = constants.%Factory]
+// CHECK:STDOUT:     %B.ref: type = name_ref B, %B.decl [template = constants.%B]
+// CHECK:STDOUT:     %.loc11_18: init type = call %Factory.ref(%B.ref) [template = constants.%.6]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic interface @Factory(file.%T.loc4_19.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1: type = interface_type @Factory, @Factory(%T) [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:   %Self.2: %.2 = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self)]
+// CHECK:STDOUT:   %Make.type: type = fn_type @Make.1, @Factory(%T) [symbolic = %Make.type (constants.%Make.type.1)]
+// CHECK:STDOUT:   %Make: @Factory.%Make.type (%Make.type.1) = struct_value () [symbolic = %Make (constants.%Make.1)]
+// CHECK:STDOUT:   %.2: type = assoc_entity_type @Factory.%.1 (%.2), @Factory.%Make.type (%Make.type.1) [symbolic = %.2 (constants.%.3)]
+// CHECK:STDOUT:   %.3: @Factory.%.2 (%.3) = assoc_entity element0, %Make.decl [symbolic = %.3 (constants.%.4)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   interface {
+// CHECK:STDOUT:     %Self.1: @Factory.%.1 (%.2) = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self)]
+// CHECK:STDOUT:     %Make.decl: @Factory.%Make.type (%Make.type.1) = fn_decl @Make.1 [symbolic = %Make (constants.%Make.1)] {
+// CHECK:STDOUT:       %T.ref: type = name_ref T, file.%T.loc4_19.2 [symbolic = @Make.1.%T (constants.%T)]
+// CHECK:STDOUT:       %return.var: ref @Make.1.%T (%T) = var <return slot>
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %.loc5: @Factory.%.2 (%.3) = assoc_entity element0, %Make.decl [symbolic = %.3 (constants.%.4)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = %Self.1
+// CHECK:STDOUT:     .Make = %.loc5
+// CHECK:STDOUT:     witness = (%Make.decl)
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: impl @impl: %A as %.6 {
+// CHECK:STDOUT:   %Make.decl: %Make.type.2 = fn_decl @Make.2 [template = constants.%Make.2] {
+// CHECK:STDOUT:     %B.ref: type = name_ref B, file.%B.decl [template = constants.%B]
+// CHECK:STDOUT:     %return.var: ref %B = var <return slot>
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %.1: <witness> = interface_witness (<error>) [template = <error>]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Make = %Make.decl
+// CHECK:STDOUT:   witness = %.1
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: class @A {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%A
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: class @B {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%B
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @Make.1(file.%T.loc4_19.2: type, @Factory.%Self.1: @Factory.%.1 (%.2)) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn() -> @Make.1.%T (%T);
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Make.2() -> %B;
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Factory(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Make.1(constants.%T, constants.%Self) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Factory(@Factory.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Factory(constants.%B) {
+// CHECK:STDOUT:   %T => constants.%B
+// CHECK:STDOUT: }
+// CHECK:STDOUT:

+ 1 - 1
toolchain/check/testdata/impl/no_prelude/self_in_class.carbon

@@ -30,7 +30,7 @@ class A {
 // CHECK:STDOUT:   %Make.type.1: type = fn_type @Make.1 [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %Make.1: %Make.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @DefaultConstructible, %Make.type.1 [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %Make.type.1 [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @DefaultConstructible.%Make.decl [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %.5: type = struct_type {} [template]

+ 2 - 2
toolchain/check/testdata/impl/no_prelude/self_in_signature.carbon

@@ -44,7 +44,7 @@ impl D as SelfNested {
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @UseSelf, %F.type.1 [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type.1 [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @UseSelf.%F.decl [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %.5: type = struct_type {} [template]
@@ -66,7 +66,7 @@ impl D as SelfNested {
 // CHECK:STDOUT:   %.13: type = tuple_type (%.10, %.11) [symbolic]
 // CHECK:STDOUT:   %F.type.4: type = fn_type @F.4 [template]
 // CHECK:STDOUT:   %F.4: %F.type.4 = struct_value () [template]
-// CHECK:STDOUT:   %.14: type = assoc_entity_type @SelfNested, %F.type.4 [template]
+// CHECK:STDOUT:   %.14: type = assoc_entity_type %.9, %F.type.4 [template]
 // CHECK:STDOUT:   %.15: %.14 = assoc_entity element0, @SelfNested.%F.decl [template]
 // CHECK:STDOUT:   %.16: type = ptr_type %C [template]
 // CHECK:STDOUT:   %.17: type = struct_type {.x: %C, .y: %.2} [template]

+ 1 - 1
toolchain/check/testdata/index/fail_negative_indexing.carbon

@@ -31,7 +31,7 @@ var b: i32 = a[-10];
 // CHECK:STDOUT:   %Self: %.8 = bind_symbolic_name Self 0 [symbolic]
 // CHECK:STDOUT:   %Op.type: type = fn_type @Op [template]
 // CHECK:STDOUT:   %Op: %Op.type = struct_value () [template]
-// CHECK:STDOUT:   %.9: type = assoc_entity_type @Negate, %Op.type [template]
+// CHECK:STDOUT:   %.9: type = assoc_entity_type %.8, %Op.type [template]
 // CHECK:STDOUT:   %.10: %.9 = assoc_entity element0, imports.%import_ref.6 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 2 - 2
toolchain/check/testdata/interface/assoc_const.carbon

@@ -18,12 +18,12 @@ interface I {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %.1: type = interface_type @I [template]
 // CHECK:STDOUT:   %Self: %.1 = bind_symbolic_name Self 0 [symbolic]
-// CHECK:STDOUT:   %.2: type = assoc_entity_type @I, type [template]
+// CHECK:STDOUT:   %.2: type = assoc_entity_type %.1, type [template]
 // CHECK:STDOUT:   %.3: %.2 = assoc_entity element0, @I.%T [template]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.4: type = tuple_type () [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %.5: type = assoc_entity_type @I, i32 [template]
+// CHECK:STDOUT:   %.5: type = assoc_entity_type %.1, i32 [template]
 // CHECK:STDOUT:   %.6: %.5 = assoc_entity element1, @I.%N [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 1
toolchain/check/testdata/interface/fail_assoc_const_bad_default.carbon

@@ -21,7 +21,7 @@ interface I {
 // CHECK:STDOUT:   %.1: type = interface_type @I [template]
 // CHECK:STDOUT:   %Self: %.1 = bind_symbolic_name Self 0 [symbolic]
 // CHECK:STDOUT:   %.2: i32 = int_literal 42 [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @I, type [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, type [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @I.%T [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 2 - 2
toolchain/check/testdata/interface/fail_todo_assoc_const_default.carbon

@@ -30,10 +30,10 @@ interface I {
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %.3: type = tuple_type (type, type) [template]
 // CHECK:STDOUT:   %.4: type = tuple_type (i32, i32) [template]
-// CHECK:STDOUT:   %.5: type = assoc_entity_type @I, type [template]
+// CHECK:STDOUT:   %.5: type = assoc_entity_type %.1, type [template]
 // CHECK:STDOUT:   %.6: %.5 = assoc_entity element0, @I.%T [template]
 // CHECK:STDOUT:   %.7: i32 = int_literal 42 [template]
-// CHECK:STDOUT:   %.8: type = assoc_entity_type @I, i32 [template]
+// CHECK:STDOUT:   %.8: type = assoc_entity_type %.1, i32 [template]
 // CHECK:STDOUT:   %.9: %.8 = assoc_entity element1, @I.%N [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 2 - 2
toolchain/check/testdata/interface/fail_todo_define_default_fn_inline.carbon

@@ -29,13 +29,13 @@ interface Interface {
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @Interface, %F.type [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @Interface.%F.decl [template]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
-// CHECK:STDOUT:   %.5: type = assoc_entity_type @Interface, %G.type [template]
+// CHECK:STDOUT:   %.5: type = assoc_entity_type %.1, %G.type [template]
 // CHECK:STDOUT:   %.6: %.5 = assoc_entity element1, @Interface.%G.decl [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 2 - 2
toolchain/check/testdata/interface/fail_todo_define_default_fn_out_of_line.carbon

@@ -71,13 +71,13 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; }
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @Interface, %F.type [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @Interface.%F.decl [template]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
-// CHECK:STDOUT:   %.5: type = assoc_entity_type @Interface, %G.type [template]
+// CHECK:STDOUT:   %.5: type = assoc_entity_type %.1, %G.type [template]
 // CHECK:STDOUT:   %.6: %.5 = assoc_entity element1, @Interface.%G.decl [template]
 // CHECK:STDOUT:   %.type.1: type = fn_type @.1 [template]
 // CHECK:STDOUT:   %.7: %.type.1 = struct_value () [template]

+ 1 - 1
toolchain/check/testdata/interface/no_prelude/basic.carbon

@@ -27,7 +27,7 @@ interface ForwardDeclared {
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %.3: type = tuple_type () [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.4: type = assoc_entity_type @ForwardDeclared, %F.type [template]
+// CHECK:STDOUT:   %.4: type = assoc_entity_type %.2, %F.type [template]
 // CHECK:STDOUT:   %.5: %.4 = assoc_entity element0, @ForwardDeclared.%F.decl [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 1
toolchain/check/testdata/interface/no_prelude/default_fn.carbon

@@ -32,7 +32,7 @@ class C {
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @I, %F.type.1 [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type.1 [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @I.%F.decl [template]
 // CHECK:STDOUT:   %F.type.2: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.2: %F.type.2 = struct_value () [template]

+ 1 - 1
toolchain/check/testdata/interface/no_prelude/fail_lookup_undefined.carbon

@@ -62,7 +62,7 @@ interface BeingDefined {
 // CHECK:STDOUT:   %Self: %.4 = bind_symbolic_name Self 0 [symbolic]
 // CHECK:STDOUT:   %H.type: type = fn_type @H [template]
 // CHECK:STDOUT:   %H: %H.type = struct_value () [template]
-// CHECK:STDOUT:   %.5: type = assoc_entity_type @BeingDefined, %H.type [template]
+// CHECK:STDOUT:   %.5: type = assoc_entity_type %.4, %H.type [template]
 // CHECK:STDOUT:   %.6: %.5 = assoc_entity element0, @BeingDefined.%H.decl [template]
 // CHECK:STDOUT:   %.type.2: type = fn_type @.2 [template]
 // CHECK:STDOUT:   %.7: %.type.2 = struct_value () [template]

+ 2 - 2
toolchain/check/testdata/interface/no_prelude/fail_member_lookup.carbon

@@ -35,9 +35,9 @@ fn F() {
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @Interface, %F.type.1 [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type.1 [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @Interface.%F.decl [template]
-// CHECK:STDOUT:   %.5: type = assoc_entity_type @Interface, type [template]
+// CHECK:STDOUT:   %.5: type = assoc_entity_type %.1, type [template]
 // CHECK:STDOUT:   %.6: %.5 = assoc_entity element1, @Interface.%T [template]
 // CHECK:STDOUT:   %F.type.2: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.2: %F.type.2 = struct_value () [template]

+ 1 - 1
toolchain/check/testdata/interface/no_prelude/fail_redeclare_member.carbon

@@ -27,7 +27,7 @@ interface Interface {
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @Interface, %F.type [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @Interface.%F.decl [template]
 // CHECK:STDOUT:   %.type: type = fn_type @.1 [template]
 // CHECK:STDOUT:   %.5: %.type = struct_value () [template]

+ 1 - 1
toolchain/check/testdata/interface/no_prelude/fail_todo_facet_lookup.carbon

@@ -33,7 +33,7 @@ fn CallFacet(T:! Interface, x: T) {
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @Interface, %F.type [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @Interface.%F.decl [template]
 // CHECK:STDOUT:   %T: %.1 = bind_symbolic_name T 0 [symbolic]
 // CHECK:STDOUT:   %CallStatic.type: type = fn_type @CallStatic [template]

+ 2 - 2
toolchain/check/testdata/interface/no_prelude/fail_todo_generic_default_fn.carbon

@@ -32,7 +32,7 @@ fn I(T:! type).F[self: Self]() -> Self { return self; }
 // CHECK:STDOUT:   %Self: %.2 = bind_symbolic_name Self 1 [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F, @I(%T) [symbolic]
 // CHECK:STDOUT:   %F.1: %F.type = struct_value () [symbolic]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @I, %F.type [symbolic]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.2, %F.type [symbolic]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @I.%F.decl [symbolic]
 // CHECK:STDOUT:   %F.2: %F.type = struct_value () [symbolic]
 // CHECK:STDOUT:   %.type: type = fn_type @.1, @I(%T) [symbolic]
@@ -72,7 +72,7 @@ fn I(T:! type).F[self: Self]() -> Self { return self; }
 // CHECK:STDOUT:   %Self.2: %.2 = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self)]
 // CHECK:STDOUT:   %F.type: type = fn_type @F, @I(%T) [symbolic = %F.type (constants.%F.type)]
 // CHECK:STDOUT:   %F: @I.%F.type (%F.type) = struct_value () [symbolic = %F (constants.%F.1)]
-// CHECK:STDOUT:   %.2: type = assoc_entity_type @I, @I.%F.type (%F.type) [symbolic = %.2 (constants.%.3)]
+// CHECK:STDOUT:   %.2: type = assoc_entity_type @I.%.1 (%.2), @I.%F.type (%F.type) [symbolic = %.2 (constants.%.3)]
 // CHECK:STDOUT:   %.3: @I.%.2 (%.3) = assoc_entity element0, %F.decl [symbolic = %.3 (constants.%.4)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {

+ 2 - 2
toolchain/check/testdata/interface/no_prelude/fail_todo_modifiers.carbon

@@ -28,11 +28,11 @@ interface Modifiers {
 // CHECK:STDOUT:   %Final.type: type = fn_type @Final [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %Final: %Final.type = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @Modifiers, %Final.type [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %Final.type [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @Modifiers.%Final.decl [template]
 // CHECK:STDOUT:   %Default.type: type = fn_type @Default [template]
 // CHECK:STDOUT:   %Default: %Default.type = struct_value () [template]
-// CHECK:STDOUT:   %.5: type = assoc_entity_type @Modifiers, %Default.type [template]
+// CHECK:STDOUT:   %.5: type = assoc_entity_type %.1, %Default.type [template]
 // CHECK:STDOUT:   %.6: %.5 = assoc_entity element1, @Modifiers.%Default.decl [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 2 - 2
toolchain/check/testdata/interface/no_prelude/generic.carbon

@@ -75,7 +75,7 @@ fn G(T:! Generic(B)) {
 // CHECK:STDOUT:   %Self.2: %.4 = bind_symbolic_name Self 1 [symbolic]
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1, @WithAssocFn(%T.1) [symbolic]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [symbolic]
-// CHECK:STDOUT:   %.5: type = assoc_entity_type @WithAssocFn, %F.type.1 [symbolic]
+// CHECK:STDOUT:   %.5: type = assoc_entity_type %.4, %F.type.1 [symbolic]
 // CHECK:STDOUT:   %.6: %.5 = assoc_entity element0, @WithAssocFn.%F.decl [symbolic]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %.7: type = interface_type @Simple, @Simple(%C) [template]
@@ -167,7 +167,7 @@ fn G(T:! Generic(B)) {
 // CHECK:STDOUT:   %Self.2: %.4 = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self.2)]
 // CHECK:STDOUT:   %F.type: type = fn_type @F.1, @WithAssocFn(%T) [symbolic = %F.type (constants.%F.type.1)]
 // CHECK:STDOUT:   %F: @WithAssocFn.%F.type (%F.type.1) = struct_value () [symbolic = %F (constants.%F.1)]
-// CHECK:STDOUT:   %.2: type = assoc_entity_type @WithAssocFn, @WithAssocFn.%F.type (%F.type.1) [symbolic = %.2 (constants.%.5)]
+// CHECK:STDOUT:   %.2: type = assoc_entity_type @WithAssocFn.%.1 (%.4), @WithAssocFn.%F.type (%F.type.1) [symbolic = %.2 (constants.%.5)]
 // CHECK:STDOUT:   %.3: @WithAssocFn.%.2 (%.5) = assoc_entity element0, %F.decl [symbolic = %.3 (constants.%.6)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {

+ 3 - 3
toolchain/check/testdata/interface/no_prelude/generic_binding_after_assoc_const.carbon

@@ -25,13 +25,13 @@ interface I {
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @I, %F.type [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @I.%F.decl [template]
-// CHECK:STDOUT:   %.5: type = assoc_entity_type @I, type [template]
+// CHECK:STDOUT:   %.5: type = assoc_entity_type %.1, type [template]
 // CHECK:STDOUT:   %.6: %.5 = assoc_entity element1, @I.%U [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
-// CHECK:STDOUT:   %.7: type = assoc_entity_type @I, %G.type [template]
+// CHECK:STDOUT:   %.7: type = assoc_entity_type %.1, %G.type [template]
 // CHECK:STDOUT:   %.8: %.7 = assoc_entity element2, @I.%G.decl [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 4 - 4
toolchain/check/testdata/interface/no_prelude/generic_import.carbon

@@ -38,7 +38,7 @@ impl C as AddWith(C) {
 // CHECK:STDOUT:   %Self: %.2 = bind_symbolic_name Self 1 [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F, @AddWith(%T) [symbolic]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [symbolic]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @AddWith, %F.type [symbolic]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.2, %F.type [symbolic]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @AddWith.%F.decl [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -60,7 +60,7 @@ impl C as AddWith(C) {
 // CHECK:STDOUT:   %Self.2: %.2 = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self)]
 // CHECK:STDOUT:   %F.type: type = fn_type @F, @AddWith(%T) [symbolic = %F.type (constants.%F.type)]
 // CHECK:STDOUT:   %F: @AddWith.%F.type (%F.type) = struct_value () [symbolic = %F (constants.%F)]
-// CHECK:STDOUT:   %.2: type = assoc_entity_type @AddWith, @AddWith.%F.type (%F.type) [symbolic = %.2 (constants.%.3)]
+// CHECK:STDOUT:   %.2: type = assoc_entity_type @AddWith.%.1 (%.2), @AddWith.%F.type (%F.type) [symbolic = %.2 (constants.%.3)]
 // CHECK:STDOUT:   %.3: @AddWith.%.2 (%.3) = assoc_entity element0, %F.decl [symbolic = %.3 (constants.%.4)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
@@ -104,7 +104,7 @@ impl C as AddWith(C) {
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
 // CHECK:STDOUT:   %F.type.2: type = fn_type @F.1, @AddWith(%T) [symbolic]
-// CHECK:STDOUT:   %.4: type = assoc_entity_type @AddWith, %F.type.2 [symbolic]
+// CHECK:STDOUT:   %.4: type = assoc_entity_type %.3, %F.type.2 [symbolic]
 // CHECK:STDOUT:   %.5: %.4 = assoc_entity element0, imports.%import_ref.2 [symbolic]
 // CHECK:STDOUT:   %F.2: %F.type.2 = struct_value () [symbolic]
 // CHECK:STDOUT:   %.6: type = interface_type @AddWith, @AddWith(%C) [template]
@@ -146,7 +146,7 @@ impl C as AddWith(C) {
 // CHECK:STDOUT:   %Self: %.3 = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self)]
 // CHECK:STDOUT:   %F.type: type = fn_type @F.1, @AddWith(%T) [symbolic = %F.type (constants.%F.type.2)]
 // CHECK:STDOUT:   %F: @AddWith.%F.type (%F.type.2) = struct_value () [symbolic = %F (constants.%F.2)]
-// CHECK:STDOUT:   %.2: type = assoc_entity_type @AddWith, @AddWith.%F.type (%F.type.2) [symbolic = %.2 (constants.%.4)]
+// CHECK:STDOUT:   %.2: type = assoc_entity_type @AddWith.%.1 (%.3), @AddWith.%F.type (%F.type.2) [symbolic = %.2 (constants.%.4)]
 // CHECK:STDOUT:   %.3: @AddWith.%.2 (%.4) = assoc_entity element0, imports.%import_ref.2 [symbolic = %.3 (constants.%.5)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {

+ 8 - 8
toolchain/check/testdata/interface/no_prelude/import.carbon

@@ -55,20 +55,20 @@ var f: ForwardDeclared* = &f_ref.f;
 // CHECK:STDOUT:   %Self.1: %.1 = bind_symbolic_name Self 0 [symbolic]
 // CHECK:STDOUT:   %.2: type = interface_type @Basic [template]
 // CHECK:STDOUT:   %Self.2: %.2 = bind_symbolic_name Self 0 [symbolic]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @Basic, type [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.2, type [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @Basic.%T [template]
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %.5: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.6: type = assoc_entity_type @Basic, %F.type.1 [template]
+// CHECK:STDOUT:   %.6: type = assoc_entity_type %.2, %F.type.1 [template]
 // CHECK:STDOUT:   %.7: %.6 = assoc_entity element1, @Basic.%F.decl [template]
 // CHECK:STDOUT:   %.8: type = interface_type @ForwardDeclared [template]
 // CHECK:STDOUT:   %Self.3: %.8 = bind_symbolic_name Self 0 [symbolic]
-// CHECK:STDOUT:   %.9: type = assoc_entity_type @ForwardDeclared, type [template]
+// CHECK:STDOUT:   %.9: type = assoc_entity_type %.8, type [template]
 // CHECK:STDOUT:   %.10: %.9 = assoc_entity element0, @ForwardDeclared.%T [template]
 // CHECK:STDOUT:   %F.type.2: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.2: %F.type.2 = struct_value () [template]
-// CHECK:STDOUT:   %.11: type = assoc_entity_type @ForwardDeclared, %F.type.2 [template]
+// CHECK:STDOUT:   %.11: type = assoc_entity_type %.8, %F.type.2 [template]
 // CHECK:STDOUT:   %.12: %.11 = assoc_entity element1, @ForwardDeclared.%F.decl [template]
 // CHECK:STDOUT:   %.13: type = struct_type {.f: %.8} [template]
 // CHECK:STDOUT:   %.14: type = struct_type {.f: %.5} [template]
@@ -156,17 +156,17 @@ var f: ForwardDeclared* = &f_ref.f;
 // CHECK:STDOUT:   %Self.3: %.4 = bind_symbolic_name Self 0 [symbolic]
 // CHECK:STDOUT:   %UseForwardDeclared.type: type = fn_type @UseForwardDeclared [template]
 // CHECK:STDOUT:   %UseForwardDeclared: %UseForwardDeclared.type = struct_value () [template]
-// CHECK:STDOUT:   %.5: type = assoc_entity_type @Basic, type [template]
+// CHECK:STDOUT:   %.5: type = assoc_entity_type %.3, type [template]
 // CHECK:STDOUT:   %.6: %.5 = assoc_entity element0, imports.%import_ref.16 [template]
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.7: type = assoc_entity_type @Basic, %F.type.1 [template]
+// CHECK:STDOUT:   %.7: type = assoc_entity_type %.3, %F.type.1 [template]
 // CHECK:STDOUT:   %.8: %.7 = assoc_entity element1, imports.%import_ref.17 [template]
-// CHECK:STDOUT:   %.9: type = assoc_entity_type @ForwardDeclared, type [template]
+// CHECK:STDOUT:   %.9: type = assoc_entity_type %.4, type [template]
 // CHECK:STDOUT:   %.10: %.9 = assoc_entity element0, imports.%import_ref.18 [template]
 // CHECK:STDOUT:   %F.type.2: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.2: %F.type.2 = struct_value () [template]
-// CHECK:STDOUT:   %.11: type = assoc_entity_type @ForwardDeclared, %F.type.2 [template]
+// CHECK:STDOUT:   %.11: type = assoc_entity_type %.4, %F.type.2 [template]
 // CHECK:STDOUT:   %.12: %.11 = assoc_entity element1, imports.%import_ref.19 [template]
 // CHECK:STDOUT:   %.13: type = ptr_type %.4 [template]
 // CHECK:STDOUT:   %.14: type = struct_type {.f: %.4} [template]

+ 1 - 1
toolchain/check/testdata/interface/no_prelude/self.carbon

@@ -20,7 +20,7 @@ interface UseSelf {
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @UseSelf, %F.type [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @UseSelf.%F.decl [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 4 - 4
toolchain/check/testdata/interface/todo_define_not_default.carbon

@@ -27,20 +27,20 @@ interface I {
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = assoc_entity_type @I, %F.type [template]
+// CHECK:STDOUT:   %.3: type = assoc_entity_type %.1, %F.type [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @I.%F.decl [template]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
-// CHECK:STDOUT:   %.5: type = assoc_entity_type @I, %G.type [template]
+// CHECK:STDOUT:   %.5: type = assoc_entity_type %.1, %G.type [template]
 // CHECK:STDOUT:   %.6: %.5 = assoc_entity element1, @I.%G.decl [template]
 // CHECK:STDOUT:   %.7: type = tuple_type (type, type) [template]
 // CHECK:STDOUT:   %.8: type = tuple_type (i32, i32) [template]
-// CHECK:STDOUT:   %.9: type = assoc_entity_type @I, type [template]
+// CHECK:STDOUT:   %.9: type = assoc_entity_type %.1, type [template]
 // CHECK:STDOUT:   %.10: %.9 = assoc_entity element2, @I.%T [template]
 // CHECK:STDOUT:   %.11: i32 = int_literal 42 [template]
-// CHECK:STDOUT:   %.12: type = assoc_entity_type @I, i32 [template]
+// CHECK:STDOUT:   %.12: type = assoc_entity_type %.1, i32 [template]
 // CHECK:STDOUT:   %.13: %.12 = assoc_entity element3, @I.%N [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 1
toolchain/check/testdata/operators/builtin/fail_type_mismatch_once.carbon

@@ -35,7 +35,7 @@ fn Main() -> i32 {
 // CHECK:STDOUT:   %Self: %.4 = bind_symbolic_name Self 0 [symbolic]
 // CHECK:STDOUT:   %Op.type: type = fn_type @Op [template]
 // CHECK:STDOUT:   %Op: %Op.type = struct_value () [template]
-// CHECK:STDOUT:   %.5: type = assoc_entity_type @Add, %Op.type [template]
+// CHECK:STDOUT:   %.5: type = assoc_entity_type %.4, %Op.type [template]
 // CHECK:STDOUT:   %.6: %.5 = assoc_entity element0, imports.%import_ref.6 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 1
toolchain/check/testdata/operators/builtin/fail_unimplemented_op.carbon

@@ -29,7 +29,7 @@ fn Main() -> i32 {
 // CHECK:STDOUT:   %Self: %.4 = bind_symbolic_name Self 0 [symbolic]
 // CHECK:STDOUT:   %Op.type: type = fn_type @Op [template]
 // CHECK:STDOUT:   %Op: %Op.type = struct_value () [template]
-// CHECK:STDOUT:   %.5: type = assoc_entity_type @Add, %Op.type [template]
+// CHECK:STDOUT:   %.5: type = assoc_entity_type %.4, %Op.type [template]
 // CHECK:STDOUT:   %.6: %.5 = assoc_entity element0, imports.%import_ref.6 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 2 - 2
toolchain/check/testdata/operators/overloaded/add.carbon

@@ -57,11 +57,11 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %.9: <witness> = interface_witness (%Op.3) [template]
 // CHECK:STDOUT:   %TestOp.type: type = fn_type @TestOp [template]
 // CHECK:STDOUT:   %TestOp: %TestOp.type = struct_value () [template]
-// CHECK:STDOUT:   %.10: type = assoc_entity_type @Add, %Op.type.2 [template]
+// CHECK:STDOUT:   %.10: type = assoc_entity_type %.2, %Op.type.2 [template]
 // CHECK:STDOUT:   %.11: %.10 = assoc_entity element0, imports.%import_ref.9 [template]
 // CHECK:STDOUT:   %TestAssign.type: type = fn_type @TestAssign [template]
 // CHECK:STDOUT:   %TestAssign: %TestAssign.type = struct_value () [template]
-// CHECK:STDOUT:   %.12: type = assoc_entity_type @AddAssign, %Op.type.4 [template]
+// CHECK:STDOUT:   %.12: type = assoc_entity_type %.6, %Op.type.4 [template]
 // CHECK:STDOUT:   %.13: %.12 = assoc_entity element0, imports.%import_ref.10 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 2 - 2
toolchain/check/testdata/operators/overloaded/bit_and.carbon

@@ -57,11 +57,11 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %.9: <witness> = interface_witness (%Op.3) [template]
 // CHECK:STDOUT:   %TestOp.type: type = fn_type @TestOp [template]
 // CHECK:STDOUT:   %TestOp: %TestOp.type = struct_value () [template]
-// CHECK:STDOUT:   %.10: type = assoc_entity_type @BitAnd, %Op.type.2 [template]
+// CHECK:STDOUT:   %.10: type = assoc_entity_type %.2, %Op.type.2 [template]
 // CHECK:STDOUT:   %.11: %.10 = assoc_entity element0, imports.%import_ref.9 [template]
 // CHECK:STDOUT:   %TestAssign.type: type = fn_type @TestAssign [template]
 // CHECK:STDOUT:   %TestAssign: %TestAssign.type = struct_value () [template]
-// CHECK:STDOUT:   %.12: type = assoc_entity_type @BitAndAssign, %Op.type.4 [template]
+// CHECK:STDOUT:   %.12: type = assoc_entity_type %.6, %Op.type.4 [template]
 // CHECK:STDOUT:   %.13: %.12 = assoc_entity element0, imports.%import_ref.10 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 1
toolchain/check/testdata/operators/overloaded/bit_complement.carbon

@@ -41,7 +41,7 @@ fn TestOp(a: C) -> C {
 // CHECK:STDOUT:   %struct: %C = struct_value () [template]
 // CHECK:STDOUT:   %TestOp.type: type = fn_type @TestOp [template]
 // CHECK:STDOUT:   %TestOp: %TestOp.type = struct_value () [template]
-// CHECK:STDOUT:   %.6: type = assoc_entity_type @BitComplement, %Op.type.2 [template]
+// CHECK:STDOUT:   %.6: type = assoc_entity_type %.2, %Op.type.2 [template]
 // CHECK:STDOUT:   %.7: %.6 = assoc_entity element0, imports.%import_ref.5 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 2 - 2
toolchain/check/testdata/operators/overloaded/bit_or.carbon

@@ -57,11 +57,11 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %.9: <witness> = interface_witness (%Op.3) [template]
 // CHECK:STDOUT:   %TestOp.type: type = fn_type @TestOp [template]
 // CHECK:STDOUT:   %TestOp: %TestOp.type = struct_value () [template]
-// CHECK:STDOUT:   %.10: type = assoc_entity_type @BitOr, %Op.type.2 [template]
+// CHECK:STDOUT:   %.10: type = assoc_entity_type %.2, %Op.type.2 [template]
 // CHECK:STDOUT:   %.11: %.10 = assoc_entity element0, imports.%import_ref.9 [template]
 // CHECK:STDOUT:   %TestAssign.type: type = fn_type @TestAssign [template]
 // CHECK:STDOUT:   %TestAssign: %TestAssign.type = struct_value () [template]
-// CHECK:STDOUT:   %.12: type = assoc_entity_type @BitOrAssign, %Op.type.4 [template]
+// CHECK:STDOUT:   %.12: type = assoc_entity_type %.6, %Op.type.4 [template]
 // CHECK:STDOUT:   %.13: %.12 = assoc_entity element0, imports.%import_ref.10 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 2 - 2
toolchain/check/testdata/operators/overloaded/bit_xor.carbon

@@ -57,11 +57,11 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %.9: <witness> = interface_witness (%Op.3) [template]
 // CHECK:STDOUT:   %TestOp.type: type = fn_type @TestOp [template]
 // CHECK:STDOUT:   %TestOp: %TestOp.type = struct_value () [template]
-// CHECK:STDOUT:   %.10: type = assoc_entity_type @BitXor, %Op.type.2 [template]
+// CHECK:STDOUT:   %.10: type = assoc_entity_type %.2, %Op.type.2 [template]
 // CHECK:STDOUT:   %.11: %.10 = assoc_entity element0, imports.%import_ref.9 [template]
 // CHECK:STDOUT:   %TestAssign.type: type = fn_type @TestAssign [template]
 // CHECK:STDOUT:   %TestAssign: %TestAssign.type = struct_value () [template]
-// CHECK:STDOUT:   %.12: type = assoc_entity_type @BitXorAssign, %Op.type.4 [template]
+// CHECK:STDOUT:   %.12: type = assoc_entity_type %.6, %Op.type.4 [template]
 // CHECK:STDOUT:   %.13: %.12 = assoc_entity element0, imports.%import_ref.10 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 1
toolchain/check/testdata/operators/overloaded/dec.carbon

@@ -42,7 +42,7 @@ fn TestOp() {
 // CHECK:STDOUT:   %TestOp: %TestOp.type = struct_value () [template]
 // CHECK:STDOUT:   %.7: type = ptr_type %.1 [template]
 // CHECK:STDOUT:   %struct: %C = struct_value () [template]
-// CHECK:STDOUT:   %.8: type = assoc_entity_type @Dec, %Op.type.2 [template]
+// CHECK:STDOUT:   %.8: type = assoc_entity_type %.2, %Op.type.2 [template]
 // CHECK:STDOUT:   %.9: %.8 = assoc_entity element0, imports.%import_ref.5 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 2 - 2
toolchain/check/testdata/operators/overloaded/div.carbon

@@ -57,11 +57,11 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %.9: <witness> = interface_witness (%Op.3) [template]
 // CHECK:STDOUT:   %TestOp.type: type = fn_type @TestOp [template]
 // CHECK:STDOUT:   %TestOp: %TestOp.type = struct_value () [template]
-// CHECK:STDOUT:   %.10: type = assoc_entity_type @Div, %Op.type.2 [template]
+// CHECK:STDOUT:   %.10: type = assoc_entity_type %.2, %Op.type.2 [template]
 // CHECK:STDOUT:   %.11: %.10 = assoc_entity element0, imports.%import_ref.9 [template]
 // CHECK:STDOUT:   %TestAssign.type: type = fn_type @TestAssign [template]
 // CHECK:STDOUT:   %TestAssign: %TestAssign.type = struct_value () [template]
-// CHECK:STDOUT:   %.12: type = assoc_entity_type @DivAssign, %Op.type.4 [template]
+// CHECK:STDOUT:   %.12: type = assoc_entity_type %.6, %Op.type.4 [template]
 // CHECK:STDOUT:   %.13: %.12 = assoc_entity element0, imports.%import_ref.10 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 6 - 6
toolchain/check/testdata/operators/overloaded/eq.carbon

@@ -101,11 +101,11 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT:   %TestEqual.type: type = fn_type @TestEqual [template]
 // CHECK:STDOUT:   %TestEqual: %TestEqual.type = struct_value () [template]
 // CHECK:STDOUT:   %.5: type = ptr_type %.1 [template]
-// CHECK:STDOUT:   %.6: type = assoc_entity_type @Eq, %Equal.type.2 [template]
+// CHECK:STDOUT:   %.6: type = assoc_entity_type %.2, %Equal.type.2 [template]
 // CHECK:STDOUT:   %.7: %.6 = assoc_entity element0, imports.%import_ref.8 [template]
 // CHECK:STDOUT:   %TestNotEqual.type: type = fn_type @TestNotEqual [template]
 // CHECK:STDOUT:   %TestNotEqual: %TestNotEqual.type = struct_value () [template]
-// CHECK:STDOUT:   %.8: type = assoc_entity_type @Eq, %NotEqual.type.2 [template]
+// CHECK:STDOUT:   %.8: type = assoc_entity_type %.2, %NotEqual.type.2 [template]
 // CHECK:STDOUT:   %.9: %.8 = assoc_entity element1, imports.%import_ref.9 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -275,13 +275,13 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT:   %Self: %.4 = bind_symbolic_name Self 0 [symbolic]
 // CHECK:STDOUT:   %Equal.type: type = fn_type @Equal [template]
 // CHECK:STDOUT:   %Equal: %Equal.type = struct_value () [template]
-// CHECK:STDOUT:   %.5: type = assoc_entity_type @Eq, %Equal.type [template]
+// CHECK:STDOUT:   %.5: type = assoc_entity_type %.4, %Equal.type [template]
 // CHECK:STDOUT:   %.6: %.5 = assoc_entity element0, imports.%import_ref.8 [template]
 // CHECK:STDOUT:   %TestNotEqual.type: type = fn_type @TestNotEqual [template]
 // CHECK:STDOUT:   %TestNotEqual: %TestNotEqual.type = struct_value () [template]
 // CHECK:STDOUT:   %NotEqual.type: type = fn_type @NotEqual [template]
 // CHECK:STDOUT:   %NotEqual: %NotEqual.type = struct_value () [template]
-// CHECK:STDOUT:   %.7: type = assoc_entity_type @Eq, %NotEqual.type [template]
+// CHECK:STDOUT:   %.7: type = assoc_entity_type %.4, %NotEqual.type [template]
 // CHECK:STDOUT:   %.8: %.7 = assoc_entity element1, imports.%import_ref.9 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -407,11 +407,11 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT:   %TestRhsBad.type: type = fn_type @TestRhsBad [template]
 // CHECK:STDOUT:   %TestRhsBad: %TestRhsBad.type = struct_value () [template]
 // CHECK:STDOUT:   %.5: type = ptr_type %.1 [template]
-// CHECK:STDOUT:   %.6: type = assoc_entity_type @Eq, %Equal.type.2 [template]
+// CHECK:STDOUT:   %.6: type = assoc_entity_type %.2, %Equal.type.2 [template]
 // CHECK:STDOUT:   %.7: %.6 = assoc_entity element0, imports.%import_ref.8 [template]
 // CHECK:STDOUT:   %TestLhsBad.type: type = fn_type @TestLhsBad [template]
 // CHECK:STDOUT:   %TestLhsBad: %TestLhsBad.type = struct_value () [template]
-// CHECK:STDOUT:   %.8: type = assoc_entity_type @Eq, %NotEqual.type.2 [template]
+// CHECK:STDOUT:   %.8: type = assoc_entity_type %.2, %NotEqual.type.2 [template]
 // CHECK:STDOUT:   %.9: %.8 = assoc_entity element1, imports.%import_ref.9 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 2 - 2
toolchain/check/testdata/operators/overloaded/fail_assign_non_ref.carbon

@@ -66,11 +66,11 @@ fn TestAddAssignNonRef(a: C, b: C) {
 // CHECK:STDOUT:   %TestIncNonRef.type: type = fn_type @TestIncNonRef [template]
 // CHECK:STDOUT:   %TestIncNonRef: %TestIncNonRef.type = struct_value () [template]
 // CHECK:STDOUT:   %.10: type = ptr_type %.1 [template]
-// CHECK:STDOUT:   %.11: type = assoc_entity_type @Inc, %Op.type.2 [template]
+// CHECK:STDOUT:   %.11: type = assoc_entity_type %.2, %Op.type.2 [template]
 // CHECK:STDOUT:   %.12: %.11 = assoc_entity element0, imports.%import_ref.9 [template]
 // CHECK:STDOUT:   %TestAddAssignNonRef.type: type = fn_type @TestAddAssignNonRef [template]
 // CHECK:STDOUT:   %TestAddAssignNonRef: %TestAddAssignNonRef.type = struct_value () [template]
-// CHECK:STDOUT:   %.13: type = assoc_entity_type @AddAssign, %Op.type.4 [template]
+// CHECK:STDOUT:   %.13: type = assoc_entity_type %.7, %Op.type.4 [template]
 // CHECK:STDOUT:   %.14: %.13 = assoc_entity element0, imports.%import_ref.10 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 4 - 4
toolchain/check/testdata/operators/overloaded/fail_no_impl.carbon

@@ -54,7 +54,7 @@ fn TestRef(b: C) {
 // CHECK:STDOUT:   %Self.1: %.4 = bind_symbolic_name Self 0 [symbolic]
 // CHECK:STDOUT:   %Op.type.1: type = fn_type @Op.1 [template]
 // CHECK:STDOUT:   %Op.1: %Op.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.5: type = assoc_entity_type @Negate, %Op.type.1 [template]
+// CHECK:STDOUT:   %.5: type = assoc_entity_type %.4, %Op.type.1 [template]
 // CHECK:STDOUT:   %.6: %.5 = assoc_entity element0, imports.%import_ref.5 [template]
 // CHECK:STDOUT:   %TestBinary.type: type = fn_type @TestBinary [template]
 // CHECK:STDOUT:   %TestBinary: %TestBinary.type = struct_value () [template]
@@ -62,7 +62,7 @@ fn TestRef(b: C) {
 // CHECK:STDOUT:   %Self.2: %.7 = bind_symbolic_name Self 0 [symbolic]
 // CHECK:STDOUT:   %Op.type.2: type = fn_type @Op.2 [template]
 // CHECK:STDOUT:   %Op.2: %Op.type.2 = struct_value () [template]
-// CHECK:STDOUT:   %.8: type = assoc_entity_type @Add, %Op.type.2 [template]
+// CHECK:STDOUT:   %.8: type = assoc_entity_type %.7, %Op.type.2 [template]
 // CHECK:STDOUT:   %.9: %.8 = assoc_entity element0, imports.%import_ref.10 [template]
 // CHECK:STDOUT:   %TestRef.type: type = fn_type @TestRef [template]
 // CHECK:STDOUT:   %TestRef: %TestRef.type = struct_value () [template]
@@ -72,14 +72,14 @@ fn TestRef(b: C) {
 // CHECK:STDOUT:   %Op.type.3: type = fn_type @Op.3 [template]
 // CHECK:STDOUT:   %Op.3: %Op.type.3 = struct_value () [template]
 // CHECK:STDOUT:   %.11: type = ptr_type %Self.3 [symbolic]
-// CHECK:STDOUT:   %.12: type = assoc_entity_type @AddAssign, %Op.type.3 [template]
+// CHECK:STDOUT:   %.12: type = assoc_entity_type %.10, %Op.type.3 [template]
 // CHECK:STDOUT:   %.13: %.12 = assoc_entity element0, imports.%import_ref.15 [template]
 // CHECK:STDOUT:   %.14: type = interface_type @Inc [template]
 // CHECK:STDOUT:   %Self.4: %.14 = bind_symbolic_name Self 0 [symbolic]
 // CHECK:STDOUT:   %Op.type.4: type = fn_type @Op.4 [template]
 // CHECK:STDOUT:   %Op.4: %Op.type.4 = struct_value () [template]
 // CHECK:STDOUT:   %.15: type = ptr_type %Self.4 [symbolic]
-// CHECK:STDOUT:   %.16: type = assoc_entity_type @Inc, %Op.type.4 [template]
+// CHECK:STDOUT:   %.16: type = assoc_entity_type %.14, %Op.type.4 [template]
 // CHECK:STDOUT:   %.17: %.16 = assoc_entity element0, imports.%import_ref.20 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 2 - 2
toolchain/check/testdata/operators/overloaded/fail_no_impl_for_arg.carbon

@@ -68,12 +68,12 @@ fn TestAssign(b: D) {
 // CHECK:STDOUT:   %Test.type: type = fn_type @Test [template]
 // CHECK:STDOUT:   %Test: %Test.type = struct_value () [template]
 // CHECK:STDOUT:   %.9: type = ptr_type %.1 [template]
-// CHECK:STDOUT:   %.10: type = assoc_entity_type @Add, %Op.type.2 [template]
+// CHECK:STDOUT:   %.10: type = assoc_entity_type %.2, %Op.type.2 [template]
 // CHECK:STDOUT:   %.11: %.10 = assoc_entity element0, imports.%import_ref.9 [template]
 // CHECK:STDOUT:   %TestAssign.type: type = fn_type @TestAssign [template]
 // CHECK:STDOUT:   %TestAssign: %TestAssign.type = struct_value () [template]
 // CHECK:STDOUT:   %struct: %C = struct_value () [template]
-// CHECK:STDOUT:   %.12: type = assoc_entity_type @AddAssign, %Op.type.4 [template]
+// CHECK:STDOUT:   %.12: type = assoc_entity_type %.5, %Op.type.4 [template]
 // CHECK:STDOUT:   %.13: %.12 = assoc_entity element0, imports.%import_ref.10 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 1
toolchain/check/testdata/operators/overloaded/inc.carbon

@@ -42,7 +42,7 @@ fn TestOp() {
 // CHECK:STDOUT:   %TestOp: %TestOp.type = struct_value () [template]
 // CHECK:STDOUT:   %.7: type = ptr_type %.1 [template]
 // CHECK:STDOUT:   %struct: %C = struct_value () [template]
-// CHECK:STDOUT:   %.8: type = assoc_entity_type @Inc, %Op.type.2 [template]
+// CHECK:STDOUT:   %.8: type = assoc_entity_type %.2, %Op.type.2 [template]
 // CHECK:STDOUT:   %.9: %.8 = assoc_entity element0, imports.%import_ref.5 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 2 - 2
toolchain/check/testdata/operators/overloaded/left_shift.carbon

@@ -57,11 +57,11 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %.9: <witness> = interface_witness (%Op.3) [template]
 // CHECK:STDOUT:   %TestOp.type: type = fn_type @TestOp [template]
 // CHECK:STDOUT:   %TestOp: %TestOp.type = struct_value () [template]
-// CHECK:STDOUT:   %.10: type = assoc_entity_type @LeftShift, %Op.type.2 [template]
+// CHECK:STDOUT:   %.10: type = assoc_entity_type %.2, %Op.type.2 [template]
 // CHECK:STDOUT:   %.11: %.10 = assoc_entity element0, imports.%import_ref.9 [template]
 // CHECK:STDOUT:   %TestAssign.type: type = fn_type @TestAssign [template]
 // CHECK:STDOUT:   %TestAssign: %TestAssign.type = struct_value () [template]
-// CHECK:STDOUT:   %.12: type = assoc_entity_type @LeftShiftAssign, %Op.type.4 [template]
+// CHECK:STDOUT:   %.12: type = assoc_entity_type %.6, %Op.type.4 [template]
 // CHECK:STDOUT:   %.13: %.12 = assoc_entity element0, imports.%import_ref.10 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 2 - 2
toolchain/check/testdata/operators/overloaded/mod.carbon

@@ -57,11 +57,11 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %.9: <witness> = interface_witness (%Op.3) [template]
 // CHECK:STDOUT:   %TestOp.type: type = fn_type @TestOp [template]
 // CHECK:STDOUT:   %TestOp: %TestOp.type = struct_value () [template]
-// CHECK:STDOUT:   %.10: type = assoc_entity_type @Mod, %Op.type.2 [template]
+// CHECK:STDOUT:   %.10: type = assoc_entity_type %.2, %Op.type.2 [template]
 // CHECK:STDOUT:   %.11: %.10 = assoc_entity element0, imports.%import_ref.9 [template]
 // CHECK:STDOUT:   %TestAssign.type: type = fn_type @TestAssign [template]
 // CHECK:STDOUT:   %TestAssign: %TestAssign.type = struct_value () [template]
-// CHECK:STDOUT:   %.12: type = assoc_entity_type @ModAssign, %Op.type.4 [template]
+// CHECK:STDOUT:   %.12: type = assoc_entity_type %.6, %Op.type.4 [template]
 // CHECK:STDOUT:   %.13: %.12 = assoc_entity element0, imports.%import_ref.10 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 2 - 2
toolchain/check/testdata/operators/overloaded/mul.carbon

@@ -57,11 +57,11 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %.9: <witness> = interface_witness (%Op.3) [template]
 // CHECK:STDOUT:   %TestOp.type: type = fn_type @TestOp [template]
 // CHECK:STDOUT:   %TestOp: %TestOp.type = struct_value () [template]
-// CHECK:STDOUT:   %.10: type = assoc_entity_type @Mul, %Op.type.2 [template]
+// CHECK:STDOUT:   %.10: type = assoc_entity_type %.2, %Op.type.2 [template]
 // CHECK:STDOUT:   %.11: %.10 = assoc_entity element0, imports.%import_ref.9 [template]
 // CHECK:STDOUT:   %TestAssign.type: type = fn_type @TestAssign [template]
 // CHECK:STDOUT:   %TestAssign: %TestAssign.type = struct_value () [template]
-// CHECK:STDOUT:   %.12: type = assoc_entity_type @MulAssign, %Op.type.4 [template]
+// CHECK:STDOUT:   %.12: type = assoc_entity_type %.6, %Op.type.4 [template]
 // CHECK:STDOUT:   %.13: %.12 = assoc_entity element0, imports.%import_ref.10 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 1
toolchain/check/testdata/operators/overloaded/negate.carbon

@@ -41,7 +41,7 @@ fn TestOp(a: C) -> C {
 // CHECK:STDOUT:   %struct: %C = struct_value () [template]
 // CHECK:STDOUT:   %TestOp.type: type = fn_type @TestOp [template]
 // CHECK:STDOUT:   %TestOp: %TestOp.type = struct_value () [template]
-// CHECK:STDOUT:   %.6: type = assoc_entity_type @Negate, %Op.type.2 [template]
+// CHECK:STDOUT:   %.6: type = assoc_entity_type %.2, %Op.type.2 [template]
 // CHECK:STDOUT:   %.7: %.6 = assoc_entity element0, imports.%import_ref.5 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 8 - 8
toolchain/check/testdata/operators/overloaded/ordered.carbon

@@ -104,19 +104,19 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT:   %TestLess.type: type = fn_type @TestLess [template]
 // CHECK:STDOUT:   %TestLess: %TestLess.type = struct_value () [template]
 // CHECK:STDOUT:   %.5: type = ptr_type %.1 [template]
-// CHECK:STDOUT:   %.6: type = assoc_entity_type @Ordered, %Less.type.2 [template]
+// CHECK:STDOUT:   %.6: type = assoc_entity_type %.2, %Less.type.2 [template]
 // CHECK:STDOUT:   %.7: %.6 = assoc_entity element0, imports.%import_ref.12 [template]
 // CHECK:STDOUT:   %TestLessEqual.type: type = fn_type @TestLessEqual [template]
 // CHECK:STDOUT:   %TestLessEqual: %TestLessEqual.type = struct_value () [template]
-// CHECK:STDOUT:   %.8: type = assoc_entity_type @Ordered, %LessOrEquivalent.type.2 [template]
+// CHECK:STDOUT:   %.8: type = assoc_entity_type %.2, %LessOrEquivalent.type.2 [template]
 // CHECK:STDOUT:   %.9: %.8 = assoc_entity element1, imports.%import_ref.13 [template]
 // CHECK:STDOUT:   %TestGreater.type: type = fn_type @TestGreater [template]
 // CHECK:STDOUT:   %TestGreater: %TestGreater.type = struct_value () [template]
-// CHECK:STDOUT:   %.10: type = assoc_entity_type @Ordered, %Greater.type.2 [template]
+// CHECK:STDOUT:   %.10: type = assoc_entity_type %.2, %Greater.type.2 [template]
 // CHECK:STDOUT:   %.11: %.10 = assoc_entity element2, imports.%import_ref.14 [template]
 // CHECK:STDOUT:   %TestGreaterEqual.type: type = fn_type @TestGreaterEqual [template]
 // CHECK:STDOUT:   %TestGreaterEqual: %TestGreaterEqual.type = struct_value () [template]
-// CHECK:STDOUT:   %.12: type = assoc_entity_type @Ordered, %GreaterOrEquivalent.type.2 [template]
+// CHECK:STDOUT:   %.12: type = assoc_entity_type %.2, %GreaterOrEquivalent.type.2 [template]
 // CHECK:STDOUT:   %.13: %.12 = assoc_entity element3, imports.%import_ref.15 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -386,25 +386,25 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT:   %Self: %.4 = bind_symbolic_name Self 0 [symbolic]
 // CHECK:STDOUT:   %Less.type: type = fn_type @Less [template]
 // CHECK:STDOUT:   %Less: %Less.type = struct_value () [template]
-// CHECK:STDOUT:   %.5: type = assoc_entity_type @Ordered, %Less.type [template]
+// CHECK:STDOUT:   %.5: type = assoc_entity_type %.4, %Less.type [template]
 // CHECK:STDOUT:   %.6: %.5 = assoc_entity element0, imports.%import_ref.12 [template]
 // CHECK:STDOUT:   %TestLessEqual.type: type = fn_type @TestLessEqual [template]
 // CHECK:STDOUT:   %TestLessEqual: %TestLessEqual.type = struct_value () [template]
 // CHECK:STDOUT:   %LessOrEquivalent.type: type = fn_type @LessOrEquivalent [template]
 // CHECK:STDOUT:   %LessOrEquivalent: %LessOrEquivalent.type = struct_value () [template]
-// CHECK:STDOUT:   %.7: type = assoc_entity_type @Ordered, %LessOrEquivalent.type [template]
+// CHECK:STDOUT:   %.7: type = assoc_entity_type %.4, %LessOrEquivalent.type [template]
 // CHECK:STDOUT:   %.8: %.7 = assoc_entity element1, imports.%import_ref.13 [template]
 // CHECK:STDOUT:   %TestGreater.type: type = fn_type @TestGreater [template]
 // CHECK:STDOUT:   %TestGreater: %TestGreater.type = struct_value () [template]
 // CHECK:STDOUT:   %Greater.type: type = fn_type @Greater [template]
 // CHECK:STDOUT:   %Greater: %Greater.type = struct_value () [template]
-// CHECK:STDOUT:   %.9: type = assoc_entity_type @Ordered, %Greater.type [template]
+// CHECK:STDOUT:   %.9: type = assoc_entity_type %.4, %Greater.type [template]
 // CHECK:STDOUT:   %.10: %.9 = assoc_entity element2, imports.%import_ref.14 [template]
 // CHECK:STDOUT:   %TestGreaterEqual.type: type = fn_type @TestGreaterEqual [template]
 // CHECK:STDOUT:   %TestGreaterEqual: %TestGreaterEqual.type = struct_value () [template]
 // CHECK:STDOUT:   %GreaterOrEquivalent.type: type = fn_type @GreaterOrEquivalent [template]
 // CHECK:STDOUT:   %GreaterOrEquivalent: %GreaterOrEquivalent.type = struct_value () [template]
-// CHECK:STDOUT:   %.11: type = assoc_entity_type @Ordered, %GreaterOrEquivalent.type [template]
+// CHECK:STDOUT:   %.11: type = assoc_entity_type %.4, %GreaterOrEquivalent.type [template]
 // CHECK:STDOUT:   %.12: %.11 = assoc_entity element3, imports.%import_ref.15 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 2 - 2
toolchain/check/testdata/operators/overloaded/right_shift.carbon

@@ -57,11 +57,11 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %.9: <witness> = interface_witness (%Op.3) [template]
 // CHECK:STDOUT:   %TestOp.type: type = fn_type @TestOp [template]
 // CHECK:STDOUT:   %TestOp: %TestOp.type = struct_value () [template]
-// CHECK:STDOUT:   %.10: type = assoc_entity_type @RightShift, %Op.type.2 [template]
+// CHECK:STDOUT:   %.10: type = assoc_entity_type %.2, %Op.type.2 [template]
 // CHECK:STDOUT:   %.11: %.10 = assoc_entity element0, imports.%import_ref.9 [template]
 // CHECK:STDOUT:   %TestAssign.type: type = fn_type @TestAssign [template]
 // CHECK:STDOUT:   %TestAssign: %TestAssign.type = struct_value () [template]
-// CHECK:STDOUT:   %.12: type = assoc_entity_type @RightShiftAssign, %Op.type.4 [template]
+// CHECK:STDOUT:   %.12: type = assoc_entity_type %.6, %Op.type.4 [template]
 // CHECK:STDOUT:   %.13: %.12 = assoc_entity element0, imports.%import_ref.10 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 2 - 2
toolchain/check/testdata/operators/overloaded/sub.carbon

@@ -57,11 +57,11 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %.9: <witness> = interface_witness (%Op.3) [template]
 // CHECK:STDOUT:   %TestOp.type: type = fn_type @TestOp [template]
 // CHECK:STDOUT:   %TestOp: %TestOp.type = struct_value () [template]
-// CHECK:STDOUT:   %.10: type = assoc_entity_type @Sub, %Op.type.2 [template]
+// CHECK:STDOUT:   %.10: type = assoc_entity_type %.2, %Op.type.2 [template]
 // CHECK:STDOUT:   %.11: %.10 = assoc_entity element0, imports.%import_ref.9 [template]
 // CHECK:STDOUT:   %TestAssign.type: type = fn_type @TestAssign [template]
 // CHECK:STDOUT:   %TestAssign: %TestAssign.type = struct_value () [template]
-// CHECK:STDOUT:   %.12: type = assoc_entity_type @SubAssign, %Op.type.4 [template]
+// CHECK:STDOUT:   %.12: type = assoc_entity_type %.6, %Op.type.4 [template]
 // CHECK:STDOUT:   %.13: %.12 = assoc_entity element0, imports.%import_ref.10 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 5 - 4
toolchain/sem_ir/file.cpp

@@ -245,11 +245,12 @@ static auto StringifyTypeExprImpl(const SemIR::File& outer_sem_ir,
           out << "<associated ";
           steps.push_back(step.Next());
           push_inst_id(sem_ir.types().GetInstId(inst.entity_type_id));
+        } else if (step.index == 1) {
+          out << " in ";
+          steps.push_back(step.Next());
+          push_inst_id(sem_ir.types().GetInstId(inst.interface_type_id));
         } else {
-          auto interface_name_id =
-              sem_ir.interfaces().Get(inst.interface_id).name_id;
-          out << " in " << sem_ir.names().GetFormatted(interface_name_id)
-              << ">";
+          out << ">";
         }
         break;
       }

+ 1 - 1
toolchain/sem_ir/typed_insts.h

@@ -213,7 +213,7 @@ struct AssociatedEntityType {
            .constant_kind = InstConstantKind::Conditional});
 
   TypeId type_id;
-  InterfaceId interface_id;
+  TypeId interface_type_id;
   TypeId entity_type_id;
 };