Просмотр исходного кода

Treat associated constants as entities parameterized by Self (#4837)

Add a full entity representation for associated constants, and build a
`Generic` object for them. This `Generic` is parameterized by the
enclosing `Self` type, allowing the use of `Self` within the type of the
associated constant to be supported.

When performing impl lookup for an associated constant, produce the type
with the provided self type substituted for its `Self` along with any
generic parameters of the interface.

Split the handling of associated constant declarations into two parts,
corresponding to the code before the `=`, and the code between the `=`
and `;` (if any). The former goes into the generic declaration region;
the latter into the generic definition region. This prepares us to
handle the default value for an associated constant, but for now we're
just storing the information and not actually using it.

Remove the entity type field from `assoc_entity_type`, because it's
almost unused and is an attractive nuisance -- it must necessarily be a
type in the generic scope of the associated constant rather than in the
scope of the instruction (because there is no `Self` anywhere else),
which means that it's hard to substitute into or derive meaning from.

See `toolchain/check/testdata/impl/assoc_const_self.carbon` for tests of
the new functionality; these used to cause the toolchain to crash.
Richard Smith 1 год назад
Родитель
Сommit
5f888e1124
100 измененных файлов с 3631 добавлено и 1652 удалено
  1. 2 14
      toolchain/check/BUILD
  2. 15 4
      toolchain/check/context.cpp
  3. 11 3
      toolchain/check/context.h
  4. 1 2
      toolchain/check/eval.cpp
  5. 5 0
      toolchain/check/generic.cpp
  6. 1 0
      toolchain/check/generic.h
  7. 13 13
      toolchain/check/handle_binding_pattern.cpp
  8. 164 69
      toolchain/check/handle_let_and_var.cpp
  9. 17 3
      toolchain/check/handle_where.cpp
  10. 56 74
      toolchain/check/impl.cpp
  11. 88 24
      toolchain/check/import_ref.cpp
  12. 78 2
      toolchain/check/interface.cpp
  13. 16 0
      toolchain/check/interface.h
  14. 5 4
      toolchain/check/keyword_modifier_set.h
  15. 19 16
      toolchain/check/member_access.cpp
  16. 12 0
      toolchain/check/node_stack.h
  17. 1 1
      toolchain/check/testdata/builtins/bool/eq.carbon
  18. 1 1
      toolchain/check/testdata/builtins/bool/neq.carbon
  19. 0 3
      toolchain/check/testdata/class/generic/member_out_of_line.carbon
  20. 4 4
      toolchain/check/testdata/function/builtin/method.carbon
  21. 57 57
      toolchain/check/testdata/function/builtin/no_prelude/call_from_operator.carbon
  22. 3 5
      toolchain/check/testdata/function/declaration/no_prelude/name_poisoning.carbon
  23. 826 0
      toolchain/check/testdata/impl/assoc_const_self.carbon
  24. 9 11
      toolchain/check/testdata/impl/compound.carbon
  25. 5 6
      toolchain/check/testdata/impl/extend_impl.carbon
  26. 22 22
      toolchain/check/testdata/impl/extend_impl_generic.carbon
  27. 4 4
      toolchain/check/testdata/impl/fail_call_invalid.carbon
  28. 6 6
      toolchain/check/testdata/impl/fail_extend_impl_forall.carbon
  29. 6 8
      toolchain/check/testdata/impl/fail_impl_as_scope.carbon
  30. 9 11
      toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon
  31. 3 3
      toolchain/check/testdata/impl/fail_self_type_mismatch.carbon
  32. 82 45
      toolchain/check/testdata/impl/fail_todo_use_assoc_const.carbon
  33. 3 4
      toolchain/check/testdata/impl/impl_as.carbon
  34. 3 4
      toolchain/check/testdata/impl/impl_forall.carbon
  35. 7 8
      toolchain/check/testdata/impl/lookup/alias.carbon
  36. 7 8
      toolchain/check/testdata/impl/lookup/fail_alias_impl_not_found.carbon
  37. 4 5
      toolchain/check/testdata/impl/lookup/fail_todo_undefined_impl.carbon
  38. 42 47
      toolchain/check/testdata/impl/lookup/generic.carbon
  39. 4 4
      toolchain/check/testdata/impl/lookup/instance_method.carbon
  40. 27 27
      toolchain/check/testdata/impl/lookup/no_prelude/impl_forall.carbon
  41. 69 88
      toolchain/check/testdata/impl/lookup/no_prelude/import.carbon
  42. 53 58
      toolchain/check/testdata/impl/lookup/no_prelude/specific_args.carbon
  43. 11 14
      toolchain/check/testdata/impl/lookup/transitive.carbon
  44. 30 38
      toolchain/check/testdata/impl/multiple_extend.carbon
  45. 3 4
      toolchain/check/testdata/impl/no_prelude/basic.carbon
  46. 13 6
      toolchain/check/testdata/impl/no_prelude/fail_impl_bad_assoc_const.carbon
  47. 290 92
      toolchain/check/testdata/impl/no_prelude/impl_assoc_const.carbon
  48. 33 33
      toolchain/check/testdata/impl/no_prelude/import_builtin_call.carbon
  49. 10 12
      toolchain/check/testdata/impl/no_prelude/import_extend_impl.carbon
  50. 326 103
      toolchain/check/testdata/impl/no_prelude/import_interface_assoc_const.carbon
  51. 8 8
      toolchain/check/testdata/impl/no_prelude/import_self.carbon
  52. 21 23
      toolchain/check/testdata/impl/no_prelude/import_use_generic.carbon
  53. 80 83
      toolchain/check/testdata/impl/no_prelude/interface_args.carbon
  54. 3 3
      toolchain/check/testdata/impl/no_prelude/self_in_class.carbon
  55. 6 6
      toolchain/check/testdata/impl/no_prelude/self_in_signature.carbon
  56. 1 1
      toolchain/check/testdata/index/fail_negative_indexing.carbon
  57. 23 10
      toolchain/check/testdata/interface/assoc_const.carbon
  58. 16 7
      toolchain/check/testdata/interface/fail_assoc_const_bad_default.carbon
  59. 40 23
      toolchain/check/testdata/interface/fail_todo_assoc_const_default.carbon
  60. 5 6
      toolchain/check/testdata/interface/fail_todo_define_default_fn_inline.carbon
  61. 5 8
      toolchain/check/testdata/interface/fail_todo_define_default_fn_out_of_line.carbon
  62. 76 38
      toolchain/check/testdata/interface/member_lookup.carbon
  63. 25 28
      toolchain/check/testdata/interface/no_prelude/assoc_const_in_generic.carbon
  64. 3 4
      toolchain/check/testdata/interface/no_prelude/basic.carbon
  65. 4 4
      toolchain/check/testdata/interface/no_prelude/default_fn.carbon
  66. 0 2
      toolchain/check/testdata/interface/no_prelude/fail_add_member_outside_definition.carbon
  67. 19 7
      toolchain/check/testdata/interface/no_prelude/fail_assoc_const_not_binding.carbon
  68. 2 1
      toolchain/check/testdata/interface/no_prelude/fail_assoc_const_template.carbon
  69. 6 7
      toolchain/check/testdata/interface/no_prelude/fail_duplicate.carbon
  70. 12 3
      toolchain/check/testdata/interface/no_prelude/fail_incomplete_type.carbon
  71. 3 5
      toolchain/check/testdata/interface/no_prelude/fail_lookup_undefined.carbon
  72. 18 13
      toolchain/check/testdata/interface/no_prelude/fail_member_lookup.carbon
  73. 6 6
      toolchain/check/testdata/interface/no_prelude/fail_modifiers.carbon
  74. 3 5
      toolchain/check/testdata/interface/no_prelude/fail_redeclare_member.carbon
  75. 8 6
      toolchain/check/testdata/interface/no_prelude/fail_todo_facet_lookup.carbon
  76. 6 6
      toolchain/check/testdata/interface/no_prelude/fail_todo_generic_default_fn.carbon
  77. 5 6
      toolchain/check/testdata/interface/no_prelude/fail_todo_modifiers.carbon
  78. 9 10
      toolchain/check/testdata/interface/no_prelude/generic.carbon
  79. 16 11
      toolchain/check/testdata/interface/no_prelude/generic_binding_after_assoc_const.carbon
  80. 15 17
      toolchain/check/testdata/interface/no_prelude/generic_import.carbon
  81. 55 65
      toolchain/check/testdata/interface/no_prelude/import.carbon
  82. 4 5
      toolchain/check/testdata/interface/no_prelude/local.carbon
  83. 3 3
      toolchain/check/testdata/interface/no_prelude/self.carbon
  84. 44 29
      toolchain/check/testdata/interface/todo_define_not_default.carbon
  85. 21 14
      toolchain/check/testdata/let/compile_time_bindings.carbon
  86. 1 1
      toolchain/check/testdata/operators/builtin/fail_type_mismatch_once.carbon
  87. 9 9
      toolchain/check/testdata/operators/overloaded/no_prelude/index.carbon
  88. 41 41
      toolchain/check/testdata/return/no_prelude/import_convert_function.carbon
  89. 1 1
      toolchain/check/testdata/tuple/access/fail_negative_indexing.carbon
  90. 52 21
      toolchain/check/testdata/where_expr/constraints.carbon
  91. 31 11
      toolchain/check/testdata/where_expr/designator.carbon
  92. 47 25
      toolchain/check/testdata/where_expr/dot_self_index.carbon
  93. 258 84
      toolchain/check/testdata/where_expr/equal_rewrite.carbon
  94. 19 6
      toolchain/check/testdata/where_expr/non_generic.carbon
  95. 1 0
      toolchain/diagnostics/diagnostic_kind.def
  96. 1 0
      toolchain/sem_ir/BUILD
  97. 53 0
      toolchain/sem_ir/associated_constant.h
  98. 2 2
      toolchain/sem_ir/entity_with_params_base.h
  99. 10 0
      toolchain/sem_ir/file.h
  100. 58 8
      toolchain/sem_ir/formatter.cpp

+ 2 - 14
toolchain/check/BUILD

@@ -29,6 +29,7 @@ cc_library(
         "import_cpp.cpp",
         "import_ref.cpp",
         "inst_block_stack.cpp",
+        "interface.cpp",
         "literal.cpp",
         "member_access.cpp",
         "merge.cpp",
@@ -56,6 +57,7 @@ cc_library(
         "import_cpp.h",
         "import_ref.h",
         "inst_block_stack.h",
+        "interface.h",
         "keyword_modifier_set.h",
         "literal.h",
         "member_access.h",
@@ -137,7 +139,6 @@ cc_library(
         ":context",
         ":dump",
         ":impl",
-        ":interface",
         ":pointer_dereference",
         ":sem_ir_diagnostic_converter",
         "//common:check",
@@ -210,19 +211,6 @@ cc_library(
     ],
 )
 
-cc_library(
-    name = "interface",
-    srcs = ["interface.cpp"],
-    hdrs = ["interface.h"],
-    deps = [
-        ":context",
-        "//common:check",
-        "//toolchain/sem_ir:file",
-        "//toolchain/sem_ir:inst",
-        "//toolchain/sem_ir:typed_insts",
-    ],
-)
-
 cc_library(
     name = "node_stack",
     srcs = ["node_stack.cpp"],

+ 15 - 4
toolchain/check/context.cpp

@@ -1454,6 +1454,19 @@ auto Context::RequireDefinedType(SemIR::TypeId type_id, SemIR::LocId loc_id,
       }
     }
     // TODO: Finish facet type resolution.
+    //
+    // Note that we will need Self to be passed into facet type resolution.
+    // The `.Self` of a facet type created by `where` will then be bound to the
+    // provided self type.
+    //
+    // For example, in `T:! X where ...`, we will bind the `.Self` of the
+    // `where` facet type to `T`, and in `(X where ...) where ...`, we will bind
+    // the inner `.Self` to the outer `.Self`.
+    //
+    // If the facet type contains a rewrite, we may have deferred converting the
+    // rewritten value to the type of the associated constant. That conversion
+    // should also be performed as part of resolution, and may depend on the
+    // Self type.
   }
 
   return true;
@@ -1516,11 +1529,9 @@ auto Context::GetTupleType(llvm::ArrayRef<SemIR::TypeId> type_ids)
                                        type_blocks().AddCanonical(type_ids));
 }
 
-auto Context::GetAssociatedEntityType(SemIR::TypeId interface_type_id,
-                                      SemIR::TypeId entity_type_id)
+auto Context::GetAssociatedEntityType(SemIR::TypeId interface_type_id)
     -> SemIR::TypeId {
-  return GetTypeImpl<SemIR::AssociatedEntityType>(*this, interface_type_id,
-                                                  entity_type_id);
+  return GetTypeImpl<SemIR::AssociatedEntityType>(*this, interface_type_id);
 }
 
 auto Context::GetSingletonType(SemIR::InstId singleton_id) -> SemIR::TypeId {

+ 11 - 3
toolchain/check/context.h

@@ -467,9 +467,14 @@ 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::TypeId interface_type_id,
-                               SemIR::TypeId entity_type_id) -> SemIR::TypeId;
+  // Gets the type to use for an unbound associated entity declared in this
+  // interface. For example, this is the type of `I.T` after
+  // `interface I { let T:! type; }`.
+  // The name of the interface is used for diagnostics.
+  // TODO: Should we use a different type for each such entity, or the same type
+  // for all associated entities?
+  auto GetAssociatedEntityType(SemIR::TypeId interface_type_id)
+      -> SemIR::TypeId;
 
   // Gets a singleton type. The returned type will be complete. Requires that
   // `singleton_id` is already validated to be a singleton.
@@ -628,6 +633,9 @@ class Context {
   auto interfaces() -> ValueStore<SemIR::InterfaceId>& {
     return sem_ir().interfaces();
   }
+  auto associated_constants() -> ValueStore<SemIR::AssociatedConstantId>& {
+    return sem_ir().associated_constants();
+  }
   auto facet_types() -> CanonicalValueStore<SemIR::FacetTypeId>& {
     return sem_ir().facet_types();
   }

+ 1 - 2
toolchain/check/eval.cpp

@@ -1568,8 +1568,7 @@ static auto TryEvalInstInContext(EvalContext& eval_context,
                                         &SemIR::AssociatedEntity::type_id);
     case SemIR::AssociatedEntityType::Kind:
       return RebuildIfFieldsAreConstant(
-          eval_context, inst, &SemIR::AssociatedEntityType::interface_type_id,
-          &SemIR::AssociatedEntityType::entity_type_id);
+          eval_context, inst, &SemIR::AssociatedEntityType::interface_type_id);
     case SemIR::BoundMethod::Kind:
       return RebuildIfFieldsAreConstant(eval_context, inst,
                                         &SemIR::BoundMethod::type_id,

+ 5 - 0
toolchain/check/generic.cpp

@@ -9,6 +9,7 @@
 #include "toolchain/check/eval.h"
 #include "toolchain/check/generic_region_stack.h"
 #include "toolchain/check/subst.h"
+#include "toolchain/sem_ir/generic.h"
 #include "toolchain/sem_ir/ids.h"
 #include "toolchain/sem_ir/inst.h"
 #include "toolchain/sem_ir/typed_insts.h"
@@ -506,6 +507,10 @@ auto GetInstForSpecific(Context& context, SemIR::SpecificId specific_id)
                           .callee_id = generic.decl_id,
                           .specific_id = specific_id}));
     }
+    case SemIR::AssociatedConstantDecl::Kind: {
+      // TODO: We don't have a good instruction to use here.
+      return generic.decl_id;
+    }
     default: {
       CARBON_FATAL("Unknown kind for generic declaration {0}", decl);
     }

+ 1 - 0
toolchain/check/generic.h

@@ -84,6 +84,7 @@ auto ResolveSpecificDefinition(Context& context, SemIRLoc loc,
                                SemIR::SpecificId specific_id) -> bool;
 
 // Returns an instruction describing the entity named by the given specific.
+// This is used to name the entity in diagnostics.
 auto GetInstForSpecific(Context& context, SemIR::SpecificId specific_id)
     -> SemIR::InstId;
 

+ 13 - 13
toolchain/check/handle_binding_pattern.cpp

@@ -159,23 +159,23 @@ static auto HandleAnyBindingPattern(Context& context, Parse::NodeId node_id,
       return context.emitter().Build(type_node, IncompleteTypeInAssociatedDecl,
                                      cast_type_id);
     });
-    context.entity_names().Add(
+
+    SemIR::AssociatedConstantDecl assoc_const_decl = {
+        .type_id = cast_type_id,
+        .assoc_const_id = SemIR::AssociatedConstantId::None,
+        .decl_block_id = SemIR::InstBlockId::None};
+    auto decl_id = context.AddPlaceholderInstInNoBlock(SemIR::LocIdAndInst(
+        context.parse_tree().As<Parse::CompileTimeBindingPatternId>(node_id),
+        assoc_const_decl));
+    assoc_const_decl.assoc_const_id = context.associated_constants().Add(
         {.name_id = name_id,
          .parent_scope_id = context.scope_stack().PeekNameScopeId(),
-         .bind_index = SemIR::CompileTimeBindIndex::None});
+         .decl_id = decl_id,
+         .generic_id = SemIR::GenericId::None,
+         .default_value_id = SemIR::InstId::None});
+    context.ReplaceInstBeforeConstantUse(decl_id, assoc_const_decl);
 
-    SemIR::InstId decl_id = context.AddInst<SemIR::AssociatedConstantDecl>(
-        context.parse_tree().As<Parse::CompileTimeBindingPatternId>(node_id),
-        {cast_type_id, name_id});
     context.node_stack().Push(node_id, decl_id);
-
-    // Add an associated entity name to the interface scope.
-    auto assoc_id = BuildAssociatedEntity(
-        context, parent_interface_decl->interface_id, decl_id);
-    auto name_context =
-        context.decl_name_stack().MakeUnqualifiedName(node_id, name_id);
-    context.decl_name_stack().AddNameOrDiagnose(
-        name_context, assoc_id, introducer.modifier_set.GetAccessKind());
     return true;
   }
 

+ 164 - 69
toolchain/check/handle_let_and_var.cpp

@@ -5,19 +5,75 @@
 #include "toolchain/check/context.h"
 #include "toolchain/check/convert.h"
 #include "toolchain/check/decl_introducer_state.h"
+#include "toolchain/check/generic.h"
 #include "toolchain/check/handle.h"
 #include "toolchain/check/interface.h"
+#include "toolchain/check/keyword_modifier_set.h"
 #include "toolchain/check/modifiers.h"
 #include "toolchain/check/pattern_match.h"
 #include "toolchain/check/return.h"
 #include "toolchain/diagnostics/diagnostic_emitter.h"
 #include "toolchain/lex/token_kind.h"
+#include "toolchain/parse/node_kind.h"
+#include "toolchain/sem_ir/ids.h"
 #include "toolchain/sem_ir/inst.h"
 #include "toolchain/sem_ir/name_scope.h"
 #include "toolchain/sem_ir/typed_insts.h"
 
 namespace Carbon::Check {
 
+// Handles the start of a declaration of an associated constant.
+static auto StartAssociatedConstant(Context& context) -> void {
+  // An associated constant is always generic.
+  StartGenericDecl(context);
+  // Collect the declarations nested in the associated constant in a decl
+  // block. This is popped by FinishAssociatedConstantDecl.
+  context.inst_block_stack().Push();
+}
+
+// Handles the end of the declaration region of an associated constant. This is
+// called at the `=` or the `;` of the declaration, whichever comes first.
+static auto EndAssociatedConstantDeclRegion(Context& context,
+                                            SemIR::InterfaceId interface_id)
+    -> void {
+  // TODO: Stop special-casing tuple patterns once they behave like other
+  // patterns.
+  if (context.node_stack().PeekIs(Parse::NodeKind::TuplePattern)) {
+    DiscardGenericDecl(context);
+    return;
+  }
+
+  // Peek the pattern. For a valid associated constant, the corresponding
+  // instruction will be an `AssociatedConstantDecl` instruction.
+  auto decl_id = context.node_stack().PeekPattern();
+  auto assoc_const_decl =
+      context.insts().TryGetAs<SemIR::AssociatedConstantDecl>(decl_id);
+  if (!assoc_const_decl) {
+    // The pattern wasn't suitable for an associated constant. We'll detect
+    // and diagnose this later. For now, just clean up the generic stack.
+    DiscardGenericDecl(context);
+    return;
+  }
+
+  // Finish the declaration region of this generic.
+  auto& assoc_const =
+      context.associated_constants().Get(assoc_const_decl->assoc_const_id);
+  assoc_const.generic_id = BuildGenericDecl(context, decl_id);
+
+  // Build a corresponding associated entity and add it into scope. Note
+  // that we do this outside the generic region.
+  // TODO: The instruction is added to the associated constant's decl block.
+  // It probably should be in the interface's body instead.
+  auto assoc_id = BuildAssociatedEntity(context, interface_id, decl_id);
+  auto name_context = context.decl_name_stack().MakeUnqualifiedName(
+      context.node_stack().PeekNodeId(), assoc_const.name_id);
+  auto access_kind = context.decl_introducer_state_stack()
+                         .innermost()
+                         .modifier_set.GetAccessKind();
+  context.decl_name_stack().AddNameOrDiagnose(name_context, assoc_id,
+                                              access_kind);
+}
+
 template <Lex::TokenKind::RawEnumType Kind>
 static auto HandleIntroducer(Context& context, Parse::NodeId node_id) -> bool {
   context.decl_introducer_state_stack().Push<Kind>();
@@ -31,6 +87,10 @@ static auto HandleIntroducer(Context& context, Parse::NodeId node_id) -> bool {
 }
 
 auto HandleParseNode(Context& context, Parse::LetIntroducerId node_id) -> bool {
+  if (context.GetCurrentScopeAs<SemIR::InterfaceDecl>()) {
+    StartAssociatedConstant(context);
+  }
+
   return HandleIntroducer<Lex::TokenKind::Let>(context, node_id);
 }
 
@@ -129,6 +189,13 @@ static auto HandleInitializer(Context& context, Parse::NodeId node_id) -> bool {
 
 auto HandleParseNode(Context& context, Parse::LetInitializerId node_id)
     -> bool {
+  if (auto interface_decl = context.GetCurrentScopeAs<SemIR::InterfaceDecl>()) {
+    EndAssociatedConstantDeclRegion(context, interface_decl->interface_id);
+
+    // Start building the definition region of the constant.
+    StartGenericDefinition(context);
+  }
+
   return HandleInitializer(context, node_id);
 }
 
@@ -141,9 +208,10 @@ namespace {
 // State from HandleDecl, returned for type-specific handling.
 struct DeclInfo {
   // The optional initializer.
-  std::optional<SemIR::InstId> init_id = std::nullopt;
+  SemIR::InstId init_id = SemIR::InstId::None;
+  // The pattern. For an associated constant, this is the associated constant
+  // declaration.
   SemIR::InstId pattern_id = SemIR::InstId::None;
-  std::optional<SemIR::Inst> parent_scope_inst = std::nullopt;
   DeclIntroducerState introducer = DeclIntroducerState();
 };
 }  // namespace
@@ -153,143 +221,170 @@ struct DeclInfo {
 // handle_binding_pattern. These should really be better unified.
 template <const Lex::TokenKind& IntroducerTokenKind,
           const Parse::NodeKind& IntroducerNodeKind,
-          const Parse::NodeKind& InitializerNodeKind, typename NodeT>
-static auto HandleDecl(Context& context, NodeT node_id)
-    -> std::optional<DeclInfo> {
-  std::optional<DeclInfo> decl_info = DeclInfo();
+          const Parse::NodeKind& InitializerNodeKind>
+static auto HandleDecl(Context& context) -> DeclInfo {
+  DeclInfo decl_info = DeclInfo();
 
   // Handle the optional initializer.
   if (context.node_stack().PeekNextIs(InitializerNodeKind)) {
-    decl_info->init_id = context.node_stack().PopExpr();
+    decl_info.init_id = context.node_stack().PopExpr();
     context.node_stack().PopAndDiscardSoloNodeId<InitializerNodeKind>();
     if (context.scope_stack().PeekIndex() == ScopeIndex::Package) {
       context.global_init().Suspend();
     }
     context.full_pattern_stack().EndPatternInitializer();
   } else {
+    // For an associated constant declaration, handle the completed declaration
+    // now. We will have done this at the `=` if there was an initializer.
+    if (IntroducerTokenKind == Lex::TokenKind::Let) {
+      if (auto interface_decl =
+              context.GetCurrentScopeAs<SemIR::InterfaceDecl>()) {
+        EndAssociatedConstantDeclRegion(context, interface_decl->interface_id);
+      }
+    }
+
     EndFullPattern(context);
   }
   context.full_pattern_stack().PopFullPattern();
 
-  if (context.node_stack().PeekIs(Parse::NodeKind::TuplePattern)) {
-    if (decl_info->init_id &&
-        context.scope_stack().PeekIndex() == ScopeIndex::Package) {
-      context.global_init().Suspend();
-    }
-    context.TODO(node_id, "tuple pattern in let/var");
-    decl_info = std::nullopt;
-    return decl_info;
+  if (auto [tuple_pattern_node_id, tuple_inst_block_id] =
+          context.node_stack().PopWithNodeIdIf<Parse::NodeKind::TuplePattern>();
+      tuple_inst_block_id) {
+    context.TODO(tuple_pattern_node_id, "tuple pattern in let/var");
+
+    // TODO: Tuple patterns don't behave like other patterns. They are
+    // associated with an InstBlockId on the node stack rather than an InstId,
+    // and leave behind an entry on the subpattern stack and one on the node
+    // stack.
+    context.EndSubpatternAsExpr(SemIR::ErrorInst::SingletonInstId);
+    context.node_stack().PopForSoloNodeId<Parse::NodeKind::TuplePatternStart>();
+    decl_info.pattern_id = SemIR::ErrorInst::SingletonInstId;
+  } else {
+    decl_info.pattern_id = context.node_stack().PopPattern();
   }
 
-  decl_info->pattern_id = context.node_stack().PopPattern();
-
   context.node_stack().PopAndDiscardSoloNodeId<IntroducerNodeKind>();
 
   // Process declaration modifiers.
   // TODO: For a qualified `let` or `var` declaration, this should use the
   // target scope of the name introduced in the declaration. See #2590.
-  decl_info->parent_scope_inst =
+  auto parent_scope_inst =
       context.name_scopes()
           .GetInstIfValid(context.scope_stack().PeekNameScopeId())
           .second;
-  decl_info->introducer =
+  decl_info.introducer =
       context.decl_introducer_state_stack().Pop<IntroducerTokenKind>();
-  CheckAccessModifiersOnDecl(context, decl_info->introducer,
-                             decl_info->parent_scope_inst);
+  CheckAccessModifiersOnDecl(context, decl_info.introducer, parent_scope_inst);
 
   return decl_info;
 }
 
-static auto HandleAssociatedConstantDecl(Context& context,
-                                         Parse::LetDeclId node_id,
-                                         DeclInfo decl_info,
-                                         SemIR::InterfaceDecl interface_scope)
-    -> void {
-  auto pattern = context.insts().GetWithLocId(decl_info.pattern_id);
+// Finishes an associated constant declaration. This is called at the `;` to
+// perform any final steps. The `AssociatedConstantDecl` instruction and the
+// corresponding `AssociatedConstant` entity are built as part of handling the
+// binding pattern, but we still need to finish building the `Generic` object
+// and attach the default value, if any is specified.
+static auto FinishAssociatedConstant(Context& context, Parse::LetDeclId node_id,
+                                     SemIR::InterfaceId interface_id,
+                                     DeclInfo& decl_info) -> void {
+  auto decl = context.insts().TryGetAs<SemIR::AssociatedConstantDecl>(
+      decl_info.pattern_id);
+  if (!decl) {
+    if (decl_info.pattern_id != SemIR::ErrorInst::SingletonInstId) {
+      CARBON_DIAGNOSTIC(ExpectedSymbolicBindingInAssociatedConstant, Error,
+                        "pattern in associated constant declaration must be a "
+                        "single `:!` binding");
+      context.emitter().Emit(context.insts().GetLocId(decl_info.pattern_id),
+                             ExpectedSymbolicBindingInAssociatedConstant);
+    }
+    context.name_scopes()
+        .Get(context.interfaces().Get(interface_id).scope_id)
+        .set_has_error();
+    context.inst_block_stack().Pop();
+    return;
+  }
 
-  if (decl_info.init_id) {
-    // Convert the value to match the type of the pattern.
-    ConvertToValueOfType(context, node_id, *decl_info.init_id,
-                         pattern.inst.type_id());
+  if (decl_info.introducer.modifier_set.HasAnyOf(
+          KeywordModifierSet::Interface)) {
+    context.TODO(decl_info.introducer.modifier_node_id(ModifierOrder::Decl),
+                 "interface modifier");
   }
 
-  if (auto decl = pattern.inst.TryAs<SemIR::AssociatedConstantDecl>();
-      !decl.has_value()) {
-    CARBON_DIAGNOSTIC(ExpectedSymbolicBindingInAssociatedConstant, Error,
-                      "pattern in associated constant declaration must be a "
-                      "single `:!` binding");
-    context.emitter().Emit(pattern.loc_id,
-                           ExpectedSymbolicBindingInAssociatedConstant);
-    context.name_scopes()
-        .Get(context.interfaces().Get(interface_scope.interface_id).scope_id)
-        .set_has_error();
+  // If there was an initializer, convert it and store it on the constant.
+  if (decl_info.init_id.has_value()) {
+    // TODO: Diagnose if the `default` modifier was not used.
+    auto default_value_id = ConvertToValueOfType(
+        context, node_id, decl_info.init_id, decl->type_id);
+    auto& assoc_const =
+        context.associated_constants().Get(decl->assoc_const_id);
+    assoc_const.default_value_id = default_value_id;
+    FinishGenericDefinition(context, assoc_const.generic_id);
+  } else {
+    // TODO: Either allow redeclarations of associated constants or diagnose if
+    // the `default` modifier was used.
   }
+
+  // Store the decl block on the declaration.
+  decl->decl_block_id = context.inst_block_stack().Pop();
+  context.ReplaceInstPreservingConstantValue(decl_info.pattern_id, *decl);
+
+  context.inst_block_stack().AddInstId(decl_info.pattern_id);
 }
 
 auto HandleParseNode(Context& context, Parse::LetDeclId node_id) -> bool {
   auto decl_info =
       HandleDecl<Lex::TokenKind::Let, Parse::NodeKind::LetIntroducer,
-                 Parse::NodeKind::LetInitializer>(context, node_id);
-  if (!decl_info) {
-    return false;
-  }
+                 Parse::NodeKind::LetInitializer>(context);
 
-  RequireDefaultFinalOnlyInInterfaces(context, decl_info->introducer,
-                                      decl_info->parent_scope_inst);
   LimitModifiersOnDecl(
-      context, decl_info->introducer,
+      context, decl_info.introducer,
       KeywordModifierSet::Access | KeywordModifierSet::Interface);
 
-  if (decl_info->introducer.modifier_set.HasAnyOf(
-          KeywordModifierSet::Interface)) {
-    context.TODO(decl_info->introducer.modifier_node_id(ModifierOrder::Decl),
-                 "interface modifier");
-  }
-
   // At interface scope, we are forming an associated constant, which has
   // different rules.
-  if (auto interface_scope = context.GetCurrentScopeAs<SemIR::InterfaceDecl>();
-      interface_scope) {
-    HandleAssociatedConstantDecl(context, node_id, *decl_info,
-                                 *interface_scope);
+  if (auto interface_scope =
+          context.GetCurrentScopeAs<SemIR::InterfaceDecl>()) {
+    FinishAssociatedConstant(context, node_id, interface_scope->interface_id,
+                             decl_info);
     return true;
   }
 
-  if (decl_info->init_id) {
-    LocalPatternMatch(context, decl_info->pattern_id, *decl_info->init_id);
+  // Diagnose interface modifiers given that we're not building an associated
+  // constant. We use this rather than `LimitModifiersOnDecl` to get a more
+  // specific error.
+  RequireDefaultFinalOnlyInInterfaces(context, decl_info.introducer,
+                                      std::nullopt);
+
+  if (decl_info.init_id.has_value()) {
+    LocalPatternMatch(context, decl_info.pattern_id, decl_info.init_id);
   } else {
     CARBON_DIAGNOSTIC(
         ExpectedInitializerAfterLet, Error,
         "expected `=`; `let` declaration must have an initializer");
     context.emitter().Emit(TokenOnly(node_id), ExpectedInitializerAfterLet);
   }
-
   return true;
 }
 
 auto HandleParseNode(Context& context, Parse::VariableDeclId node_id) -> bool {
   auto decl_info =
       HandleDecl<Lex::TokenKind::Var, Parse::NodeKind::VariableIntroducer,
-                 Parse::NodeKind::VariableInitializer>(context, node_id);
-  if (!decl_info) {
-    return false;
-  }
+                 Parse::NodeKind::VariableInitializer>(context);
 
   LimitModifiersOnDecl(
-      context, decl_info->introducer,
+      context, decl_info.introducer,
       KeywordModifierSet::Access | KeywordModifierSet::Returned);
 
   if (context.GetCurrentScopeAs<SemIR::ClassDecl>()) {
-    if (decl_info->init_id) {
+    if (decl_info.init_id.has_value()) {
       // TODO: In a class scope, we should instead save the initializer
       // somewhere so that we can use it as a default.
       context.TODO(node_id, "Field initializer");
     }
     return true;
   }
-  LocalPatternMatch(context, decl_info->pattern_id,
-                    decl_info->init_id.value_or(SemIR::InstId::None));
 
+  LocalPatternMatch(context, decl_info.pattern_id, decl_info.init_id);
   return true;
 }
 

+ 17 - 3
toolchain/check/handle_where.cpp

@@ -62,13 +62,27 @@ auto HandleParseNode(Context& context, Parse::RequirementEqualId node_id)
   auto lhs = context.node_stack().PopExpr();
 
   // Convert rhs to type of lhs.
-  SemIR::InstId rhs_inst_id = ConvertToValueOfType(
-      context, rhs_node, rhs_id, context.insts().Get(lhs).type_id());
+  auto lhs_type_id = context.insts().Get(lhs).type_id();
+  if (context.types().GetConstantId(lhs_type_id).is_symbolic()) {
+    // If the type of the associated constant is symbolic, we defer conversion
+    // until the constraint is resolved, in case it depends on `Self` (which
+    // will now be a reference to `.Self`).
+    // TODO: It would be simpler to always defer this conversion until the
+    // constraint is resolved.
+    // For now we convert to a value expression eagerly because otherwise we'll
+    // often be unable to constant-evaluate the enclosing `where` expression.
+    // TODO: Find another way to handle this that allows us to only convert the
+    // RHS once.
+    rhs_id = ConvertToValueExpr(context, rhs_id);
+  } else {
+    rhs_id = ConvertToValueOfType(context, rhs_node, rhs_id,
+                                  context.insts().Get(lhs).type_id());
+  }
 
   // Build up the list of arguments for the `WhereExpr` inst.
   context.args_type_info_stack().AddInstId(
       context.AddInstInNoBlock<SemIR::RequirementRewrite>(
-          node_id, {.lhs_id = lhs, .rhs_id = rhs_inst_id}));
+          node_id, {.lhs_id = lhs, .rhs_id = rhs_id}));
   return true;
 }
 

+ 56 - 74
toolchain/check/impl.cpp

@@ -6,10 +6,12 @@
 
 #include "toolchain/base/kind_switch.h"
 #include "toolchain/check/context.h"
+#include "toolchain/check/convert.h"
 #include "toolchain/check/eval.h"
 #include "toolchain/check/function.h"
 #include "toolchain/check/generic.h"
 #include "toolchain/check/import_ref.h"
+#include "toolchain/check/interface.h"
 #include "toolchain/diagnostics/diagnostic_emitter.h"
 #include "toolchain/sem_ir/generic.h"
 #include "toolchain/sem_ir/ids.h"
@@ -40,60 +42,6 @@ static auto NotePreviousDecl(Context& context,
   builder.Note(impl.latest_decl_id(), ImplPreviousDeclHere);
 }
 
-// Gets the self specific of a generic declaration that is an interface member,
-// given a specific for an enclosing generic, plus a type to use as `Self`.
-static auto GetSelfSpecificForInterfaceMemberWithSelfType(
-    Context& context, SemIRLoc loc, SemIR::SpecificId enclosing_specific_id,
-    SemIR::GenericId generic_id, SemIR::TypeId self_type_id,
-    SemIR::InstId witness_inst_id) -> SemIR::SpecificId {
-  const auto& generic = context.generics().Get(generic_id);
-  auto bindings = context.inst_blocks().Get(generic.bindings_id);
-
-  llvm::SmallVector<SemIR::InstId> arg_ids;
-  arg_ids.reserve(bindings.size());
-
-  // Start with the enclosing arguments.
-  if (enclosing_specific_id.has_value()) {
-    auto enclosing_specific_args_id =
-        context.specifics().Get(enclosing_specific_id).args_id;
-    auto enclosing_specific_args =
-        context.inst_blocks().Get(enclosing_specific_args_id);
-    arg_ids.assign(enclosing_specific_args.begin(),
-                   enclosing_specific_args.end());
-  }
-
-  // Add the `Self` argument. First find the `Self` binding.
-  auto self_binding =
-      context.insts().GetAs<SemIR::BindSymbolicName>(bindings[arg_ids.size()]);
-  CARBON_CHECK(
-      context.entity_names().Get(self_binding.entity_name_id).name_id ==
-          SemIR::NameId::SelfType,
-      "Expected a Self binding, found {0}", self_binding);
-  // Create a facet value to be the value of `Self` in the interface.
-  // This facet value consists of the type `self_type_id` and a witness that the
-  // type implements `self_binding.type_id`. Note that the witness is incomplete
-  // since we haven't finished defining the implementation here.
-  auto type_inst_id = context.types().GetInstId(self_type_id);
-  auto facet_value_const_id =
-      TryEvalInst(context, SemIR::InstId::None,
-                  SemIR::FacetValue{.type_id = self_binding.type_id,
-                                    .type_inst_id = type_inst_id,
-                                    .witness_inst_id = witness_inst_id});
-  arg_ids.push_back(context.constant_values().GetInstId(facet_value_const_id));
-
-  // Take any trailing argument values from the self specific.
-  // TODO: If these refer to outer arguments, for example in their types, we may
-  // need to perform extra substitutions here.
-  auto self_specific_args = context.inst_blocks().Get(
-      context.specifics().Get(generic.self_specific_id).args_id);
-  for (auto arg_id : self_specific_args.drop_front(arg_ids.size())) {
-    arg_ids.push_back(context.constant_values().GetConstantInstId(arg_id));
-  }
-
-  auto args_id = context.inst_blocks().AddCanonical(arg_ids);
-  return MakeSpecific(context, loc, generic_id, args_id);
-}
-
 // Checks that `impl_function_id` is a valid implementation of the function
 // described in the interface as `interface_function_id`. Returns the value to
 // put into the corresponding slot in the witness table, which can be
@@ -267,16 +215,14 @@ auto AddConstantsToImplWitnessFromConstraint(Context& context,
         CARBON_DIAGNOSTIC(AssociatedConstantWithDifferentValues, Error,
                           "associated constant {0} given two different values",
                           SemIR::NameId);
-        auto decl_id = assoc_entities[access.index.index];
-        decl_id = context.constant_values().GetInstId(
-            SemIR::GetConstantValueInSpecific(
-                context.sem_ir(), interface_type->specific_id, decl_id));
+        auto decl_id = context.constant_values().GetConstantInstId(
+            assoc_entities[access.index.index]);
         CARBON_CHECK(decl_id.has_value(), "Non-constant associated entity");
         auto decl =
             context.insts().GetAs<SemIR::AssociatedConstantDecl>(decl_id);
-        context.emitter().Emit(impl.constraint_id,
-                               AssociatedConstantWithDifferentValues,
-                               decl.name_id);
+        context.emitter().Emit(
+            impl.constraint_id, AssociatedConstantWithDifferentValues,
+            context.associated_constants().Get(decl.assoc_const_id).name_id);
       }
     } else {
       rewrite_value = rewrite.rhs_const_id;
@@ -285,15 +231,51 @@ auto AddConstantsToImplWitnessFromConstraint(Context& context,
 
   // For each non-function associated constant, update witness entry.
   for (auto index : llvm::seq(assoc_entities.size())) {
-    auto decl_id = assoc_entities[index];
-    decl_id =
-        context.constant_values().GetInstId(SemIR::GetConstantValueInSpecific(
-            context.sem_ir(), interface_type->specific_id, decl_id));
+    auto decl_id =
+        context.constant_values().GetConstantInstId(assoc_entities[index]);
     CARBON_CHECK(decl_id.has_value(), "Non-constant associated entity");
     if (auto decl =
             context.insts().TryGetAs<SemIR::AssociatedConstantDecl>(decl_id)) {
+      const auto& assoc_const =
+          context.associated_constants().Get(decl->assoc_const_id);
       auto& witness_value = witness_block[index];
       auto rewrite_value = rewrite_values[index];
+
+      // If the associated constant has a symbolic type, convert the rewrite
+      // value to that type now we know the value of `Self`.
+      SemIR::TypeId assoc_const_type_id = decl->type_id;
+      if (context.types().GetConstantId(assoc_const_type_id).is_symbolic()) {
+        // Get the type of the associated constant in this interface with this
+        // value for `Self`.
+        assoc_const_type_id = GetTypeForSpecificAssociatedEntity(
+            context, impl.constraint_id, interface_type->specific_id, decl_id,
+            context.GetTypeIdForTypeInst(impl.self_id), witness_id);
+
+        // Perform the conversion of the value to the type. We skipped this when
+        // forming the facet type because the type of the associated constant
+        // was symbolic.
+        auto converted_inst_id = ConvertToValueOfType(
+            context, context.insts().GetLocId(impl.constraint_id),
+            context.constant_values().GetInstId(rewrite_value),
+            assoc_const_type_id);
+        rewrite_value = context.constant_values().Get(converted_inst_id);
+
+        // The result of conversion can be non-constant even if the original
+        // value was constant.
+        if (!rewrite_value.is_constant() &&
+            rewrite_value != SemIR::ErrorInst::SingletonConstantId) {
+          CARBON_DIAGNOSTIC(
+              AssociatedConstantNotConstantAfterConversion, Error,
+              "associated constant {0} given value that is not constant "
+              "after conversion to {1}",
+              SemIR::NameId, SemIR::TypeId);
+          context.emitter().Emit(impl.constraint_id,
+                                 AssociatedConstantNotConstantAfterConversion,
+                                 assoc_const.name_id, assoc_const_type_id);
+          rewrite_value = SemIR::ErrorInst::SingletonConstantId;
+        }
+      }
+
       if (witness_value.has_value() &&
           witness_value != SemIR::ErrorInst::SingletonInstId) {
         // TODO: Support just using the witness values if the redeclaration uses
@@ -305,7 +287,7 @@ auto AddConstantsToImplWitnessFromConstraint(Context& context,
                             SemIR::NameId);
           auto builder = context.emitter().Build(
               impl.latest_decl_id(), AssociatedConstantMissingInRedecl,
-              decl->name_id);
+              assoc_const.name_id);
           NotePreviousDecl(context, builder, prev_decl_id);
           builder.Emit();
           continue;
@@ -320,7 +302,7 @@ auto AddConstantsToImplWitnessFromConstraint(Context& context,
               SemIR::NameId);
           auto builder = context.emitter().Build(
               impl.latest_decl_id(), AssociatedConstantDifferentInRedecl,
-              decl->name_id);
+              assoc_const.name_id);
           NotePreviousDecl(context, builder, prev_decl_id);
           builder.Emit();
           continue;
@@ -360,9 +342,7 @@ auto ImplWitnessStartDefinition(Context& context, SemIR::Impl& impl) -> void {
   // witness.
   for (auto index : llvm::seq(assoc_entities.size())) {
     auto decl_id = assoc_entities[index];
-    decl_id =
-        context.constant_values().GetInstId(SemIR::GetConstantValueInSpecific(
-            context.sem_ir(), interface_type->specific_id, decl_id));
+    decl_id = context.constant_values().GetConstantInstId(decl_id);
     CARBON_CHECK(decl_id.has_value(), "Non-constant associated entity");
     if (auto decl =
             context.insts().TryGetAs<SemIR::AssociatedConstantDecl>(decl_id)) {
@@ -373,12 +353,14 @@ auto ImplWitnessStartDefinition(Context& context, SemIR::Impl& impl) -> void {
                           "of interface {1}",
                           SemIR::NameId, SemIR::NameId);
         CARBON_DIAGNOSTIC(AssociatedConstantHere, Note,
-                          "associated constant {0} declared here",
-                          SemIR::NameId);
+                          "associated constant declared here");
         context.emitter()
             .Build(impl.constraint_id, ImplAssociatedConstantNeedsValue,
-                   decl->name_id, interface.name_id)
-            .Note(assoc_entities[index], AssociatedConstantHere, decl->name_id)
+                   context.associated_constants()
+                       .Get(decl->assoc_const_id)
+                       .name_id,
+                   interface.name_id)
+            .Note(assoc_entities[index], AssociatedConstantHere)
             .Emit();
 
         witness_value = SemIR::ErrorInst::SingletonInstId;

+ 88 - 24
toolchain/check/import_ref.cpp

@@ -242,6 +242,9 @@ class ImportContext {
   auto import_ir() -> const SemIR::File& { return import_ir_; }
 
   // Accessors into value stores of the file we are importing from.
+  auto import_associated_constants() -> decltype(auto) {
+    return import_ir().associated_constants();
+  }
   auto import_classes() -> decltype(auto) { return import_ir().classes(); }
   auto import_constant_values() -> decltype(auto) {
     return import_ir().constant_values();
@@ -298,6 +301,9 @@ class ImportContext {
   auto local_context() -> Context& { return context_; }
 
   // Accessors into value stores of the file we are importing into.
+  auto local_associated_constants() -> decltype(auto) {
+    return local_ir().associated_constants();
+  }
   auto local_classes() -> decltype(auto) { return local_ir().classes(); }
   auto local_constant_values() -> decltype(auto) {
     return local_ir().constant_values();
@@ -1234,14 +1240,16 @@ static auto AddAssociatedEntities(ImportContext& context,
   for (auto inst_id : associated_entities) {
     // Determine the name of the associated entity, by switching on its kind.
     SemIR::NameId import_name_id = SemIR::NameId::None;
-    if (auto associated_const =
+    if (auto assoc_const_decl =
             context.import_insts().TryGetAs<SemIR::AssociatedConstantDecl>(
                 inst_id)) {
-      import_name_id = associated_const->name_id;
+      const auto& assoc_const = context.import_associated_constants().Get(
+          assoc_const_decl->assoc_const_id);
+      import_name_id = assoc_const.name_id;
     } else if (auto function_decl =
                    context.import_insts().TryGetAs<SemIR::FunctionDecl>(
                        inst_id)) {
-      auto function =
+      const auto& function =
           context.import_functions().Get(function_decl->function_id);
       import_name_id = function.name_id;
     } else if (auto import_ref =
@@ -1333,26 +1341,85 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
                  .element_type_id = element_type_id});
 }
 
+static auto MakeAssociatedConstant(
+    ImportContext& context, const SemIR::AssociatedConstant& import_assoc_const,
+    SemIR::TypeId type_id)
+    -> std::pair<SemIR::AssociatedConstantId, SemIR::ConstantId> {
+  SemIR::AssociatedConstantDecl assoc_const_decl = {
+      .type_id = type_id,
+      .assoc_const_id = SemIR::AssociatedConstantId::None,
+      .decl_block_id = SemIR::InstBlockId::Empty};
+  auto assoc_const_decl_id =
+      context.local_context().AddPlaceholderInstInNoBlock(
+          context.local_context().MakeImportedLocAndInst(
+              AddImportIRInst(context, import_assoc_const.decl_id),
+              assoc_const_decl));
+  assoc_const_decl.assoc_const_id = context.local_associated_constants().Add({
+      .name_id = GetLocalNameId(context, import_assoc_const.name_id),
+      .parent_scope_id = SemIR::NameScopeId::None,
+      .decl_id = assoc_const_decl_id,
+      .generic_id = MakeIncompleteGeneric(context, import_assoc_const.decl_id,
+                                          import_assoc_const.generic_id),
+      .default_value_id =
+          import_assoc_const.default_value_id.has_value()
+              ? AddImportRef(context, import_assoc_const.default_value_id)
+              : SemIR::InstId::None,
+  });
+
+  // Write the associated constant ID into the AssociatedConstantDecl.
+  context.local_context().ReplaceInstBeforeConstantUse(assoc_const_decl_id,
+                                                       assoc_const_decl);
+  auto const_id = context.local_constant_values().Get(assoc_const_decl_id);
+  return {assoc_const_decl.assoc_const_id, const_id};
+}
+
 static auto TryResolveTypedInst(ImportRefResolver& resolver,
                                 SemIR::AssociatedConstantDecl inst,
-                                SemIR::InstId import_inst_id) -> ResolveResult {
-  auto type_const_id = GetLocalConstantId(resolver, inst.type_id);
-  if (resolver.HasNewWork()) {
-    return ResolveResult::Retry();
+                                SemIR::ConstantId const_id) -> ResolveResult {
+  const auto& import_assoc_const =
+      resolver.import_associated_constants().Get(inst.assoc_const_id);
+
+  SemIR::AssociatedConstantId assoc_const_id =
+      SemIR::AssociatedConstantId::None;
+  if (!const_id.has_value()) {
+    // In the first phase, import the type of the associated constant.
+    auto type_const_id = GetLocalConstantId(resolver, inst.type_id);
+    if (resolver.HasNewWork()) {
+      return ResolveResult::Retry();
+    }
+
+    // In the second phase, create the associated constant and its declaration.
+    auto type_id =
+        resolver.local_context().GetTypeIdForTypeConstant(type_const_id);
+    std::tie(assoc_const_id, const_id) =
+        MakeAssociatedConstant(resolver, import_assoc_const, type_id);
+  } else {
+    // In the third phase, compute the associated constant ID from the constant
+    // value of the declaration.
+    assoc_const_id =
+        resolver.local_insts()
+            .GetAs<SemIR::AssociatedConstantDecl>(
+                resolver.local_constant_values().GetInstId(const_id))
+            .assoc_const_id;
   }
 
-  auto type_id =
-      resolver.local_context().GetTypeIdForTypeConstant(type_const_id);
+  // Load the values to populate the entity with.
+  auto parent_scope_id =
+      GetLocalNameScopeId(resolver, import_assoc_const.parent_scope_id);
+  auto generic_data =
+      GetLocalGenericData(resolver, import_assoc_const.generic_id);
+  auto& new_assoc_const =
+      resolver.local_associated_constants().Get(assoc_const_id);
 
-  // Create a corresponding instruction to represent the declaration.
-  auto inst_id = resolver.local_context().AddInstInNoBlock(
-      resolver.local_context()
-          .MakeImportedLocAndInst<SemIR::AssociatedConstantDecl>(
-              AddImportIRInst(resolver, import_inst_id),
-              {.type_id = type_id,
-               .name_id = GetLocalNameId(resolver, inst.name_id)}));
-  return ResolveResult::Done(resolver.local_constant_values().Get(inst_id),
-                             inst_id);
+  if (resolver.HasNewWork()) {
+    return ResolveResult::Retry(const_id, new_assoc_const.decl_id);
+  }
+
+  // Populate the entity.
+  new_assoc_const.parent_scope_id = parent_scope_id;
+  SetGenericData(resolver, import_assoc_const.generic_id,
+                 new_assoc_const.generic_id, generic_data);
+  return ResolveResult::Done(const_id, new_assoc_const.decl_id);
 }
 
 static auto TryResolveTypedInst(ImportRefResolver& resolver,
@@ -1377,7 +1444,6 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
     -> ResolveResult {
   CARBON_CHECK(inst.type_id == SemIR::TypeType::SingletonTypeId);
 
-  auto entity_type_const_id = GetLocalConstantId(resolver, inst.entity_type_id);
   auto interface_inst_id = GetLocalConstantId(resolver, inst.interface_type_id);
   if (resolver.HasNewWork()) {
     return ResolveResult::Retry();
@@ -1386,10 +1452,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
   return ResolveAs<SemIR::AssociatedEntityType>(
       resolver,
       {.type_id = SemIR::TypeType::SingletonTypeId,
-       .interface_type_id =
-           resolver.local_context().GetTypeIdForTypeConstant(interface_inst_id),
-       .entity_type_id = resolver.local_context().GetTypeIdForTypeConstant(
-           entity_type_const_id)});
+       .interface_type_id = resolver.local_context().GetTypeIdForTypeConstant(
+           interface_inst_id)});
 }
 
 static auto TryResolveTypedInst(ImportRefResolver& resolver,
@@ -2618,7 +2682,7 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver,
       return TryResolveTypedInst(resolver, inst);
     }
     case CARBON_KIND(SemIR::AssociatedConstantDecl inst): {
-      return TryResolveTypedInst(resolver, inst, inst_id);
+      return TryResolveTypedInst(resolver, inst, const_id);
     }
     case CARBON_KIND(SemIR::AssociatedEntity inst): {
       return TryResolveTypedInst(resolver, inst);

+ 78 - 2
toolchain/check/interface.cpp

@@ -5,6 +5,8 @@
 #include "toolchain/check/interface.h"
 
 #include "toolchain/check/context.h"
+#include "toolchain/check/eval.h"
+#include "toolchain/check/generic.h"
 #include "toolchain/sem_ir/ids.h"
 #include "toolchain/sem_ir/inst.h"
 #include "toolchain/sem_ir/typed_insts.h"
@@ -32,11 +34,85 @@ 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(
-      self_type_id, context.insts().Get(decl_id).type_id());
+  auto type_id = context.GetAssociatedEntityType(self_type_id);
   return context.AddInst<SemIR::AssociatedEntity>(
       context.insts().GetLocId(decl_id),
       {.type_id = type_id, .index = index, .decl_id = decl_id});
 }
 
+auto GetSelfSpecificForInterfaceMemberWithSelfType(
+    Context& context, SemIRLoc loc, SemIR::SpecificId enclosing_specific_id,
+    SemIR::GenericId generic_id, SemIR::TypeId self_type_id,
+    SemIR::InstId witness_inst_id) -> SemIR::SpecificId {
+  const auto& generic = context.generics().Get(generic_id);
+  auto bindings = context.inst_blocks().Get(generic.bindings_id);
+
+  llvm::SmallVector<SemIR::InstId> arg_ids;
+  arg_ids.reserve(bindings.size());
+
+  // Start with the enclosing arguments.
+  if (enclosing_specific_id.has_value()) {
+    auto enclosing_specific_args_id =
+        context.specifics().Get(enclosing_specific_id).args_id;
+    auto enclosing_specific_args =
+        context.inst_blocks().Get(enclosing_specific_args_id);
+    arg_ids.assign(enclosing_specific_args.begin(),
+                   enclosing_specific_args.end());
+  }
+
+  // Add the `Self` argument. First find the `Self` binding.
+  auto self_binding =
+      context.insts().GetAs<SemIR::BindSymbolicName>(bindings[arg_ids.size()]);
+  CARBON_CHECK(
+      context.entity_names().Get(self_binding.entity_name_id).name_id ==
+          SemIR::NameId::SelfType,
+      "Expected a Self binding, found {0}", self_binding);
+  // Create a facet value to be the value of `Self` in the interface.
+  // TODO: Pass this in instead of creating it here. The caller sometimes
+  // already has a facet value.
+  auto type_inst_id = context.types().GetInstId(self_type_id);
+  auto facet_value_const_id =
+      TryEvalInst(context, SemIR::InstId::None,
+                  SemIR::FacetValue{.type_id = self_binding.type_id,
+                                    .type_inst_id = type_inst_id,
+                                    .witness_inst_id = witness_inst_id});
+  arg_ids.push_back(context.constant_values().GetInstId(facet_value_const_id));
+
+  // Take any trailing argument values from the self specific.
+  // TODO: If these refer to outer arguments, for example in their types, we may
+  // need to perform extra substitutions here.
+  auto self_specific_args = context.inst_blocks().Get(
+      context.specifics().Get(generic.self_specific_id).args_id);
+  for (auto arg_id : self_specific_args.drop_front(arg_ids.size())) {
+    arg_ids.push_back(context.constant_values().GetConstantInstId(arg_id));
+  }
+
+  auto args_id = context.inst_blocks().AddCanonical(arg_ids);
+  return MakeSpecific(context, loc, generic_id, args_id);
+}
+
+auto GetTypeForSpecificAssociatedEntity(Context& context, SemIRLoc loc,
+                                        SemIR::SpecificId interface_specific_id,
+                                        SemIR::InstId decl_id,
+                                        SemIR::TypeId self_type_id,
+                                        SemIR::InstId self_witness_id)
+    -> SemIR::TypeId {
+  auto decl =
+      context.insts().Get(context.constant_values().GetConstantInstId(decl_id));
+
+  auto specific_id = interface_specific_id;
+  if (auto assoc_const = decl.TryAs<SemIR::AssociatedConstantDecl>()) {
+    specific_id = GetSelfSpecificForInterfaceMemberWithSelfType(
+        context, loc, interface_specific_id,
+        context.associated_constants()
+            .Get(assoc_const->assoc_const_id)
+            .generic_id,
+        self_type_id, self_witness_id);
+  }
+  // TODO: For a `FunctionDecl`, should we substitute `Self` into the type?
+
+  return SemIR::GetTypeInSpecific(context.sem_ir(), specific_id,
+                                  context.insts().Get(decl_id).type_id());
+}
+
 }  // namespace Carbon::Check

+ 16 - 0
toolchain/check/interface.h

@@ -17,6 +17,22 @@ namespace Carbon::Check {
 auto BuildAssociatedEntity(Context& context, SemIR::InterfaceId interface_id,
                            SemIR::InstId decl_id) -> SemIR::InstId;
 
+// Gets the self specific of a generic declaration that is an interface member,
+// given a specific for an enclosing generic, plus a type to use as `Self`.
+auto GetSelfSpecificForInterfaceMemberWithSelfType(
+    Context& context, SemIRLoc loc, SemIR::SpecificId enclosing_specific_id,
+    SemIR::GenericId generic_id, SemIR::TypeId self_type_id,
+    SemIR::InstId witness_inst_id) -> SemIR::SpecificId;
+
+// Gets the type of the specified associated entity, given the specific for the
+// interface and the type of `Self`.
+auto GetTypeForSpecificAssociatedEntity(Context& context, SemIRLoc loc,
+                                        SemIR::SpecificId interface_specific_id,
+                                        SemIR::InstId decl_id,
+                                        SemIR::TypeId self_type_id,
+                                        SemIR::InstId self_witness_id)
+    -> SemIR::TypeId;
+
 }  // namespace Carbon::Check
 
 #endif  // CARBON_TOOLCHAIN_CHECK_INTERFACE_H_

+ 5 - 4
toolchain/check/keyword_modifier_set.h

@@ -86,7 +86,7 @@ class KeywordModifierSet {
   //                .Default(SomeEnum::DefaultValue);
   //   ```
   template <typename T>
-  auto ToEnum() -> auto {
+  auto ToEnum() const -> auto {
     class Converter {
      public:
       explicit Converter(const KeywordModifierSet& set) : set_(set) {}
@@ -124,15 +124,16 @@ class KeywordModifierSet {
   }
 
   // Returns true if empty.
-  constexpr auto empty() -> bool { return !set_; }
+  constexpr auto empty() const -> bool { return !set_; }
 
   // Returns the set intersection.
-  constexpr auto operator&(KeywordModifierSet other) -> KeywordModifierSet {
+  constexpr auto operator&(KeywordModifierSet other) const
+      -> KeywordModifierSet {
     return set_ & other.set_;
   }
 
   // Returns the set inverse.
-  auto operator~() -> KeywordModifierSet { return ~set_; }
+  auto operator~() const -> KeywordModifierSet { return ~set_; }
 
  private:
   RawEnumType set_;

+ 19 - 16
toolchain/check/member_access.cpp

@@ -11,6 +11,8 @@
 #include "toolchain/check/context.h"
 #include "toolchain/check/convert.h"
 #include "toolchain/check/impl_lookup.h"
+#include "toolchain/check/import_ref.h"
+#include "toolchain/check/interface.h"
 #include "toolchain/diagnostics/diagnostic_emitter.h"
 #include "toolchain/sem_ir/generic.h"
 #include "toolchain/sem_ir/ids.h"
@@ -138,9 +140,9 @@ static auto GetInterfaceFromFacetType(Context& context, SemIR::TypeId type_id)
 }
 
 static auto AccessMemberOfImplWitness(Context& context, SemIR::LocId loc_id,
+                                      SemIR::TypeId self_type_id,
                                       SemIR::InstId witness_id,
                                       SemIR::SpecificId interface_specific_id,
-                                      SemIR::AssociatedEntityType assoc_type,
                                       SemIR::InstId member_id)
     -> SemIR::InstId {
   auto member_value_id = context.constant_values().GetConstantInstId(member_id);
@@ -158,14 +160,15 @@ static auto AccessMemberOfImplWitness(Context& context, SemIR::LocId loc_id,
     return SemIR::ErrorInst::SingletonInstId;
   }
 
-  // TODO: This produces the type of the associated entity with no value for
-  // `Self`. The type `Self` might appear in the type of an associated constant,
-  // and if so, we'll need to substitute it here somehow.
-  auto subst_type_id = SemIR::GetTypeInSpecific(
-      context.sem_ir(), interface_specific_id, assoc_type.entity_type_id);
+  // Substitute the interface specific and `Self` type into the type of the
+  // associated entity to find the type of the member access.
+  LoadImportRef(context, assoc_entity->decl_id);
+  auto assoc_type_id = GetTypeForSpecificAssociatedEntity(
+      context, loc_id, interface_specific_id, assoc_entity->decl_id,
+      self_type_id, witness_id);
 
   return context.GetOrAddInst<SemIR::ImplWitnessAccess>(
-      loc_id, {.type_id = subst_type_id,
+      loc_id, {.type_id = assoc_type_id,
                .witness_id = witness_id,
                .index = assoc_entity->index});
 }
@@ -186,6 +189,7 @@ static auto PerformImplLookup(
     return SemIR::ErrorInst::SingletonInstId;
   }
 
+  auto self_type_id = context.GetTypeIdForTypeConstant(type_const_id);
   auto witness_id =
       LookupImplWitness(context, loc_id, type_const_id,
                         assoc_type.interface_type_id.AsConstantId());
@@ -199,7 +203,7 @@ static auto PerformImplLookup(
                         SemIR::TypeId, SemIR::TypeId);
       missing_impl_diagnoser()
           .Note(loc_id, MissingImplInMemberAccessNote, interface_type_id,
-                context.GetTypeIdForTypeConstant(type_const_id))
+                self_type_id)
           .Emit();
     } else {
       // TODO: Pass in the expression whose type we are printing.
@@ -208,14 +212,12 @@ static auto PerformImplLookup(
                         "that does not implement that interface",
                         SemIR::TypeId, SemIR::TypeId);
       context.emitter().Emit(loc_id, MissingImplInMemberAccess,
-                             interface_type_id,
-                             context.GetTypeIdForTypeConstant(type_const_id));
+                             interface_type_id, self_type_id);
     }
     return SemIR::ErrorInst::SingletonInstId;
   }
-  return AccessMemberOfImplWitness(context, loc_id, witness_id,
-                                   interface_type->specific_id, assoc_type,
-                                   member_id);
+  return AccessMemberOfImplWitness(context, loc_id, self_type_id, witness_id,
+                                   interface_type->specific_id, member_id);
 }
 
 // Performs a member name lookup into the specified scope, including performing
@@ -276,6 +278,7 @@ static auto LookupMemberNameInScope(Context& context, SemIR::LocId loc_id,
       if (base_type_id != SemIR::TypeType::SingletonTypeId &&
           context.IsFacetType(base_type_id)) {
         // Handles `T.F` when `T` is a non-type facet.
+        auto base_as_type = ExprAsType(context, loc_id, base_id);
 
         auto assoc_interface =
             GetInterfaceFromFacetType(context, assoc_type->interface_type_id);
@@ -315,9 +318,9 @@ static auto LookupMemberNameInScope(Context& context, SemIR::LocId loc_id,
           return SemIR::ErrorInst::SingletonInstId;
         }
 
-        member_id = AccessMemberOfImplWitness(context, loc_id, witness_inst_id,
-                                              assoc_interface->specific_id,
-                                              *assoc_type, member_id);
+        member_id = AccessMemberOfImplWitness(
+            context, loc_id, base_as_type.type_id, witness_inst_id,
+            assoc_interface->specific_id, member_id);
       } else {
         // Handles `x.F` if `x` is of type `class C` that extends an interface
         // containing `F`.

+ 12 - 0
toolchain/check/node_stack.h

@@ -212,6 +212,8 @@ class NodeStack {
 
   // Pops a pattern from the top of the stack and returns the ID.
   // Patterns map multiple Parse::NodeKinds to SemIR::InstId always.
+  // TODO: TuplePatterns store an InstBlockId instead and must be dealt with as
+  // a special case before calling this function.
   auto PopPattern() -> SemIR::InstId { return PopPatternWithNodeId().second; }
 
   // Pops a name from the top of the stack and returns the ID.
@@ -316,6 +318,12 @@ class NodeStack {
     return Peek<*RequiredIdKind>();
   }
 
+  // Peeks at the ID associated with the pattern at the top of the stack.
+  // Patterns map multiple Parse::NodeKinds to SemIR::InstId always.
+  // TODO: TuplePatterns store an InstBlockId instead and must be dealt with as
+  // a special case before calling this function.
+  auto PeekPattern() const -> SemIR::InstId;
+
   // Prints the stack for a stack dump.
   auto PrintForStackDump(int indent, llvm::raw_ostream& output) const -> void;
 
@@ -719,6 +727,10 @@ inline auto NodeStack::PopExprWithNodeId()
   return PopWithNodeId<Parse::NodeCategory::Expr>();
 }
 
+inline auto NodeStack::PeekPattern() const -> SemIR::InstId {
+  return Peek<Id::KindFor<SemIR::InstId>()>();
+}
+
 }  // namespace Carbon::Check
 
 #endif  // CARBON_TOOLCHAIN_CHECK_NODE_STACK_H_

+ 1 - 1
toolchain/check/testdata/builtins/bool/eq.carbon

@@ -290,8 +290,8 @@ var d: C(false == false) = True();
 // CHECK:STDOUT:   %C.2ba: type = class_type @C, @C(%false) [template]
 // CHECK:STDOUT:   %False.type: type = fn_type @False [template]
 // CHECK:STDOUT:   %False: %False.type = struct_value () [template]
-// CHECK:STDOUT:   %Equal.type.79c: type = fn_type @Equal.1 [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (imports.%Core.import_ref.998, imports.%Core.import_ref.fb6) [template]
+// CHECK:STDOUT:   %Equal.type.79c: type = fn_type @Equal.1 [template]
 // CHECK:STDOUT:   %Equal.type.aa3: type = fn_type @Equal.2 [template]
 // CHECK:STDOUT:   %Equal.6e2: %Equal.type.aa3 = struct_value () [template]
 // CHECK:STDOUT:   %Equal.bound.fe0: <bound method> = bound_method %true, %Equal.6e2 [template]

+ 1 - 1
toolchain/check/testdata/builtins/bool/neq.carbon

@@ -290,8 +290,8 @@ var d: C(false != false) = False();
 // CHECK:STDOUT:   %C.2ba: type = class_type @C, @C(%false) [template]
 // CHECK:STDOUT:   %False.type: type = fn_type @False [template]
 // CHECK:STDOUT:   %False: %False.type = struct_value () [template]
-// CHECK:STDOUT:   %NotEqual.type.e6c: type = fn_type @NotEqual.1 [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (imports.%Core.import_ref.85b, imports.%Core.import_ref.67a) [template]
+// CHECK:STDOUT:   %NotEqual.type.e6c: type = fn_type @NotEqual.1 [template]
 // CHECK:STDOUT:   %NotEqual.type.c0e: type = fn_type @NotEqual.2 [template]
 // CHECK:STDOUT:   %NotEqual.bf4: %NotEqual.type.c0e = struct_value () [template]
 // CHECK:STDOUT:   %NotEqual.bound.542: <bound method> = bound_method %true, %NotEqual.bf4 [template]

+ 0 - 3
toolchain/check/testdata/class/generic/member_out_of_line.carbon

@@ -595,7 +595,6 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @TooFew(@Generic.%T.loc4_15.1: type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -679,7 +678,6 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @TooMany(@Generic.%T.loc4_15.1: type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -782,7 +780,6 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @WrongType(@Generic.%T.loc4_15.1: type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

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

@@ -26,8 +26,8 @@ var arr: [i32; (1 as i32).(I.F)(2)];
 // CHECK:STDOUT:   %Self.as_type.b70: type = facet_access_type %Self.826 [symbolic]
 // CHECK:STDOUT:   %F.type.cf0: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.bc6: %F.type.cf0 = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %I.type, %F.type.cf0 [template]
-// CHECK:STDOUT:   %assoc0.fa7: %F.assoc_type = assoc_entity element0, @I.%F.decl [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0.a5e: %I.assoc_type = assoc_entity element0, @I.%F.decl [template]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [template]
 // CHECK:STDOUT:   %impl_witness.da7: <witness> = impl_witness (@impl.1.%F.decl) [template]
@@ -104,7 +104,7 @@ var arr: [i32; (1 as i32).(I.F)(2)];
 // CHECK:STDOUT:     %.loc19_19.1: %i32 = value_of_initializer %int.convert_checked.loc19_19 [template = constants.%int_1.5d2]
 // CHECK:STDOUT:     %.loc19_19.2: %i32 = converted %int_1, %.loc19_19.1 [template = constants.%int_1.5d2]
 // CHECK:STDOUT:     %I.ref: type = name_ref I, %I.decl [template = constants.%I.type]
-// CHECK:STDOUT:     %F.ref: %F.assoc_type = name_ref F, @I.%assoc0 [template = constants.%assoc0.fa7]
+// CHECK:STDOUT:     %F.ref: %I.assoc_type = name_ref F, @I.%assoc0 [template = constants.%assoc0.a5e]
 // CHECK:STDOUT:     %impl.elem0.loc19_26: %F.type.cf0 = impl_witness_access constants.%impl_witness.da7, element0 [template = constants.%F.9ec]
 // CHECK:STDOUT:     %F.bound: <bound method> = bound_method %.loc19_19.2, %impl.elem0.loc19_26 [template = constants.%F.bound]
 // CHECK:STDOUT:     %int_2: Core.IntLiteral = int_value 2 [template = constants.%int_2.ecc]
@@ -158,7 +158,7 @@ var arr: [i32; (1 as i32).(I.F)(2)];
 // CHECK:STDOUT:     %return.param: ref @F.1.%Self.as_type.loc12_14.1 (%Self.as_type.b70) = out_param runtime_param2
 // CHECK:STDOUT:     %return: ref @F.1.%Self.as_type.loc12_14.1 (%Self.as_type.b70) = return_slot %return.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0.fa7]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0.a5e]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self

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

@@ -61,8 +61,8 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   %Self.as_type.f73: type = facet_access_type %Self.b3d [symbolic]
 // CHECK:STDOUT:   %Op.type.31b: type = fn_type @Op.1 [template]
 // CHECK:STDOUT:   %Op.d59: %Op.type.31b = struct_value () [template]
-// CHECK:STDOUT:   %Op.assoc_type: type = assoc_entity_type %Add.type, %Op.type.31b [template]
-// CHECK:STDOUT:   %assoc0.a27: %Op.assoc_type = assoc_entity element0, @Add.%Op.decl [template]
+// CHECK:STDOUT:   %Add.assoc_type: type = assoc_entity_type %Add.type [template]
+// CHECK:STDOUT:   %assoc0.245: %Add.assoc_type = assoc_entity element0, @Add.%Op.decl [template]
 // CHECK:STDOUT:   %T: type = bind_symbolic_name T, 0 [symbolic]
 // CHECK:STDOUT:   %T.patt: type = symbolic_binding_pattern T, 0 [symbolic]
 // CHECK:STDOUT:   %As.type.b51: type = generic_interface_type @As [template]
@@ -72,8 +72,8 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   %Self.as_type.7f0: type = facet_access_type %Self.b4e [symbolic]
 // CHECK:STDOUT:   %Convert.type.ad1: type = fn_type @Convert.1, @As(%T) [symbolic]
 // CHECK:STDOUT:   %Convert.0ed: %Convert.type.ad1 = struct_value () [symbolic]
-// CHECK:STDOUT:   %Convert.assoc_type.0ce: type = assoc_entity_type %As.type.8ba, %Convert.type.ad1 [symbolic]
-// CHECK:STDOUT:   %assoc0.179: %Convert.assoc_type.0ce = assoc_entity element0, @As.%Convert.decl [symbolic]
+// CHECK:STDOUT:   %As.assoc_type.600: type = assoc_entity_type %As.type.8ba [symbolic]
+// CHECK:STDOUT:   %assoc0.ac5: %As.assoc_type.600 = assoc_entity element0, @As.%Convert.decl [symbolic]
 // CHECK:STDOUT:   %ImplicitAs.type.96f: type = generic_interface_type @ImplicitAs [template]
 // CHECK:STDOUT:   %ImplicitAs.generic: %ImplicitAs.type.96f = struct_value () [template]
 // CHECK:STDOUT:   %ImplicitAs.type.07f: type = facet_type <@ImplicitAs, @ImplicitAs(%T)> [symbolic]
@@ -81,8 +81,8 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   %Self.as_type.419: type = facet_access_type %Self.0f3 [symbolic]
 // CHECK:STDOUT:   %Convert.type.4cf: type = fn_type @Convert.2, @ImplicitAs(%T) [symbolic]
 // CHECK:STDOUT:   %Convert.147: %Convert.type.4cf = struct_value () [symbolic]
-// CHECK:STDOUT:   %Convert.assoc_type.154: type = assoc_entity_type %ImplicitAs.type.07f, %Convert.type.4cf [symbolic]
-// CHECK:STDOUT:   %assoc0.1f7: %Convert.assoc_type.154 = assoc_entity element0, @ImplicitAs.%Convert.decl [symbolic]
+// CHECK:STDOUT:   %ImplicitAs.assoc_type.94e: type = assoc_entity_type %ImplicitAs.type.07f [symbolic]
+// CHECK:STDOUT:   %assoc0.a50: %ImplicitAs.assoc_type.94e = assoc_entity element0, @ImplicitAs.%Convert.decl [symbolic]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
 // CHECK:STDOUT:   %i32.builtin: type = int_type signed, %int_32 [template]
 // CHECK:STDOUT:   %impl_witness.8b6: <witness> = impl_witness (@impl.1.%Op.decl) [template]
@@ -92,8 +92,8 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   %As.type.a09: type = facet_type <@As, @As(%i32.builtin)> [template]
 // CHECK:STDOUT:   %Convert.type.c0d: type = fn_type @Convert.1, @As(%i32.builtin) [template]
 // CHECK:STDOUT:   %Convert.713: %Convert.type.c0d = struct_value () [template]
-// CHECK:STDOUT:   %Convert.assoc_type.3d5: type = assoc_entity_type %As.type.a09, %Convert.type.c0d [template]
-// CHECK:STDOUT:   %assoc0.099: %Convert.assoc_type.3d5 = assoc_entity element0, @As.%Convert.decl [template]
+// CHECK:STDOUT:   %As.assoc_type.567: type = assoc_entity_type %As.type.a09 [template]
+// CHECK:STDOUT:   %assoc0.3bd: %As.assoc_type.567 = assoc_entity element0, @As.%Convert.decl [template]
 // CHECK:STDOUT:   %impl_witness.213: <witness> = impl_witness (@impl.2.%Convert.decl) [template]
 // CHECK:STDOUT:   %Convert.type.fc9: type = fn_type @Convert.3 [template]
 // CHECK:STDOUT:   %Convert.33c: %Convert.type.fc9 = struct_value () [template]
@@ -101,8 +101,8 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   %ImplicitAs.type.11a: type = facet_type <@ImplicitAs, @ImplicitAs(%i32.builtin)> [template]
 // CHECK:STDOUT:   %Convert.type.752: type = fn_type @Convert.2, @ImplicitAs(%i32.builtin) [template]
 // CHECK:STDOUT:   %Convert.fcc: %Convert.type.752 = struct_value () [template]
-// CHECK:STDOUT:   %Convert.assoc_type.93b: type = assoc_entity_type %ImplicitAs.type.11a, %Convert.type.752 [template]
-// CHECK:STDOUT:   %assoc0.8ce: %Convert.assoc_type.93b = assoc_entity element0, @ImplicitAs.%Convert.decl [template]
+// CHECK:STDOUT:   %ImplicitAs.assoc_type.dd3: type = assoc_entity_type %ImplicitAs.type.11a [template]
+// CHECK:STDOUT:   %assoc0.7cc: %ImplicitAs.assoc_type.dd3 = assoc_entity element0, @ImplicitAs.%Convert.decl [template]
 // CHECK:STDOUT:   %impl_witness.48c: <witness> = impl_witness (@impl.3.%Convert.decl) [template]
 // CHECK:STDOUT:   %Convert.type.c2a: type = fn_type @Convert.4 [template]
 // CHECK:STDOUT:   %Convert.40d: %Convert.type.c2a = struct_value () [template]
@@ -110,8 +110,8 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   %ImplicitAs.type.9fc: type = facet_type <@ImplicitAs, @ImplicitAs(Core.IntLiteral)> [template]
 // CHECK:STDOUT:   %Convert.type.60e: type = fn_type @Convert.2, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.c73: %Convert.type.60e = struct_value () [template]
-// CHECK:STDOUT:   %Convert.assoc_type.6ab: type = assoc_entity_type %ImplicitAs.type.9fc, %Convert.type.60e [template]
-// CHECK:STDOUT:   %assoc0.9d6: %Convert.assoc_type.6ab = assoc_entity element0, @ImplicitAs.%Convert.decl [template]
+// CHECK:STDOUT:   %ImplicitAs.assoc_type.81c: type = assoc_entity_type %ImplicitAs.type.9fc [template]
+// CHECK:STDOUT:   %assoc0.80e: %ImplicitAs.assoc_type.81c = assoc_entity element0, @ImplicitAs.%Convert.decl [template]
 // CHECK:STDOUT:   %impl_witness.caf: <witness> = impl_witness (@impl.4.%Convert.decl) [template]
 // CHECK:STDOUT:   %Convert.type.295: type = fn_type @Convert.5 [template]
 // CHECK:STDOUT:   %Convert.2bf: %Convert.type.295 = struct_value () [template]
@@ -244,7 +244,7 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:     %return.param: ref @Op.1.%Self.as_type.loc8_15.1 (%Self.as_type.f73) = out_param runtime_param2
 // CHECK:STDOUT:     %return: ref @Op.1.%Self.as_type.loc8_15.1 (%Self.as_type.f73) = return_slot %return.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc0: %Op.assoc_type = assoc_entity element0, %Op.decl [template = constants.%assoc0.a27]
+// CHECK:STDOUT:   %assoc0: %Add.assoc_type = assoc_entity element0, %Op.decl [template = constants.%assoc0.245]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -261,8 +261,8 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   %Self.2: %As.type.8ba = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self.b4e)]
 // CHECK:STDOUT:   %Convert.type: type = fn_type @Convert.1, @As(%T.loc11_14.2) [symbolic = %Convert.type (constants.%Convert.type.ad1)]
 // CHECK:STDOUT:   %Convert: @As.%Convert.type (%Convert.type.ad1) = struct_value () [symbolic = %Convert (constants.%Convert.0ed)]
-// CHECK:STDOUT:   %Convert.assoc_type: type = assoc_entity_type @As.%As.type (%As.type.8ba), @As.%Convert.type (%Convert.type.ad1) [symbolic = %Convert.assoc_type (constants.%Convert.assoc_type.0ce)]
-// CHECK:STDOUT:   %assoc0.loc12_32.2: @As.%Convert.assoc_type (%Convert.assoc_type.0ce) = assoc_entity element0, %Convert.decl [symbolic = %assoc0.loc12_32.2 (constants.%assoc0.179)]
+// CHECK:STDOUT:   %As.assoc_type: type = assoc_entity_type @As.%As.type (%As.type.8ba) [symbolic = %As.assoc_type (constants.%As.assoc_type.600)]
+// CHECK:STDOUT:   %assoc0.loc12_32.2: @As.%As.assoc_type (%As.assoc_type.600) = assoc_entity element0, %Convert.decl [symbolic = %assoc0.loc12_32.2 (constants.%assoc0.ac5)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:     %Self.1: @As.%As.type (%As.type.8ba) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self.b4e)]
@@ -284,7 +284,7 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:       %return.param: ref @Convert.1.%T (%T) = out_param runtime_param1
 // CHECK:STDOUT:       %return: ref @Convert.1.%T (%T) = return_slot %return.param
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %assoc0.loc12_32.1: @As.%Convert.assoc_type (%Convert.assoc_type.0ce) = assoc_entity element0, %Convert.decl [symbolic = %assoc0.loc12_32.2 (constants.%assoc0.179)]
+// CHECK:STDOUT:     %assoc0.loc12_32.1: @As.%As.assoc_type (%As.assoc_type.600) = assoc_entity element0, %Convert.decl [symbolic = %assoc0.loc12_32.2 (constants.%assoc0.ac5)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = %Self.1
@@ -302,8 +302,8 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   %Self.2: %ImplicitAs.type.07f = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self.0f3)]
 // CHECK:STDOUT:   %Convert.type: type = fn_type @Convert.2, @ImplicitAs(%T.loc15_22.2) [symbolic = %Convert.type (constants.%Convert.type.4cf)]
 // CHECK:STDOUT:   %Convert: @ImplicitAs.%Convert.type (%Convert.type.4cf) = struct_value () [symbolic = %Convert (constants.%Convert.147)]
-// CHECK:STDOUT:   %Convert.assoc_type: type = assoc_entity_type @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.07f), @ImplicitAs.%Convert.type (%Convert.type.4cf) [symbolic = %Convert.assoc_type (constants.%Convert.assoc_type.154)]
-// CHECK:STDOUT:   %assoc0.loc16_32.2: @ImplicitAs.%Convert.assoc_type (%Convert.assoc_type.154) = assoc_entity element0, %Convert.decl [symbolic = %assoc0.loc16_32.2 (constants.%assoc0.1f7)]
+// CHECK:STDOUT:   %ImplicitAs.assoc_type: type = assoc_entity_type @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.07f) [symbolic = %ImplicitAs.assoc_type (constants.%ImplicitAs.assoc_type.94e)]
+// CHECK:STDOUT:   %assoc0.loc16_32.2: @ImplicitAs.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.94e) = assoc_entity element0, %Convert.decl [symbolic = %assoc0.loc16_32.2 (constants.%assoc0.a50)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:     %Self.1: @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.07f) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self.0f3)]
@@ -325,7 +325,7 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:       %return.param: ref @Convert.2.%T (%T) = out_param runtime_param1
 // CHECK:STDOUT:       %return: ref @Convert.2.%T (%T) = return_slot %return.param
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %assoc0.loc16_32.1: @ImplicitAs.%Convert.assoc_type (%Convert.assoc_type.154) = assoc_entity element0, %Convert.decl [symbolic = %assoc0.loc16_32.2 (constants.%assoc0.1f7)]
+// CHECK:STDOUT:     %assoc0.loc16_32.1: @ImplicitAs.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.94e) = assoc_entity element0, %Convert.decl [symbolic = %assoc0.loc16_32.2 (constants.%assoc0.a50)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = %Self.1
@@ -516,8 +516,8 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   %Self.2 => constants.%Self.b4e
 // CHECK:STDOUT:   %Convert.type => constants.%Convert.type.c0d
 // CHECK:STDOUT:   %Convert => constants.%Convert.713
-// CHECK:STDOUT:   %Convert.assoc_type => constants.%Convert.assoc_type.3d5
-// CHECK:STDOUT:   %assoc0.loc12_32.2 => constants.%assoc0.099
+// CHECK:STDOUT:   %As.assoc_type => constants.%As.assoc_type.567
+// CHECK:STDOUT:   %assoc0.loc12_32.2 => constants.%assoc0.3bd
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @Convert.1(constants.%i32.builtin, constants.%As.facet) {
@@ -536,8 +536,8 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   %Self.2 => constants.%Self.0f3
 // CHECK:STDOUT:   %Convert.type => constants.%Convert.type.752
 // CHECK:STDOUT:   %Convert => constants.%Convert.fcc
-// CHECK:STDOUT:   %Convert.assoc_type => constants.%Convert.assoc_type.93b
-// CHECK:STDOUT:   %assoc0.loc16_32.2 => constants.%assoc0.8ce
+// CHECK:STDOUT:   %ImplicitAs.assoc_type => constants.%ImplicitAs.assoc_type.dd3
+// CHECK:STDOUT:   %assoc0.loc16_32.2 => constants.%assoc0.7cc
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @Convert.2(constants.%i32.builtin, constants.%ImplicitAs.facet.555) {
@@ -556,8 +556,8 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   %Self.2 => constants.%Self.0f3
 // CHECK:STDOUT:   %Convert.type => constants.%Convert.type.60e
 // CHECK:STDOUT:   %Convert => constants.%Convert.c73
-// CHECK:STDOUT:   %Convert.assoc_type => constants.%Convert.assoc_type.6ab
-// CHECK:STDOUT:   %assoc0.loc16_32.2 => constants.%assoc0.9d6
+// CHECK:STDOUT:   %ImplicitAs.assoc_type => constants.%ImplicitAs.assoc_type.81c
+// CHECK:STDOUT:   %assoc0.loc16_32.2 => constants.%assoc0.80e
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @Convert.2(Core.IntLiteral, constants.%ImplicitAs.facet.2ca) {
@@ -582,14 +582,14 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   %Convert.type.843: type = fn_type @Convert.1, @As(%T) [symbolic]
 // CHECK:STDOUT:   %Convert.95f: %Convert.type.843 = struct_value () [symbolic]
 // CHECK:STDOUT:   %Self.as_type.04d: type = facet_access_type %Self.65a [symbolic]
-// CHECK:STDOUT:   %Convert.assoc_type.1e9: type = assoc_entity_type %As.type.eed, %Convert.type.843 [symbolic]
-// CHECK:STDOUT:   %assoc0.4ac002.1: %Convert.assoc_type.1e9 = assoc_entity element0, imports.%Core.import_ref.4e8b20.1 [symbolic]
+// CHECK:STDOUT:   %As.assoc_type.a44: type = assoc_entity_type %As.type.eed [symbolic]
+// CHECK:STDOUT:   %assoc0.ea3: %As.assoc_type.a44 = assoc_entity element0, imports.%Core.import_ref.708 [symbolic]
 // CHECK:STDOUT:   %As.type.a6d: type = facet_type <@As, @As(%i32.builtin)> [template]
 // CHECK:STDOUT:   %Convert.type.378: type = fn_type @Convert.1, @As(%i32.builtin) [template]
 // CHECK:STDOUT:   %Convert.e51: %Convert.type.378 = struct_value () [template]
-// CHECK:STDOUT:   %Convert.assoc_type.b93: type = assoc_entity_type %As.type.a6d, %Convert.type.378 [template]
-// CHECK:STDOUT:   %assoc0.9da: %Convert.assoc_type.b93 = assoc_entity element0, imports.%Core.import_ref.4e8b20.1 [template]
-// CHECK:STDOUT:   %assoc0.4ac002.2: %Convert.assoc_type.1e9 = assoc_entity element0, imports.%Core.import_ref.4e8b20.2 [symbolic]
+// CHECK:STDOUT:   %As.assoc_type.e21: type = assoc_entity_type %As.type.a6d [template]
+// CHECK:STDOUT:   %assoc0.545: %As.assoc_type.e21 = assoc_entity element0, imports.%Core.import_ref.708 [template]
+// CHECK:STDOUT:   %assoc0.5bc: %As.assoc_type.a44 = assoc_entity element0, imports.%Core.import_ref.4e8 [symbolic]
 // CHECK:STDOUT:   %Add.type: type = facet_type <@Add> [template]
 // CHECK:STDOUT:   %Self.a99: %Add.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %ImplicitAs.type.d62: type = facet_type <@ImplicitAs, @ImplicitAs(%T)> [symbolic]
@@ -598,17 +598,17 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   %Convert.type.275: type = fn_type @Convert.2, @ImplicitAs(%T) [symbolic]
 // CHECK:STDOUT:   %Convert.42e: %Convert.type.275 = struct_value () [symbolic]
 // CHECK:STDOUT:   %Self.as_type.40a: type = facet_access_type %Self.519 [symbolic]
-// CHECK:STDOUT:   %Convert.assoc_type.c0e: type = assoc_entity_type %ImplicitAs.type.d62, %Convert.type.275 [symbolic]
-// CHECK:STDOUT:   %assoc0.5048c6.1: %Convert.assoc_type.c0e = assoc_entity element0, imports.%Core.import_ref.207961.1 [symbolic]
+// CHECK:STDOUT:   %ImplicitAs.assoc_type.837: type = assoc_entity_type %ImplicitAs.type.d62 [symbolic]
+// CHECK:STDOUT:   %assoc0.43db8b.1: %ImplicitAs.assoc_type.837 = assoc_entity element0, imports.%Core.import_ref.207961.1 [symbolic]
 // CHECK:STDOUT:   %Convert.type.059: type = fn_type @Convert.2, @ImplicitAs(%i32.builtin) [template]
 // CHECK:STDOUT:   %Convert.4d7: %Convert.type.059 = struct_value () [template]
-// CHECK:STDOUT:   %Convert.assoc_type.40f: type = assoc_entity_type %ImplicitAs.type.61e, %Convert.type.059 [template]
-// CHECK:STDOUT:   %assoc0.44d: %Convert.assoc_type.40f = assoc_entity element0, imports.%Core.import_ref.207961.2 [template]
+// CHECK:STDOUT:   %ImplicitAs.assoc_type.740: type = assoc_entity_type %ImplicitAs.type.61e [template]
+// CHECK:STDOUT:   %assoc0.a81: %ImplicitAs.assoc_type.740 = assoc_entity element0, imports.%Core.import_ref.1c752f.1 [template]
 // CHECK:STDOUT:   %ImplicitAs.type.2fd: type = facet_type <@ImplicitAs, @ImplicitAs(Core.IntLiteral)> [template]
 // CHECK:STDOUT:   %Convert.type.71e: type = fn_type @Convert.2, @ImplicitAs(Core.IntLiteral) [template]
 // CHECK:STDOUT:   %Convert.0e2: %Convert.type.71e = struct_value () [template]
-// CHECK:STDOUT:   %Convert.assoc_type.94e: type = assoc_entity_type %ImplicitAs.type.2fd, %Convert.type.71e [template]
-// CHECK:STDOUT:   %assoc0.3db: %Convert.assoc_type.94e = assoc_entity element0, imports.%Core.import_ref.207961.3 [template]
+// CHECK:STDOUT:   %ImplicitAs.assoc_type.29f: type = assoc_entity_type %ImplicitAs.type.2fd [template]
+// CHECK:STDOUT:   %assoc0.ed3: %ImplicitAs.assoc_type.29f = assoc_entity element0, imports.%Core.import_ref.1c752f.2 [template]
 // CHECK:STDOUT:   %impl_witness.d9b: <witness> = impl_witness (imports.%Core.import_ref.73a) [template]
 // CHECK:STDOUT:   %Convert.type.953: type = fn_type @Convert.3 [template]
 // CHECK:STDOUT:   %Convert.5bc: %Convert.type.953 = struct_value () [template]
@@ -617,16 +617,16 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   %int_2.ecc: Core.IntLiteral = int_value 2 [template]
 // CHECK:STDOUT:   %Convert.bound.324: <bound method> = bound_method %int_2.ecc, %Convert.5bc [template]
 // CHECK:STDOUT:   %int_2.5a1: %i32.builtin = int_value 2 [template]
+// CHECK:STDOUT:   %Add.assoc_type: type = assoc_entity_type %Add.type [template]
+// CHECK:STDOUT:   %assoc0.b3c: %Add.assoc_type = assoc_entity element0, imports.%Core.import_ref.6dd [template]
+// CHECK:STDOUT:   %impl_witness.bd0: <witness> = impl_witness (imports.%Core.import_ref.db4) [template]
 // CHECK:STDOUT:   %Op.type.545: type = fn_type @Op.1 [template]
 // CHECK:STDOUT:   %Self.as_type.da9: type = facet_access_type %Self.a99 [symbolic]
-// CHECK:STDOUT:   %Op.assoc_type: type = assoc_entity_type %Add.type, %Op.type.545 [template]
-// CHECK:STDOUT:   %assoc0.8e5: %Op.assoc_type = assoc_entity element0, imports.%Core.import_ref.047 [template]
-// CHECK:STDOUT:   %impl_witness.bd0: <witness> = impl_witness (imports.%Core.import_ref.db4) [template]
 // CHECK:STDOUT:   %Op.type.240: type = fn_type @Op.2 [template]
 // CHECK:STDOUT:   %Op.0e2: %Op.type.240 = struct_value () [template]
 // CHECK:STDOUT:   %Op.bound.393: <bound method> = bound_method %int_1.f38, %Op.0e2 [template]
 // CHECK:STDOUT:   %int_3.a0f: %i32.builtin = int_value 3 [template]
-// CHECK:STDOUT:   %assoc0.5048c6.2: %Convert.assoc_type.c0e = assoc_entity element0, imports.%Core.import_ref.207961.4 [symbolic]
+// CHECK:STDOUT:   %assoc0.43db8b.2: %ImplicitAs.assoc_type.837 = assoc_entity element0, imports.%Core.import_ref.207961.2 [symbolic]
 // CHECK:STDOUT:   %impl_witness.8f3: <witness> = impl_witness (imports.%Core.import_ref.4f9) [template]
 // CHECK:STDOUT:   %Convert.type.0e4: type = fn_type @Convert.4 [template]
 // CHECK:STDOUT:   %Convert.b32: %Convert.type.0e4 = struct_value () [template]
@@ -658,12 +658,12 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:     import Core//default
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.import_ref.a7c = import_ref Core//default, inst85 [no loc], unloaded
-// CHECK:STDOUT:   %Core.import_ref.638: @As.%Convert.assoc_type (%Convert.assoc_type.1e9) = import_ref Core//default, loc12_32, loaded [symbolic = @As.%assoc0 (constants.%assoc0.4ac002.2)]
+// CHECK:STDOUT:   %Core.import_ref.713: @As.%As.assoc_type (%As.assoc_type.a44) = import_ref Core//default, loc12_32, loaded [symbolic = @As.%assoc0 (constants.%assoc0.5bc)]
 // CHECK:STDOUT:   %Core.Convert.313 = import_ref Core//default, Convert, unloaded
-// CHECK:STDOUT:   %Core.import_ref.4e8b20.1 = import_ref Core//default, loc12_32, unloaded
+// CHECK:STDOUT:   %Core.import_ref.708: @As.%Convert.type (%Convert.type.843) = import_ref Core//default, loc12_32, loaded [symbolic = @As.%Convert (constants.%Convert.95f)]
 // CHECK:STDOUT:   %Core.import_ref.595: <witness> = import_ref Core//default, loc19_17, loaded [template = constants.%impl_witness.bd0]
 // CHECK:STDOUT:   %Core.import_ref.07c = import_ref Core//default, inst39 [no loc], unloaded
-// CHECK:STDOUT:   %Core.import_ref.a6b: %Op.assoc_type = import_ref Core//default, loc8_41, loaded [template = constants.%assoc0.8e5]
+// CHECK:STDOUT:   %Core.import_ref.bdf: %Add.assoc_type = import_ref Core//default, loc8_41, loaded [template = constants.%assoc0.b3c]
 // CHECK:STDOUT:   %Core.Op = import_ref Core//default, Op, unloaded
 // CHECK:STDOUT:   %Core.import_ref.c8c7cd.1: type = import_ref Core//default, loc19_6, loaded [template = constants.%i32.builtin]
 // CHECK:STDOUT:   %Core.import_ref.bf0: type = import_ref Core//default, loc19_13, loaded [template = constants.%Add.type]
@@ -672,7 +672,7 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   %Core.import_ref.1e5: type = import_ref Core//default, loc23_28, loaded [template = constants.%As.type.a6d]
 // CHECK:STDOUT:   %Core.import_ref.de9: <witness> = import_ref Core//default, loc27_38, loaded [template = constants.%impl_witness.39c]
 // CHECK:STDOUT:   %Core.import_ref.ff5 = import_ref Core//default, inst128 [no loc], unloaded
-// CHECK:STDOUT:   %Core.import_ref.589: @ImplicitAs.%Convert.assoc_type (%Convert.assoc_type.c0e) = import_ref Core//default, loc16_32, loaded [symbolic = @ImplicitAs.%assoc0 (constants.%assoc0.5048c6.2)]
+// CHECK:STDOUT:   %Core.import_ref.630: @ImplicitAs.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.837) = import_ref Core//default, loc16_32, loaded [symbolic = @ImplicitAs.%assoc0 (constants.%assoc0.43db8b.2)]
 // CHECK:STDOUT:   %Core.Convert.e69 = import_ref Core//default, Convert, unloaded
 // CHECK:STDOUT:   %Core.import_ref.8721d7.2: type = import_ref Core//default, loc27_17, loaded [template = Core.IntLiteral]
 // CHECK:STDOUT:   %Core.import_ref.4d9: type = import_ref Core//default, loc27_36, loaded [template = constants.%ImplicitAs.type.61e]
@@ -742,13 +742,13 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   %Self: %As.type.eed = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self.65a)]
 // CHECK:STDOUT:   %Convert.type: type = fn_type @Convert.1, @As(%T) [symbolic = %Convert.type (constants.%Convert.type.843)]
 // CHECK:STDOUT:   %Convert: @As.%Convert.type (%Convert.type.843) = struct_value () [symbolic = %Convert (constants.%Convert.95f)]
-// CHECK:STDOUT:   %Convert.assoc_type: type = assoc_entity_type @As.%As.type (%As.type.eed), @As.%Convert.type (%Convert.type.843) [symbolic = %Convert.assoc_type (constants.%Convert.assoc_type.1e9)]
-// CHECK:STDOUT:   %assoc0: @As.%Convert.assoc_type (%Convert.assoc_type.1e9) = assoc_entity element0, imports.%Core.import_ref.4e8b20.1 [symbolic = %assoc0 (constants.%assoc0.4ac002.1)]
+// CHECK:STDOUT:   %As.assoc_type: type = assoc_entity_type @As.%As.type (%As.type.eed) [symbolic = %As.assoc_type (constants.%As.assoc_type.a44)]
+// CHECK:STDOUT:   %assoc0: @As.%As.assoc_type (%As.assoc_type.a44) = assoc_entity element0, imports.%Core.import_ref.708 [symbolic = %assoc0 (constants.%assoc0.ea3)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = imports.%Core.import_ref.a7c
-// CHECK:STDOUT:     .Convert = imports.%Core.import_ref.638
+// CHECK:STDOUT:     .Convert = imports.%Core.import_ref.713
 // CHECK:STDOUT:     witness = (imports.%Core.Convert.313)
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -756,7 +756,7 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT: interface @Add [from "core.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = imports.%Core.import_ref.07c
-// CHECK:STDOUT:   .Op = imports.%Core.import_ref.a6b
+// CHECK:STDOUT:   .Op = imports.%Core.import_ref.bdf
 // CHECK:STDOUT:   witness = (imports.%Core.Op)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -769,13 +769,13 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   %Self: %ImplicitAs.type.d62 = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self.519)]
 // CHECK:STDOUT:   %Convert.type: type = fn_type @Convert.2, @ImplicitAs(%T) [symbolic = %Convert.type (constants.%Convert.type.275)]
 // CHECK:STDOUT:   %Convert: @ImplicitAs.%Convert.type (%Convert.type.275) = struct_value () [symbolic = %Convert (constants.%Convert.42e)]
-// CHECK:STDOUT:   %Convert.assoc_type: type = assoc_entity_type @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.d62), @ImplicitAs.%Convert.type (%Convert.type.275) [symbolic = %Convert.assoc_type (constants.%Convert.assoc_type.c0e)]
-// CHECK:STDOUT:   %assoc0: @ImplicitAs.%Convert.assoc_type (%Convert.assoc_type.c0e) = assoc_entity element0, imports.%Core.import_ref.207961.1 [symbolic = %assoc0 (constants.%assoc0.5048c6.1)]
+// CHECK:STDOUT:   %ImplicitAs.assoc_type: type = assoc_entity_type @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.d62) [symbolic = %ImplicitAs.assoc_type (constants.%ImplicitAs.assoc_type.837)]
+// CHECK:STDOUT:   %assoc0: @ImplicitAs.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.837) = assoc_entity element0, imports.%Core.import_ref.207961.1 [symbolic = %assoc0 (constants.%assoc0.43db8b.1)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = imports.%Core.import_ref.ff5
-// CHECK:STDOUT:     .Convert = imports.%Core.import_ref.589
+// CHECK:STDOUT:     .Convert = imports.%Core.import_ref.630
 // CHECK:STDOUT:     witness = (imports.%Core.Convert.e69)
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -911,8 +911,8 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   %Self => constants.%Self.65a
 // CHECK:STDOUT:   %Convert.type => constants.%Convert.type.378
 // CHECK:STDOUT:   %Convert => constants.%Convert.e51
-// CHECK:STDOUT:   %Convert.assoc_type => constants.%Convert.assoc_type.b93
-// CHECK:STDOUT:   %assoc0 => constants.%assoc0.9da
+// CHECK:STDOUT:   %As.assoc_type => constants.%As.assoc_type.e21
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.545
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @ImplicitAs(constants.%T) {
@@ -929,8 +929,8 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   %Self => constants.%Self.519
 // CHECK:STDOUT:   %Convert.type => constants.%Convert.type.059
 // CHECK:STDOUT:   %Convert => constants.%Convert.4d7
-// CHECK:STDOUT:   %Convert.assoc_type => constants.%Convert.assoc_type.40f
-// CHECK:STDOUT:   %assoc0 => constants.%assoc0.44d
+// CHECK:STDOUT:   %ImplicitAs.assoc_type => constants.%ImplicitAs.assoc_type.740
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.a81
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @ImplicitAs(%T) {}
@@ -953,8 +953,8 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   %Self => constants.%Self.519
 // CHECK:STDOUT:   %Convert.type => constants.%Convert.type.71e
 // CHECK:STDOUT:   %Convert => constants.%Convert.0e2
-// CHECK:STDOUT:   %Convert.assoc_type => constants.%Convert.assoc_type.94e
-// CHECK:STDOUT:   %assoc0 => constants.%assoc0.3db
+// CHECK:STDOUT:   %ImplicitAs.assoc_type => constants.%ImplicitAs.assoc_type.29f
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.ed3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @Op.1(constants.%Self.a99) {

+ 3 - 5
toolchain/check/testdata/function/declaration/no_prelude/name_poisoning.carbon

@@ -975,7 +975,6 @@ fn F() {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(@D2.%Self: %D2.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%x.param_patt: %C);
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -1155,8 +1154,8 @@ fn F() {
 // CHECK:STDOUT:   %Self: %A.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %B.type: type = fn_type @B [template]
 // CHECK:STDOUT:   %B: %B.type = struct_value () [template]
-// CHECK:STDOUT:   %B.assoc_type: type = assoc_entity_type %A.type, %B.type [template]
-// CHECK:STDOUT:   %assoc0: %B.assoc_type = assoc_entity element0, @A.%B.decl [template]
+// CHECK:STDOUT:   %A.assoc_type: type = assoc_entity_type %A.type [template]
+// CHECK:STDOUT:   %assoc0: %A.assoc_type = assoc_entity element0, @A.%B.decl [template]
 // CHECK:STDOUT:   %X: type = class_type @X [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -1165,7 +1164,7 @@ fn F() {
 // CHECK:STDOUT: interface @A {
 // CHECK:STDOUT:   %Self: %A.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %B.decl: %B.type = fn_decl @B [template = constants.%B] {} {}
-// CHECK:STDOUT:   %assoc0: %B.assoc_type = assoc_entity element0, %B.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %A.assoc_type = assoc_entity element0, %B.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -1184,7 +1183,6 @@ fn F() {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @B(@A.%Self: %A.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 826 - 0
toolchain/check/testdata/impl/assoc_const_self.carbon

@@ -0,0 +1,826 @@
+// 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/assoc_const_self.carbon
+// TIP: To dump output, run:
+// TIP:   bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/assoc_const_self.carbon
+
+// --- assoc_const_self.carbon
+
+library "[[@TEST_NAME]]";
+
+interface I {
+  let V:! Self;
+}
+
+impl {} as I where .V = {} {}
+
+impl i32 as I where .V = 0 {}
+
+// --- fail_assoc_const_mismatch.carbon
+
+library "[[@TEST_NAME]]";
+
+interface I {
+  let V:! Self;
+}
+
+// CHECK:STDERR: fail_assoc_const_mismatch.carbon:[[@LINE+7]]:12: error: cannot implicitly convert from `Core.IntLiteral` to `{}` [ImplicitAsConversionFailure]
+// CHECK:STDERR: impl {} as I where .V = 0 {}
+// CHECK:STDERR:            ^~~~~~~~~~~~~~
+// CHECK:STDERR: fail_assoc_const_mismatch.carbon:[[@LINE+4]]:12: note: type `Core.IntLiteral` does not implement interface `Core.ImplicitAs({})` [MissingImplInMemberAccessNote]
+// CHECK:STDERR: impl {} as I where .V = 0 {}
+// CHECK:STDERR:            ^~~~~~~~~~~~~~
+// CHECK:STDERR:
+impl {} as I where .V = 0 {}
+
+// --- fail_assoc_const_not_constant_after_conversion.carbon
+
+library "[[@TEST_NAME]]";
+
+interface I {
+  let V:! Self;
+}
+
+class C {}
+
+impl () as Core.ImplicitAs(C) {
+  fn Convert[self: ()]() -> C { return {}; }
+}
+
+// CHECK:STDERR: fail_assoc_const_not_constant_after_conversion.carbon:[[@LINE+4]]:11: error: associated constant V given value that is not constant after conversion to `C` [AssociatedConstantNotConstantAfterConversion]
+// CHECK:STDERR: impl C as I where .V = () {}
+// CHECK:STDERR:           ^~~~~~~~~~~~~~~
+// CHECK:STDERR:
+impl C as I where .V = () {}
+
+// --- fail_monomorphization_failure.carbon
+
+library "[[@TEST_NAME]]";
+
+interface I(N:! Core.IntLiteral()) {
+  // CHECK:STDERR: fail_monomorphization_failure.carbon:[[@LINE+3]]:12: error: array bound of -1 is negative [ArrayBoundNegative]
+  // CHECK:STDERR:   let V:! [Self; N];
+  // CHECK:STDERR:            ^~~~
+  let V:! [Self; N];
+}
+
+// CHECK:STDERR: fail_monomorphization_failure.carbon:[[@LINE+4]]:24: note: in `V` used here [ResolvingSpecificHere]
+// CHECK:STDERR: impl {} as I(-1) where .V = () {}
+// CHECK:STDERR:                        ^~
+// CHECK:STDERR:
+impl {} as I(-1) where .V = () {}
+
+// --- fail_todo_constrained_fn.carbon
+
+library "[[@TEST_NAME]]";
+
+interface I {
+  let V:! Self;
+}
+
+fn F(T:! I where {} impls Core.ImplicitAs(.Self) and .V = {});
+
+fn CallF() {
+  // TODO: This call should eventually work.
+  // CHECK:STDERR: fail_todo_constrained_fn.carbon:[[@LINE+10]]:3: error: cannot implicitly convert from `{}` to `I where .(I.V) = {} and...` [ImplicitAsConversionFailure]
+  // CHECK:STDERR:   F({});
+  // CHECK:STDERR:   ^~~~~
+  // CHECK:STDERR: fail_todo_constrained_fn.carbon:[[@LINE+7]]:3: note: type `{}` does not implement interface `Core.ImplicitAs(I where .(I.V) = {} and...)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR:   F({});
+  // CHECK:STDERR:   ^~~~~
+  // CHECK:STDERR: fail_todo_constrained_fn.carbon:[[@LINE-10]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
+  // CHECK:STDERR: fn F(T:! I where {} impls Core.ImplicitAs(.Self) and .V = {});
+  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR:
+  F({});
+}
+
+// CHECK:STDOUT: --- assoc_const_self.carbon
+// CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %I.type: type = facet_type <@I> [template]
+// CHECK:STDOUT:   %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic]
+// CHECK:STDOUT:   %Self.as_type.b70: type = facet_access_type %Self.826 [symbolic]
+// CHECK:STDOUT:   %require_complete.9b1: <witness> = require_complete_type %Self.as_type.b70 [symbolic]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0.a1d: %I.assoc_type = assoc_entity element0, @I.%V [template]
+// CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
+// CHECK:STDOUT:   %.Self: %I.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %I.facet.1f7: %I.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
+// CHECK:STDOUT:   %require_complete.d0c: <witness> = require_complete_type %.Self.as_type [symbolic]
+// CHECK:STDOUT:   %impl.elem0: %.Self.as_type = impl_witness_access %.Self.as_wit, element0 [symbolic]
+// CHECK:STDOUT:   %empty_struct: %empty_struct_type = struct_value () [template]
+// CHECK:STDOUT:   %I_where.type.5de: type = facet_type <@I where %impl.elem0 = %empty_struct> [template]
+// CHECK:STDOUT:   %impl_witness.a4f: <witness> = impl_witness (%empty_struct) [template]
+// CHECK:STDOUT:   %I.facet.27e: %I.type = facet_value %empty_struct_type, %impl_witness.a4f [template]
+// CHECK:STDOUT:   %complete_type.357: <witness> = complete_type_witness %empty_struct_type [template]
+// CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
+// CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [template]
+// CHECK:STDOUT:   %int_0.5c6: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %I_where.type.cad: type = facet_type <@I where %impl.elem0 = %int_0.5c6> [template]
+// CHECK:STDOUT:   %impl_witness.6f4: <witness> = impl_witness (%int_0.6a9) [template]
+// CHECK:STDOUT:   %I.facet.401: %I.type = facet_value %i32, %impl_witness.6f4 [template]
+// CHECK:STDOUT:   %i32.builtin: type = int_type signed, %int_32 [template]
+// CHECK:STDOUT:   %complete_type.f8a: <witness> = complete_type_witness %i32.builtin [template]
+// CHECK:STDOUT:   %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [template]
+// CHECK:STDOUT:   %impl_witness.d39: <witness> = impl_witness (imports.%Core.import_ref.a5b), @impl.2(%int_32) [template]
+// CHECK:STDOUT:   %Convert.type.035: type = fn_type @Convert.2, @impl.2(%int_32) [template]
+// CHECK:STDOUT:   %Convert.956: %Convert.type.035 = struct_value () [template]
+// CHECK:STDOUT:   %Convert.bound: <bound method> = bound_method %int_0.5c6, %Convert.956 [template]
+// CHECK:STDOUT:   %Convert.specific_fn: <specific function> = specific_function %Convert.bound, @Convert.2(%int_32) [template]
+// CHECK:STDOUT:   %int_0.6a9: %i32 = int_value 0 [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
+// CHECK:STDOUT:     .Int = %Core.Int
+// CHECK:STDOUT:     .ImplicitAs = %Core.ImplicitAs
+// CHECK:STDOUT:     import Core//prelude
+// CHECK:STDOUT:     import Core//prelude/...
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: file {
+// CHECK:STDOUT:   package: <namespace> = namespace [template] {
+// CHECK:STDOUT:     .Core = imports.%Core
+// CHECK:STDOUT:     .I = %I.decl
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Core.import = import Core
+// CHECK:STDOUT:   %I.decl: type = interface_decl @I [template = constants.%I.type] {} {}
+// CHECK:STDOUT:   impl_decl @impl.1 [template] {} {
+// CHECK:STDOUT:     %.loc8_7.1: %empty_struct_type = struct_literal ()
+// CHECK:STDOUT:     %.loc8_7.2: type = converted %.loc8_7.1, constants.%empty_struct_type [template = constants.%empty_struct_type]
+// CHECK:STDOUT:     %I.ref: type = name_ref I, file.%I.decl [template = constants.%I.type]
+// CHECK:STDOUT:     %.Self: %I.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
+// CHECK:STDOUT:     %.Self.ref: %I.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
+// CHECK:STDOUT:     %V.ref: %I.assoc_type = name_ref V, @V.%assoc0 [template = constants.%assoc0.a1d]
+// CHECK:STDOUT:     %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc8_20: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
+// CHECK:STDOUT:     %impl.elem0: %.Self.as_type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
+// CHECK:STDOUT:     %.loc8_26.1: %empty_struct_type = struct_literal ()
+// CHECK:STDOUT:     %empty_struct: %empty_struct_type = struct_value () [template = constants.%empty_struct]
+// CHECK:STDOUT:     %.loc8_26.2: %empty_struct_type = converted %.loc8_26.1, %empty_struct [template = constants.%empty_struct]
+// CHECK:STDOUT:     %.loc8_14: type = where_expr %.Self [template = constants.%I_where.type.5de] {
+// CHECK:STDOUT:       requirement_rewrite %impl.elem0, %.loc8_26.2
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %impl_witness.loc8: <witness> = impl_witness (constants.%empty_struct) [template = constants.%impl_witness.a4f]
+// CHECK:STDOUT:   impl_decl @impl.45 [template] {} {
+// CHECK:STDOUT:     %int_32: Core.IntLiteral = int_value 32 [template = constants.%int_32]
+// CHECK:STDOUT:     %i32: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
+// CHECK:STDOUT:     %I.ref: type = name_ref I, file.%I.decl [template = constants.%I.type]
+// CHECK:STDOUT:     %.Self: %I.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
+// CHECK:STDOUT:     %.Self.ref: %I.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
+// CHECK:STDOUT:     %V.ref: %I.assoc_type = name_ref V, @V.%assoc0 [template = constants.%assoc0.a1d]
+// CHECK:STDOUT:     %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc10_21: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
+// CHECK:STDOUT:     %impl.elem0: %.Self.as_type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
+// CHECK:STDOUT:     %int_0: Core.IntLiteral = int_value 0 [template = constants.%int_0.5c6]
+// CHECK:STDOUT:     %.loc10_15: type = where_expr %.Self [template = constants.%I_where.type.cad] {
+// CHECK:STDOUT:       requirement_rewrite %impl.elem0, %int_0
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %impl_witness.loc10: <witness> = impl_witness (constants.%int_0.6a9) [template = constants.%impl_witness.6f4]
+// CHECK:STDOUT:   %impl.elem0: %Convert.type.1b6 = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
+// CHECK:STDOUT:   %Convert.bound: <bound method> = bound_method constants.%int_0.5c6, %impl.elem0 [template = constants.%Convert.bound]
+// CHECK:STDOUT:   %Convert.specific_fn: <specific function> = specific_function %Convert.bound, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn]
+// CHECK:STDOUT:   %int.convert_checked: init %i32 = call %Convert.specific_fn(constants.%int_0.5c6) [template = constants.%int_0.6a9]
+// CHECK:STDOUT:   %.loc10_15.1: %i32 = value_of_initializer %int.convert_checked [template = constants.%int_0.6a9]
+// CHECK:STDOUT:   %.loc10_15.2: %i32 = converted constants.%int_0.5c6, %.loc10_15.1 [template = constants.%int_0.6a9]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: interface @I {
+// CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826]
+// CHECK:STDOUT:   %V: @V.%Self.as_type (%Self.as_type.b70) = assoc_const_decl @V [template] {
+// CHECK:STDOUT:     %assoc0: %I.assoc_type = assoc_entity element0, @I.%V [template = constants.%assoc0.a1d]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = %Self
+// CHECK:STDOUT:   .V = @V.%assoc0
+// CHECK:STDOUT:   witness = (%V)
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @V(@I.%Self: %I.type) {
+// CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.826)]
+// CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic = %Self.as_type (constants.%Self.as_type.b70)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type @V.%Self.as_type (%Self.as_type.b70) [symbolic = %require_complete (constants.%require_complete.9b1)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   assoc_const V:! @V.%Self.as_type (%Self.as_type.b70);
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: impl @impl.1: %.loc8_7.2 as %.loc8_14 {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   witness = file.%impl_witness.loc8
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: impl @impl.45: %i32 as %.loc10_15 {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   witness = file.%impl_witness.loc10
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @V(constants.%Self.826) {
+// CHECK:STDOUT:   %Self => constants.%Self.826
+// CHECK:STDOUT:   %Self.as_type => constants.%Self.as_type.b70
+// CHECK:STDOUT:   %require_complete => constants.%require_complete.9b1
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @V(constants.%I.facet.1f7) {
+// CHECK:STDOUT:   %Self => constants.%I.facet.1f7
+// CHECK:STDOUT:   %Self.as_type => constants.%.Self.as_type
+// CHECK:STDOUT:   %require_complete => constants.%require_complete.d0c
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @V(constants.%I.facet.27e) {
+// CHECK:STDOUT:   %Self => constants.%I.facet.27e
+// CHECK:STDOUT:   %Self.as_type => constants.%empty_struct_type
+// CHECK:STDOUT:   %require_complete => constants.%complete_type.357
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @V(constants.%I.facet.401) {
+// CHECK:STDOUT:   %Self => constants.%I.facet.401
+// CHECK:STDOUT:   %Self.as_type => constants.%i32
+// CHECK:STDOUT:   %require_complete => constants.%complete_type.f8a
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: --- fail_assoc_const_mismatch.carbon
+// CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %I.type: type = facet_type <@I> [template]
+// CHECK:STDOUT:   %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic]
+// CHECK:STDOUT:   %Self.as_type.b70: type = facet_access_type %Self.826 [symbolic]
+// CHECK:STDOUT:   %require_complete.9b1: <witness> = require_complete_type %Self.as_type.b70 [symbolic]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0.a1d: %I.assoc_type = assoc_entity element0, @I.%V [template]
+// CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
+// CHECK:STDOUT:   %.Self: %I.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %I.facet.1f7: %I.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
+// CHECK:STDOUT:   %require_complete.d0c: <witness> = require_complete_type %.Self.as_type [symbolic]
+// CHECK:STDOUT:   %impl.elem0: %.Self.as_type = impl_witness_access %.Self.as_wit, element0 [symbolic]
+// CHECK:STDOUT:   %int_0: Core.IntLiteral = int_value 0 [template]
+// CHECK:STDOUT:   %I_where.type: type = facet_type <@I where %impl.elem0 = %int_0> [template]
+// CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (<error>) [template]
+// CHECK:STDOUT:   %I.facet.c20: %I.type = facet_value %empty_struct_type, %impl_witness [template]
+// CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
+// CHECK:STDOUT:     .ImplicitAs = %Core.ImplicitAs
+// CHECK:STDOUT:     import Core//prelude
+// CHECK:STDOUT:     import Core//prelude/...
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: file {
+// CHECK:STDOUT:   package: <namespace> = namespace [template] {
+// CHECK:STDOUT:     .Core = imports.%Core
+// CHECK:STDOUT:     .I = %I.decl
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Core.import = import Core
+// CHECK:STDOUT:   %I.decl: type = interface_decl @I [template = constants.%I.type] {} {}
+// CHECK:STDOUT:   impl_decl @impl [template] {} {
+// CHECK:STDOUT:     %.loc15_7.1: %empty_struct_type = struct_literal ()
+// CHECK:STDOUT:     %.loc15_7.2: type = converted %.loc15_7.1, constants.%empty_struct_type [template = constants.%empty_struct_type]
+// CHECK:STDOUT:     %I.ref: type = name_ref I, file.%I.decl [template = constants.%I.type]
+// CHECK:STDOUT:     %.Self: %I.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
+// CHECK:STDOUT:     %.Self.ref: %I.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
+// CHECK:STDOUT:     %V.ref: %I.assoc_type = name_ref V, @V.%assoc0 [template = constants.%assoc0.a1d]
+// CHECK:STDOUT:     %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc15_20: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
+// CHECK:STDOUT:     %impl.elem0: %.Self.as_type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
+// CHECK:STDOUT:     %int_0: Core.IntLiteral = int_value 0 [template = constants.%int_0]
+// CHECK:STDOUT:     %.loc15_14: type = where_expr %.Self [template = constants.%I_where.type] {
+// CHECK:STDOUT:       requirement_rewrite %impl.elem0, %int_0
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (<error>) [template = constants.%impl_witness]
+// CHECK:STDOUT:   %.loc15: %empty_struct_type = converted constants.%int_0, <error> [template = <error>]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: interface @I {
+// CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826]
+// CHECK:STDOUT:   %V: @V.%Self.as_type (%Self.as_type.b70) = assoc_const_decl @V [template] {
+// CHECK:STDOUT:     %assoc0: %I.assoc_type = assoc_entity element0, @I.%V [template = constants.%assoc0.a1d]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = %Self
+// CHECK:STDOUT:   .V = @V.%assoc0
+// CHECK:STDOUT:   witness = (%V)
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @V(@I.%Self: %I.type) {
+// CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.826)]
+// CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic = %Self.as_type (constants.%Self.as_type.b70)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type @V.%Self.as_type (%Self.as_type.b70) [symbolic = %require_complete (constants.%require_complete.9b1)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   assoc_const V:! @V.%Self.as_type (%Self.as_type.b70);
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: impl @impl: %.loc15_7.2 as %.loc15_14 {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   witness = file.%impl_witness
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @V(constants.%Self.826) {
+// CHECK:STDOUT:   %Self => constants.%Self.826
+// CHECK:STDOUT:   %Self.as_type => constants.%Self.as_type.b70
+// CHECK:STDOUT:   %require_complete => constants.%require_complete.9b1
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @V(constants.%I.facet.1f7) {
+// CHECK:STDOUT:   %Self => constants.%I.facet.1f7
+// CHECK:STDOUT:   %Self.as_type => constants.%.Self.as_type
+// CHECK:STDOUT:   %require_complete => constants.%require_complete.d0c
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @V(constants.%I.facet.c20) {
+// CHECK:STDOUT:   %Self => constants.%I.facet.c20
+// CHECK:STDOUT:   %Self.as_type => constants.%empty_struct_type
+// CHECK:STDOUT:   %require_complete => constants.%complete_type
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: --- fail_assoc_const_not_constant_after_conversion.carbon
+// CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %I.type: type = facet_type <@I> [template]
+// CHECK:STDOUT:   %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic]
+// CHECK:STDOUT:   %Self.as_type.b70: type = facet_access_type %Self.826 [symbolic]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
+// CHECK:STDOUT:   %require_complete.9b1: <witness> = require_complete_type %Self.as_type.b70 [symbolic]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0.a1d: %I.assoc_type = assoc_entity element0, @I.%V [template]
+// CHECK:STDOUT:   %C: type = class_type @C [template]
+// CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
+// CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [template]
+// CHECK:STDOUT:   %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [template]
+// CHECK:STDOUT:   %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [template]
+// CHECK:STDOUT:   %ImplicitAs.type.15e: type = facet_type <@ImplicitAs, @ImplicitAs(%C)> [template]
+// CHECK:STDOUT:   %Convert.type.56d: type = fn_type @Convert.1, @ImplicitAs(%C) [template]
+// CHECK:STDOUT:   %impl_witness.3db: <witness> = impl_witness (@impl.1.%Convert.decl) [template]
+// CHECK:STDOUT:   %Convert.type.721: type = fn_type @Convert.2 [template]
+// CHECK:STDOUT:   %Convert.155: %Convert.type.721 = struct_value () [template]
+// CHECK:STDOUT:   %C.val: %C = struct_value () [template]
+// CHECK:STDOUT:   %.Self: %I.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %I.facet.1f7: %I.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
+// CHECK:STDOUT:   %require_complete.d0c: <witness> = require_complete_type %.Self.as_type [symbolic]
+// CHECK:STDOUT:   %impl.elem0: %.Self.as_type = impl_witness_access %.Self.as_wit, element0 [symbolic]
+// CHECK:STDOUT:   %empty_tuple: %empty_tuple.type = tuple_value () [template]
+// CHECK:STDOUT:   %I_where.type: type = facet_type <@I where %impl.elem0 = %empty_tuple> [template]
+// CHECK:STDOUT:   %impl_witness.85b: <witness> = impl_witness (<error>) [template]
+// CHECK:STDOUT:   %I.facet.b45: %I.type = facet_value %C, %impl_witness.85b [template]
+// CHECK:STDOUT:   %Convert.bound: <bound method> = bound_method %empty_tuple, %Convert.155 [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
+// CHECK:STDOUT:     .ImplicitAs = %Core.ImplicitAs
+// CHECK:STDOUT:     import Core//prelude
+// CHECK:STDOUT:     import Core//prelude/...
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/operators/as, ImplicitAs, loaded [template = constants.%ImplicitAs.generic]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: file {
+// CHECK:STDOUT:   package: <namespace> = namespace [template] {
+// CHECK:STDOUT:     .Core = imports.%Core
+// CHECK:STDOUT:     .I = %I.decl
+// CHECK:STDOUT:     .C = %C.decl
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Core.import = import Core
+// CHECK:STDOUT:   %I.decl: type = interface_decl @I [template = constants.%I.type] {} {}
+// CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {} {}
+// CHECK:STDOUT:   impl_decl @impl.1 [template] {} {
+// CHECK:STDOUT:     %.loc10_7.1: %empty_tuple.type = tuple_literal ()
+// CHECK:STDOUT:     %.loc10_7.2: type = converted %.loc10_7.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type]
+// CHECK:STDOUT:     %Core.ref: <namespace> = name_ref Core, imports.%Core [template = imports.%Core]
+// CHECK:STDOUT:     %ImplicitAs.ref: %ImplicitAs.type.cc7 = name_ref ImplicitAs, imports.%Core.ImplicitAs [template = constants.%ImplicitAs.generic]
+// CHECK:STDOUT:     %C.ref: type = name_ref C, file.%C.decl [template = constants.%C]
+// CHECK:STDOUT:     %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(constants.%C)> [template = constants.%ImplicitAs.type.15e]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %impl_witness.loc10: <witness> = impl_witness (@impl.1.%Convert.decl) [template = constants.%impl_witness.3db]
+// CHECK:STDOUT:   impl_decl @impl.2 [template] {} {
+// CHECK:STDOUT:     %C.ref: type = name_ref C, file.%C.decl [template = constants.%C]
+// CHECK:STDOUT:     %I.ref: type = name_ref I, file.%I.decl [template = constants.%I.type]
+// CHECK:STDOUT:     %.Self: %I.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
+// CHECK:STDOUT:     %.Self.ref: %I.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
+// CHECK:STDOUT:     %V.ref: %I.assoc_type = name_ref V, @V.%assoc0 [template = constants.%assoc0.a1d]
+// CHECK:STDOUT:     %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc18_19: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
+// CHECK:STDOUT:     %impl.elem0: %.Self.as_type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
+// CHECK:STDOUT:     %.loc18_25.1: %empty_tuple.type = tuple_literal ()
+// CHECK:STDOUT:     %empty_tuple: %empty_tuple.type = tuple_value () [template = constants.%empty_tuple]
+// CHECK:STDOUT:     %.loc18_25.2: %empty_tuple.type = converted %.loc18_25.1, %empty_tuple [template = constants.%empty_tuple]
+// CHECK:STDOUT:     %.loc18_13: type = where_expr %.Self [template = constants.%I_where.type] {
+// CHECK:STDOUT:       requirement_rewrite %impl.elem0, %.loc18_25.2
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %impl_witness.loc18: <witness> = impl_witness (<error>) [template = constants.%impl_witness.85b]
+// CHECK:STDOUT:   %impl.elem0: %Convert.type.56d = impl_witness_access constants.%impl_witness.3db, element0 [template = constants.%Convert.155]
+// CHECK:STDOUT:   %Convert.bound: <bound method> = bound_method constants.%empty_tuple, %impl.elem0 [template = constants.%Convert.bound]
+// CHECK:STDOUT:   %.loc18_13.1: ref %C = temporary_storage
+// CHECK:STDOUT:   %Convert.call: init %C = call %Convert.bound(constants.%empty_tuple) to %.loc18_13.1
+// CHECK:STDOUT:   %.loc18_13.2: init %C = converted constants.%empty_tuple, %Convert.call
+// CHECK:STDOUT:   %.loc18_13.3: ref %C = temporary %.loc18_13.1, %.loc18_13.2
+// CHECK:STDOUT:   %.loc18_13.4: %C = bind_value %.loc18_13.3
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: interface @I {
+// CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826]
+// CHECK:STDOUT:   %V: @V.%Self.as_type (%Self.as_type.b70) = assoc_const_decl @V [template] {
+// CHECK:STDOUT:     %assoc0: %I.assoc_type = assoc_entity element0, @I.%V [template = constants.%assoc0.a1d]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = %Self
+// CHECK:STDOUT:   .V = @V.%assoc0
+// CHECK:STDOUT:   witness = (%V)
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @V(@I.%Self: %I.type) {
+// CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.826)]
+// CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic = %Self.as_type (constants.%Self.as_type.b70)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type @V.%Self.as_type (%Self.as_type.b70) [symbolic = %require_complete (constants.%require_complete.9b1)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   assoc_const V:! @V.%Self.as_type (%Self.as_type.b70);
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: impl @impl.1: %.loc10_7.2 as %ImplicitAs.type {
+// CHECK:STDOUT:   %Convert.decl: %Convert.type.721 = fn_decl @Convert.2 [template = constants.%Convert.155] {
+// CHECK:STDOUT:     %self.patt: %empty_tuple.type = binding_pattern self
+// CHECK:STDOUT:     %self.param_patt: %empty_tuple.type = value_param_pattern %self.patt, runtime_param0
+// CHECK:STDOUT:     %return.patt: %C = return_slot_pattern
+// CHECK:STDOUT:     %return.param_patt: %C = out_param_pattern %return.patt, runtime_param1
+// CHECK:STDOUT:   } {
+// CHECK:STDOUT:     %C.ref: type = name_ref C, file.%C.decl [template = constants.%C]
+// CHECK:STDOUT:     %self.param: %empty_tuple.type = value_param runtime_param0
+// CHECK:STDOUT:     %.loc11_21.1: type = splice_block %.loc11_21.3 [template = constants.%empty_tuple.type] {
+// CHECK:STDOUT:       %.loc11_21.2: %empty_tuple.type = tuple_literal ()
+// CHECK:STDOUT:       %.loc11_21.3: type = converted %.loc11_21.2, constants.%empty_tuple.type [template = constants.%empty_tuple.type]
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %self: %empty_tuple.type = bind_name self, %self.param
+// CHECK:STDOUT:     %return.param: ref %C = out_param runtime_param1
+// CHECK:STDOUT:     %return: ref %C = return_slot %return.param
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Convert = %Convert.decl
+// CHECK:STDOUT:   witness = file.%impl_witness.loc10
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: impl @impl.2: %C.ref as %.loc18_13 {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   witness = file.%impl_witness.loc18
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: class @C {
+// CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [template = constants.%complete_type]
+// CHECK:STDOUT:   complete_type_witness = %complete_type
+// CHECK:STDOUT:
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Convert.2[%self.param_patt: %empty_tuple.type]() -> %return.param_patt: %C {
+// CHECK:STDOUT: !entry:
+// CHECK:STDOUT:   %.loc11_41.1: %empty_struct_type = struct_literal ()
+// CHECK:STDOUT:   %.loc11_41.2: init %C = class_init (), %return [template = constants.%C.val]
+// CHECK:STDOUT:   %.loc11_42: init %C = converted %.loc11_41.1, %.loc11_41.2 [template = constants.%C.val]
+// CHECK:STDOUT:   return %.loc11_42 to %return
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @V(constants.%Self.826) {
+// CHECK:STDOUT:   %Self => constants.%Self.826
+// CHECK:STDOUT:   %Self.as_type => constants.%Self.as_type.b70
+// CHECK:STDOUT:   %require_complete => constants.%require_complete.9b1
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @V(constants.%I.facet.1f7) {
+// CHECK:STDOUT:   %Self => constants.%I.facet.1f7
+// CHECK:STDOUT:   %Self.as_type => constants.%.Self.as_type
+// CHECK:STDOUT:   %require_complete => constants.%require_complete.d0c
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @V(constants.%I.facet.b45) {
+// CHECK:STDOUT:   %Self => constants.%I.facet.b45
+// CHECK:STDOUT:   %Self.as_type => constants.%C
+// CHECK:STDOUT:   %require_complete => constants.%complete_type
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: --- fail_monomorphization_failure.carbon
+// CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %IntLiteral.type: type = fn_type @IntLiteral [template]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
+// CHECK:STDOUT:   %IntLiteral: %IntLiteral.type = struct_value () [template]
+// CHECK:STDOUT:   %N: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic]
+// CHECK:STDOUT:   %N.patt: Core.IntLiteral = symbolic_binding_pattern N, 0 [symbolic]
+// CHECK:STDOUT:   %I.type.dac: type = generic_interface_type @I [template]
+// CHECK:STDOUT:   %I.generic: %I.type.dac = struct_value () [template]
+// CHECK:STDOUT:   %I.type.8a1: type = facet_type <@I, @I(%N)> [symbolic]
+// CHECK:STDOUT:   %Self.3a0: %I.type.8a1 = bind_symbolic_name Self, 1 [symbolic]
+// CHECK:STDOUT:   %Self.as_type.72b: type = facet_access_type %Self.3a0 [symbolic]
+// CHECK:STDOUT:   %array_type: type = array_type %N, %Self.as_type.72b [symbolic]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %array_type [symbolic]
+// CHECK:STDOUT:   %I.assoc_type.656: type = assoc_entity_type %I.type.8a1 [symbolic]
+// CHECK:STDOUT:   %assoc0.6db: %I.assoc_type.656 = assoc_entity element0, @I.%V [symbolic]
+// CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
+// CHECK:STDOUT:   %int_1: Core.IntLiteral = int_value 1 [template]
+// CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (imports.%Core.import_ref.c15) [template]
+// CHECK:STDOUT:   %Op.type.e42: type = fn_type @Op.1 [template]
+// CHECK:STDOUT:   %Op.type.1be: type = fn_type @Op.2 [template]
+// CHECK:STDOUT:   %Op.bba: %Op.type.1be = struct_value () [template]
+// CHECK:STDOUT:   %Op.bound: <bound method> = bound_method %int_1, %Op.bba [template]
+// CHECK:STDOUT:   %int_-1: Core.IntLiteral = int_value -1 [template]
+// CHECK:STDOUT:   %I.type.057: type = facet_type <@I, @I(%int_-1)> [template]
+// CHECK:STDOUT:   %.Self: %I.type.057 = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %I.assoc_type.3f5: type = assoc_entity_type %I.type.057 [template]
+// CHECK:STDOUT:   %assoc0.34f: %I.assoc_type.3f5 = assoc_entity element0, @I.%V [template]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %I.facet: %I.type.8a1 = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
+// CHECK:STDOUT:   %impl.elem0: <error> = impl_witness_access %.Self.as_wit, element0 [symbolic]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
+// CHECK:STDOUT:     .IntLiteral = %Core.IntLiteral
+// CHECK:STDOUT:     .Negate = %Core.Negate
+// CHECK:STDOUT:     import Core//prelude
+// CHECK:STDOUT:     import Core//prelude/...
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Core.IntLiteral: %IntLiteral.type = import_ref Core//prelude/types/int_literal, IntLiteral, loaded [template = constants.%IntLiteral]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: file {
+// CHECK:STDOUT:   package: <namespace> = namespace [template] {
+// CHECK:STDOUT:     .Core = imports.%Core
+// CHECK:STDOUT:     .I = %I.decl
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Core.import = import Core
+// CHECK:STDOUT:   %I.decl: %I.type.dac = interface_decl @I [template = constants.%I.generic] {
+// CHECK:STDOUT:     %N.patt.loc4_13.1: Core.IntLiteral = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc4_13.2 (constants.%N.patt)]
+// CHECK:STDOUT:     %N.param_patt: Core.IntLiteral = value_param_pattern %N.patt.loc4_13.1, runtime_param<none> [symbolic = %N.patt.loc4_13.2 (constants.%N.patt)]
+// CHECK:STDOUT:   } {
+// CHECK:STDOUT:     %N.param: Core.IntLiteral = value_param runtime_param<none>
+// CHECK:STDOUT:     %.loc4_33.1: type = splice_block %.loc4_33.3 [template = Core.IntLiteral] {
+// CHECK:STDOUT:       %Core.ref: <namespace> = name_ref Core, imports.%Core [template = imports.%Core]
+// CHECK:STDOUT:       %IntLiteral.ref: %IntLiteral.type = name_ref IntLiteral, imports.%Core.IntLiteral [template = constants.%IntLiteral]
+// CHECK:STDOUT:       %int_literal.make_type: init type = call %IntLiteral.ref() [template = Core.IntLiteral]
+// CHECK:STDOUT:       %.loc4_33.2: type = value_of_initializer %int_literal.make_type [template = Core.IntLiteral]
+// CHECK:STDOUT:       %.loc4_33.3: type = converted %int_literal.make_type, %.loc4_33.2 [template = Core.IntLiteral]
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %N.loc4_13.1: Core.IntLiteral = bind_symbolic_name N, 0, %N.param [symbolic = %N.loc4_13.2 (constants.%N)]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   impl_decl @impl.7 [template] {} {
+// CHECK:STDOUT:     %.loc15_7.1: %empty_struct_type = struct_literal ()
+// CHECK:STDOUT:     %.loc15_7.2: type = converted %.loc15_7.1, constants.%empty_struct_type [template = constants.%empty_struct_type]
+// CHECK:STDOUT:     %I.ref: %I.type.dac = name_ref I, file.%I.decl [template = constants.%I.generic]
+// CHECK:STDOUT:     %int_1: Core.IntLiteral = int_value 1 [template = constants.%int_1]
+// CHECK:STDOUT:     %impl.elem0.loc15_14: %Op.type.e42 = impl_witness_access constants.%impl_witness, element0 [template = constants.%Op.bba]
+// CHECK:STDOUT:     %Op.bound: <bound method> = bound_method %int_1, %impl.elem0.loc15_14 [template = constants.%Op.bound]
+// CHECK:STDOUT:     %int.snegate: init Core.IntLiteral = call %Op.bound(%int_1) [template = constants.%int_-1]
+// CHECK:STDOUT:     %.loc15_16.1: Core.IntLiteral = value_of_initializer %int.snegate [template = constants.%int_-1]
+// CHECK:STDOUT:     %.loc15_16.2: Core.IntLiteral = converted %int.snegate, %.loc15_16.1 [template = constants.%int_-1]
+// CHECK:STDOUT:     %I.type: type = facet_type <@I, @I(constants.%int_-1)> [template = constants.%I.type.057]
+// CHECK:STDOUT:     %.Self: %I.type.057 = bind_symbolic_name .Self [symbolic = constants.%.Self]
+// CHECK:STDOUT:     %.Self.ref: %I.type.057 = name_ref .Self, %.Self [symbolic = constants.%.Self]
+// CHECK:STDOUT:     %.loc15_24.1: %I.assoc_type.3f5 = specific_constant @V.%assoc0, @I(constants.%int_-1) [template = constants.%assoc0.34f]
+// CHECK:STDOUT:     %V.ref: %I.assoc_type.3f5 = name_ref V, %.loc15_24.1 [template = constants.%assoc0.34f]
+// CHECK:STDOUT:     %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc15_24.2: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
+// CHECK:STDOUT:     %impl.elem0.loc15_24: <error> = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
+// CHECK:STDOUT:     %.loc15_30: %empty_tuple.type = tuple_literal ()
+// CHECK:STDOUT:     %.loc15_18: type = where_expr %.Self [template = <error>] {
+// CHECK:STDOUT:       requirement_rewrite %impl.elem0.loc15_24, <error>
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic interface @I(%N.loc4_13.1: Core.IntLiteral) {
+// CHECK:STDOUT:   %N.loc4_13.2: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic = %N.loc4_13.2 (constants.%N)]
+// CHECK:STDOUT:   %N.patt.loc4_13.2: Core.IntLiteral = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc4_13.2 (constants.%N.patt)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %I.type: type = facet_type <@I, @I(%N.loc4_13.2)> [symbolic = %I.type (constants.%I.type.8a1)]
+// CHECK:STDOUT:   %Self.2: %I.type.8a1 = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self.3a0)]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type @I.%I.type (%I.type.8a1) [symbolic = %I.assoc_type (constants.%I.assoc_type.656)]
+// CHECK:STDOUT:   %assoc0: @I.%I.assoc_type (%I.assoc_type.656) = assoc_entity element0, %V [symbolic = %assoc0 (constants.%assoc0.6db)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   interface {
+// CHECK:STDOUT:     %Self.1: @I.%I.type (%I.type.8a1) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self.3a0)]
+// CHECK:STDOUT:     %V: @V.%array_type (%array_type) = assoc_const_decl @V [template] {
+// CHECK:STDOUT:       %assoc0: @I.%I.assoc_type (%I.assoc_type.656) = assoc_entity element0, @I.%V [symbolic = @I.%assoc0 (constants.%assoc0.6db)]
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = %Self.1
+// CHECK:STDOUT:     .V = @V.%assoc0
+// CHECK:STDOUT:     witness = (%V)
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @V(@I.%N.loc4_13.1: Core.IntLiteral, @I.%Self.1: @I.%I.type (%I.type.8a1)) {
+// CHECK:STDOUT:   %N: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic = %N (constants.%N)]
+// CHECK:STDOUT:   %I.type: type = facet_type <@I, @I(%N)> [symbolic = %I.type (constants.%I.type.8a1)]
+// CHECK:STDOUT:   %Self: %I.type.8a1 = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self.3a0)]
+// CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic = %Self.as_type (constants.%Self.as_type.72b)]
+// CHECK:STDOUT:   %array_type: type = array_type %N, @V.%Self.as_type (%Self.as_type.72b) [symbolic = %array_type (constants.%array_type)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type @V.%array_type (%array_type) [symbolic = %require_complete (constants.%require_complete)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   assoc_const V:! @V.%array_type (%array_type);
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: impl @impl.7: %.loc15_7.2 as %.loc15_18 {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   witness = <error>
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @I(constants.%N) {
+// CHECK:STDOUT:   %N.loc4_13.2 => constants.%N
+// CHECK:STDOUT:   %N.patt.loc4_13.2 => constants.%N
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @V(constants.%N, constants.%Self.3a0) {
+// CHECK:STDOUT:   %N => constants.%N
+// CHECK:STDOUT:   %I.type => constants.%I.type.8a1
+// CHECK:STDOUT:   %Self => constants.%Self.3a0
+// CHECK:STDOUT:   %Self.as_type => constants.%Self.as_type.72b
+// CHECK:STDOUT:   %array_type => constants.%array_type
+// CHECK:STDOUT:   %require_complete => constants.%require_complete
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @I(@V.%N) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @I(%N.loc4_13.2) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @I(constants.%int_-1) {
+// CHECK:STDOUT:   %N.loc4_13.2 => constants.%int_-1
+// CHECK:STDOUT:   %N.patt.loc4_13.2 => constants.%int_-1
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %I.type => constants.%I.type.057
+// CHECK:STDOUT:   %Self.2 => constants.%Self.3a0
+// CHECK:STDOUT:   %I.assoc_type => constants.%I.assoc_type.3f5
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.34f
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @V(constants.%int_-1, constants.%I.facet) {
+// CHECK:STDOUT:   %N => constants.%int_-1
+// CHECK:STDOUT:   %I.type => constants.%I.type.057
+// CHECK:STDOUT:   %Self => constants.%I.facet
+// CHECK:STDOUT:   %Self.as_type => constants.%.Self.as_type
+// CHECK:STDOUT:   %array_type => <error>
+// CHECK:STDOUT:   %require_complete => <error>
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: --- fail_todo_constrained_fn.carbon
+// CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %I.type: type = facet_type <@I> [template]
+// CHECK:STDOUT:   %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic]
+// CHECK:STDOUT:   %Self.as_type.b70: type = facet_access_type %Self.826 [symbolic]
+// CHECK:STDOUT:   %require_complete.9b1: <witness> = require_complete_type %Self.as_type.b70 [symbolic]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0.a1d: %I.assoc_type = assoc_entity element0, @I.%V [template]
+// CHECK:STDOUT:   %.Self: %I.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
+// CHECK:STDOUT:   %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [template]
+// CHECK:STDOUT:   %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [template]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
+// CHECK:STDOUT:   %ImplicitAs.type.2a8: type = facet_type <@ImplicitAs, @ImplicitAs(%.Self.as_type)> [symbolic]
+// CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %I.facet: %I.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
+// CHECK:STDOUT:   %require_complete.d0c: <witness> = require_complete_type %.Self.as_type [symbolic]
+// CHECK:STDOUT:   %impl.elem0: %.Self.as_type = impl_witness_access %.Self.as_wit, element0 [symbolic]
+// CHECK:STDOUT:   %empty_struct: %empty_struct_type = struct_value () [template]
+// CHECK:STDOUT:   %I_where.type: type = facet_type <@I where %impl.elem0 = %empty_struct and TODO> [template]
+// CHECK:STDOUT:   %T: %I_where.type = bind_symbolic_name T, 0 [symbolic]
+// CHECK:STDOUT:   %T.patt: %I_where.type = symbolic_binding_pattern T, 0 [symbolic]
+// CHECK:STDOUT:   %F.type: type = fn_type @F [template]
+// CHECK:STDOUT:   %F: %F.type = struct_value () [template]
+// CHECK:STDOUT:   %CallF.type: type = fn_type @CallF [template]
+// CHECK:STDOUT:   %CallF: %CallF.type = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
+// CHECK:STDOUT:     .ImplicitAs = %Core.ImplicitAs
+// CHECK:STDOUT:     import Core//prelude
+// CHECK:STDOUT:     import Core//prelude/...
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/operators/as, ImplicitAs, loaded [template = constants.%ImplicitAs.generic]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: file {
+// CHECK:STDOUT:   package: <namespace> = namespace [template] {
+// CHECK:STDOUT:     .Core = imports.%Core
+// CHECK:STDOUT:     .I = %I.decl
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:     .CallF = %CallF.decl
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Core.import = import Core
+// CHECK:STDOUT:   %I.decl: type = interface_decl @I [template = constants.%I.type] {} {}
+// CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
+// CHECK:STDOUT:     %T.patt.loc8_6.1: %I_where.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_6.2 (constants.%T.patt)]
+// CHECK:STDOUT:     %T.param_patt: %I_where.type = value_param_pattern %T.patt.loc8_6.1, runtime_param<none> [symbolic = %T.patt.loc8_6.2 (constants.%T.patt)]
+// CHECK:STDOUT:   } {
+// CHECK:STDOUT:     %T.param: %I_where.type = value_param runtime_param<none>
+// CHECK:STDOUT:     %.loc8_12.1: type = splice_block %.loc8_12.2 [template = constants.%I_where.type] {
+// CHECK:STDOUT:       %I.ref: type = name_ref I, file.%I.decl [template = constants.%I.type]
+// CHECK:STDOUT:       %.Self: %I.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
+// CHECK:STDOUT:       %.loc8_19.1: %empty_struct_type = struct_literal ()
+// CHECK:STDOUT:       %Core.ref: <namespace> = name_ref Core, imports.%Core [template = imports.%Core]
+// CHECK:STDOUT:       %ImplicitAs.ref: %ImplicitAs.type.cc7 = name_ref ImplicitAs, imports.%Core.ImplicitAs [template = constants.%ImplicitAs.generic]
+// CHECK:STDOUT:       %.Self.ref.loc8_43: %I.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
+// CHECK:STDOUT:       %.Self.as_type.loc8_48: type = facet_access_type %.Self.ref.loc8_43 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.loc8_48: type = converted %.Self.ref.loc8_43, %.Self.as_type.loc8_48 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:       %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(constants.%.Self.as_type)> [symbolic = constants.%ImplicitAs.type.2a8]
+// CHECK:STDOUT:       %.loc8_19.2: type = converted %.loc8_19.1, constants.%empty_struct_type [template = constants.%empty_struct_type]
+// CHECK:STDOUT:       %.Self.ref.loc8_54: %I.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
+// CHECK:STDOUT:       %V.ref: %I.assoc_type = name_ref V, @V.%assoc0 [template = constants.%assoc0.a1d]
+// CHECK:STDOUT:       %.Self.as_type.loc8_54: type = facet_access_type %.Self.ref.loc8_54 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.loc8_54: type = converted %.Self.ref.loc8_54, %.Self.as_type.loc8_54 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.Self.as_wit: <witness> = facet_access_witness %.Self.ref.loc8_54 [symbolic = constants.%.Self.as_wit]
+// CHECK:STDOUT:       %impl.elem0: %.Self.as_type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
+// CHECK:STDOUT:       %.loc8_60.1: %empty_struct_type = struct_literal ()
+// CHECK:STDOUT:       %empty_struct: %empty_struct_type = struct_value () [template = constants.%empty_struct]
+// CHECK:STDOUT:       %.loc8_60.2: %empty_struct_type = converted %.loc8_60.1, %empty_struct [template = constants.%empty_struct]
+// CHECK:STDOUT:       %.loc8_12.2: type = where_expr %.Self [template = constants.%I_where.type] {
+// CHECK:STDOUT:         requirement_impls %.loc8_19.2, %ImplicitAs.type
+// CHECK:STDOUT:         requirement_rewrite %impl.elem0, %.loc8_60.2
+// CHECK:STDOUT:       }
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %T.loc8_6.1: %I_where.type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc8_6.2 (constants.%T)]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %CallF.decl: %CallF.type = fn_decl @CallF [template = constants.%CallF] {} {}
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: interface @I {
+// CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826]
+// CHECK:STDOUT:   %V: @V.%Self.as_type (%Self.as_type.b70) = assoc_const_decl @V [template] {
+// CHECK:STDOUT:     %assoc0: %I.assoc_type = assoc_entity element0, @I.%V [template = constants.%assoc0.a1d]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = %Self
+// CHECK:STDOUT:   .V = @V.%assoc0
+// CHECK:STDOUT:   witness = (%V)
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @V(@I.%Self: %I.type) {
+// CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.826)]
+// CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic = %Self.as_type (constants.%Self.as_type.b70)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type @V.%Self.as_type (%Self.as_type.b70) [symbolic = %require_complete (constants.%require_complete.9b1)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   assoc_const V:! @V.%Self.as_type (%Self.as_type.b70);
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @F(%T.loc8_6.1: %I_where.type) {
+// CHECK:STDOUT:   %T.loc8_6.2: %I_where.type = bind_symbolic_name T, 0 [symbolic = %T.loc8_6.2 (constants.%T)]
+// CHECK:STDOUT:   %T.patt.loc8_6.2: %I_where.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_6.2 (constants.%T.patt)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%T.param_patt: %I_where.type);
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @CallF() {
+// CHECK:STDOUT: !entry:
+// CHECK:STDOUT:   %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
+// CHECK:STDOUT:   %.loc22_6: %empty_struct_type = struct_literal ()
+// CHECK:STDOUT:   %.loc22_7: %I_where.type = converted %.loc22_6, <error> [template = <error>]
+// CHECK:STDOUT:   return
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @V(constants.%Self.826) {
+// CHECK:STDOUT:   %Self => constants.%Self.826
+// CHECK:STDOUT:   %Self.as_type => constants.%Self.as_type.b70
+// CHECK:STDOUT:   %require_complete => constants.%require_complete.9b1
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @V(constants.%I.facet) {
+// CHECK:STDOUT:   %Self => constants.%I.facet
+// CHECK:STDOUT:   %Self.as_type => constants.%.Self.as_type
+// CHECK:STDOUT:   %require_complete => constants.%require_complete.d0c
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F(constants.%T) {
+// CHECK:STDOUT:   %T.loc8_6.2 => constants.%T
+// CHECK:STDOUT:   %T.patt.loc8_6.2 => constants.%T
+// CHECK:STDOUT: }
+// CHECK:STDOUT:

+ 9 - 11
toolchain/check/testdata/impl/compound.carbon

@@ -42,13 +42,12 @@ fn InstanceCallIndirect(p: i32*) {
 // CHECK:STDOUT:   %F.type.e2e: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.df8: %F.type.e2e = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %Simple.type, %F.type.e2e [template]
-// CHECK:STDOUT:   %assoc0.346: %F.assoc_type = assoc_entity element0, @Simple.%F.decl [template]
+// CHECK:STDOUT:   %Simple.assoc_type: type = assoc_entity_type %Simple.type [template]
+// CHECK:STDOUT:   %assoc0.9ca: %Simple.assoc_type = assoc_entity element0, @Simple.%F.decl [template]
 // CHECK:STDOUT:   %Self.as_type.716: type = facet_access_type %Self.3c9 [symbolic]
 // CHECK:STDOUT:   %G.type.b60: type = fn_type @G.1 [template]
 // CHECK:STDOUT:   %G.cb0: %G.type.b60 = struct_value () [template]
-// CHECK:STDOUT:   %G.assoc_type: type = assoc_entity_type %Simple.type, %G.type.b60 [template]
-// CHECK:STDOUT:   %assoc1: %G.assoc_type = assoc_entity element1, @Simple.%G.decl [template]
+// CHECK:STDOUT:   %assoc1: %Simple.assoc_type = assoc_entity element1, @Simple.%G.decl [template]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [template]
 // CHECK:STDOUT:   %impl_witness.5b2: <witness> = impl_witness (@impl.1.%F.decl, @impl.1.%G.decl) [template]
@@ -144,7 +143,7 @@ fn InstanceCallIndirect(p: i32*) {
 // CHECK:STDOUT: interface @Simple {
 // CHECK:STDOUT:   %Self: %Simple.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.3c9]
 // CHECK:STDOUT:   %F.decl: %F.type.e2e = fn_decl @F.1 [template = constants.%F.df8] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0.346]
+// CHECK:STDOUT:   %assoc0: %Simple.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0.9ca]
 // CHECK:STDOUT:   %G.decl: %G.type.b60 = fn_decl @G.1 [template = constants.%G.cb0] {
 // CHECK:STDOUT:     %self.patt: @G.1.%Self.as_type.loc13_14.1 (%Self.as_type.716) = binding_pattern self
 // CHECK:STDOUT:     %self.param_patt: @G.1.%Self.as_type.loc13_14.1 (%Self.as_type.716) = value_param_pattern %self.patt, runtime_param0
@@ -157,7 +156,7 @@ fn InstanceCallIndirect(p: i32*) {
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %self: @G.1.%Self.as_type.loc13_14.1 (%Self.as_type.716) = bind_name self, %self.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc1: %G.assoc_type = assoc_entity element1, %G.decl [template = constants.%assoc1]
+// CHECK:STDOUT:   %assoc1: %Simple.assoc_type = assoc_entity element1, %G.decl [template = constants.%assoc1]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -187,7 +186,6 @@ fn InstanceCallIndirect(p: i32*) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(@Simple.%Self: %Simple.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -206,7 +204,7 @@ fn InstanceCallIndirect(p: i32*) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %n.ref: %i32 = name_ref n, %n
 // CHECK:STDOUT:   %Simple.ref: type = name_ref Simple, file.%Simple.decl [template = constants.%Simple.type]
-// CHECK:STDOUT:   %F.ref: %F.assoc_type = name_ref F, @Simple.%assoc0 [template = constants.%assoc0.346]
+// CHECK:STDOUT:   %F.ref: %Simple.assoc_type = name_ref F, @Simple.%assoc0 [template = constants.%assoc0.9ca]
 // CHECK:STDOUT:   %impl.elem0: %F.type.e2e = impl_witness_access constants.%impl_witness.5b2, element0 [template = constants.%F.df1]
 // CHECK:STDOUT:   %F.call: init %empty_tuple.type = call %impl.elem0()
 // CHECK:STDOUT:   return
@@ -216,7 +214,7 @@ fn InstanceCallIndirect(p: i32*) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %n.ref: %i32 = name_ref n, %n
 // CHECK:STDOUT:   %Simple.ref: type = name_ref Simple, file.%Simple.decl [template = constants.%Simple.type]
-// CHECK:STDOUT:   %G.ref: %G.assoc_type = name_ref G, @Simple.%assoc1 [template = constants.%assoc1]
+// CHECK:STDOUT:   %G.ref: %Simple.assoc_type = name_ref G, @Simple.%assoc1 [template = constants.%assoc1]
 // CHECK:STDOUT:   %impl.elem1: %G.type.b60 = impl_witness_access constants.%impl_witness.5b2, element1 [template = constants.%G.e73]
 // CHECK:STDOUT:   %G.bound: <bound method> = bound_method %n.ref, %impl.elem1
 // CHECK:STDOUT:   %G.call: init %empty_tuple.type = call %G.bound(%n.ref)
@@ -227,7 +225,7 @@ fn InstanceCallIndirect(p: i32*) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %p.ref: %ptr = name_ref p, %p
 // CHECK:STDOUT:   %Simple.ref: type = name_ref Simple, file.%Simple.decl [template = constants.%Simple.type]
-// CHECK:STDOUT:   %F.ref: %F.assoc_type = name_ref F, @Simple.%assoc0 [template = constants.%assoc0.346]
+// CHECK:STDOUT:   %F.ref: %Simple.assoc_type = name_ref F, @Simple.%assoc0 [template = constants.%assoc0.9ca]
 // CHECK:STDOUT:   %.loc30: ref %i32 = deref %p.ref
 // CHECK:STDOUT:   %impl.elem0: %F.type.e2e = impl_witness_access constants.%impl_witness.5b2, element0 [template = constants.%F.df1]
 // CHECK:STDOUT:   %F.call: init %empty_tuple.type = call %impl.elem0()
@@ -238,7 +236,7 @@ fn InstanceCallIndirect(p: i32*) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %p.ref: %ptr = name_ref p, %p
 // CHECK:STDOUT:   %Simple.ref: type = name_ref Simple, file.%Simple.decl [template = constants.%Simple.type]
-// CHECK:STDOUT:   %G.ref: %G.assoc_type = name_ref G, @Simple.%assoc1 [template = constants.%assoc1]
+// CHECK:STDOUT:   %G.ref: %Simple.assoc_type = name_ref G, @Simple.%assoc1 [template = constants.%assoc1]
 // CHECK:STDOUT:   %.loc34_4.1: ref %i32 = deref %p.ref
 // CHECK:STDOUT:   %impl.elem1: %G.type.b60 = impl_witness_access constants.%impl_witness.5b2, element1 [template = constants.%G.e73]
 // CHECK:STDOUT:   %G.bound: <bound method> = bound_method %.loc34_4.1, %impl.elem1

+ 5 - 6
toolchain/check/testdata/impl/extend_impl.carbon

@@ -31,8 +31,8 @@ fn G(c: C) {
 // CHECK:STDOUT:   %F.type.b7b: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.f50: %F.type.b7b = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %HasF.type, %F.type.b7b [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @HasF.%F.decl [template]
+// CHECK:STDOUT:   %HasF.assoc_type: type = assoc_entity_type %HasF.type [template]
+// CHECK:STDOUT:   %assoc0: %HasF.assoc_type = assoc_entity element0, @HasF.%F.decl [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (@impl.%F.decl) [template]
 // CHECK:STDOUT:   %F.type.a65: type = fn_type @F.2 [template]
@@ -74,7 +74,7 @@ fn G(c: C) {
 // CHECK:STDOUT: interface @HasF {
 // CHECK:STDOUT:   %Self: %HasF.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type.b7b = fn_decl @F.1 [template = constants.%F.f50] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %HasF.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -105,7 +105,6 @@ fn G(c: C) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(@HasF.%Self: %HasF.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -117,11 +116,11 @@ fn G(c: C) {
 // CHECK:STDOUT: fn @G(%c.param_patt: %C) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %C.ref.loc22: type = name_ref C, file.%C.decl [template = constants.%C]
-// CHECK:STDOUT:   %F.ref.loc22: %F.assoc_type = name_ref F, @HasF.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:   %F.ref.loc22: %HasF.assoc_type = name_ref F, @HasF.%assoc0 [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0.loc22: %F.type.b7b = impl_witness_access constants.%impl_witness, element0 [template = constants.%F.ad8]
 // CHECK:STDOUT:   %F.call.loc22: init %empty_tuple.type = call %impl.elem0.loc22()
 // CHECK:STDOUT:   %c.ref: %C = name_ref c, %c
-// CHECK:STDOUT:   %F.ref.loc23: %F.assoc_type = name_ref F, @HasF.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:   %F.ref.loc23: %HasF.assoc_type = name_ref F, @HasF.%assoc0 [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0.loc23: %F.type.b7b = impl_witness_access constants.%impl_witness, element0 [template = constants.%F.ad8]
 // CHECK:STDOUT:   %F.call.loc23: init %empty_tuple.type = call %impl.elem0.loc23()
 // CHECK:STDOUT:   return

+ 22 - 22
toolchain/check/testdata/impl/extend_impl_generic.carbon

@@ -58,8 +58,8 @@ class X(U:! type) {
 // CHECK:STDOUT:   %Self.322: %HasF.type.901 = bind_symbolic_name Self, 1 [symbolic]
 // CHECK:STDOUT:   %F.type.46c: type = fn_type @F.1, @HasF(%T) [symbolic]
 // CHECK:STDOUT:   %F.823: %F.type.46c = struct_value () [symbolic]
-// CHECK:STDOUT:   %F.assoc_type.a8c: type = assoc_entity_type %HasF.type.901, %F.type.46c [symbolic]
-// CHECK:STDOUT:   %assoc0.c51: %F.assoc_type.a8c = assoc_entity element0, @HasF.%F.decl [symbolic]
+// CHECK:STDOUT:   %HasF.assoc_type.595: type = assoc_entity_type %HasF.type.901 [symbolic]
+// CHECK:STDOUT:   %assoc0.35e: %HasF.assoc_type.595 = assoc_entity element0, @HasF.%F.decl [symbolic]
 // CHECK:STDOUT:   %Param: type = class_type @Param [template]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [template]
@@ -70,8 +70,8 @@ class X(U:! type) {
 // CHECK:STDOUT:   %HasF.type.b18: type = facet_type <@HasF, @HasF(%Param)> [template]
 // CHECK:STDOUT:   %F.type.7f1: type = fn_type @F.1, @HasF(%Param) [template]
 // CHECK:STDOUT:   %F.eff: %F.type.7f1 = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type.b26: type = assoc_entity_type %HasF.type.b18, %F.type.7f1 [template]
-// CHECK:STDOUT:   %assoc0.501: %F.assoc_type.b26 = assoc_entity element0, @HasF.%F.decl [template]
+// CHECK:STDOUT:   %HasF.assoc_type.dc4: type = assoc_entity_type %HasF.type.b18 [template]
+// CHECK:STDOUT:   %assoc0.a6b: %HasF.assoc_type.dc4 = assoc_entity element0, @HasF.%F.decl [template]
 // CHECK:STDOUT:   %impl_witness.9bf: <witness> = impl_witness (@impl.1.%F.decl) [template]
 // CHECK:STDOUT:   %F.type.94c: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.901: %F.type.94c = struct_value () [template]
@@ -138,8 +138,8 @@ class X(U:! type) {
 // CHECK:STDOUT:   %Self.2: %HasF.type.901 = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self.322)]
 // CHECK:STDOUT:   %F.type: type = fn_type @F.1, @HasF(%T.loc4_16.2) [symbolic = %F.type (constants.%F.type.46c)]
 // CHECK:STDOUT:   %F: @HasF.%F.type (%F.type.46c) = struct_value () [symbolic = %F (constants.%F.823)]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type @HasF.%HasF.type (%HasF.type.901), @HasF.%F.type (%F.type.46c) [symbolic = %F.assoc_type (constants.%F.assoc_type.a8c)]
-// CHECK:STDOUT:   %assoc0.loc5_14.2: @HasF.%F.assoc_type (%F.assoc_type.a8c) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc5_14.2 (constants.%assoc0.c51)]
+// CHECK:STDOUT:   %HasF.assoc_type: type = assoc_entity_type @HasF.%HasF.type (%HasF.type.901) [symbolic = %HasF.assoc_type (constants.%HasF.assoc_type.595)]
+// CHECK:STDOUT:   %assoc0.loc5_14.2: @HasF.%HasF.assoc_type (%HasF.assoc_type.595) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc5_14.2 (constants.%assoc0.35e)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:     %Self.1: @HasF.%HasF.type (%HasF.type.901) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self.322)]
@@ -151,7 +151,7 @@ class X(U:! type) {
 // CHECK:STDOUT:       %return.param: ref @F.1.%T (%T) = out_param runtime_param0
 // CHECK:STDOUT:       %return: ref @F.1.%T (%T) = return_slot %return.param
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %assoc0.loc5_14.1: @HasF.%F.assoc_type (%F.assoc_type.a8c) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc5_14.2 (constants.%assoc0.c51)]
+// CHECK:STDOUT:     %assoc0.loc5_14.1: @HasF.%HasF.assoc_type (%HasF.assoc_type.595) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc5_14.2 (constants.%assoc0.35e)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = %Self.1
@@ -233,8 +233,8 @@ class X(U:! type) {
 // CHECK:STDOUT:     %a.patt: %i32 = binding_pattern a
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %C.ref.loc21: type = name_ref C, file.%C.decl [template = constants.%C]
-// CHECK:STDOUT:   %.loc21_17: %F.assoc_type.b26 = specific_constant @HasF.%assoc0.loc5_14.1, @HasF(constants.%Param) [template = constants.%assoc0.501]
-// CHECK:STDOUT:   %F.ref.loc21: %F.assoc_type.b26 = name_ref F, %.loc21_17 [template = constants.%assoc0.501]
+// CHECK:STDOUT:   %.loc21_17: %HasF.assoc_type.dc4 = specific_constant @HasF.%assoc0.loc5_14.1, @HasF(constants.%Param) [template = constants.%assoc0.a6b]
+// CHECK:STDOUT:   %F.ref.loc21: %HasF.assoc_type.dc4 = name_ref F, %.loc21_17 [template = constants.%assoc0.a6b]
 // CHECK:STDOUT:   %impl.elem0.loc21: %F.type.7f1 = impl_witness_access constants.%impl_witness.9bf, element0 [template = constants.%F.901]
 // CHECK:STDOUT:   %.loc21_20.1: ref %Param = temporary_storage
 // CHECK:STDOUT:   %F.call.loc21: init %Param = call %impl.elem0.loc21() to %.loc21_20.1
@@ -252,8 +252,8 @@ class X(U:! type) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %b.var: ref %i32 = var b
 // CHECK:STDOUT:   %c.ref: %C = name_ref c, %c
-// CHECK:STDOUT:   %.loc22_17: %F.assoc_type.b26 = specific_constant @HasF.%assoc0.loc5_14.1, @HasF(constants.%Param) [template = constants.%assoc0.501]
-// CHECK:STDOUT:   %F.ref.loc22: %F.assoc_type.b26 = name_ref F, %.loc22_17 [template = constants.%assoc0.501]
+// CHECK:STDOUT:   %.loc22_17: %HasF.assoc_type.dc4 = specific_constant @HasF.%assoc0.loc5_14.1, @HasF(constants.%Param) [template = constants.%assoc0.a6b]
+// CHECK:STDOUT:   %F.ref.loc22: %HasF.assoc_type.dc4 = name_ref F, %.loc22_17 [template = constants.%assoc0.a6b]
 // CHECK:STDOUT:   %impl.elem0.loc22: %F.type.7f1 = impl_witness_access constants.%impl_witness.9bf, element0 [template = constants.%F.901]
 // CHECK:STDOUT:   %.loc22_20.1: ref %Param = temporary_storage
 // CHECK:STDOUT:   %F.call.loc22: init %Param = call %impl.elem0.loc22() to %.loc22_20.1
@@ -290,8 +290,8 @@ class X(U:! type) {
 // CHECK:STDOUT:   %Self.2 => constants.%Self.322
 // CHECK:STDOUT:   %F.type => constants.%F.type.7f1
 // CHECK:STDOUT:   %F => constants.%F.eff
-// CHECK:STDOUT:   %F.assoc_type => constants.%F.assoc_type.b26
-// CHECK:STDOUT:   %assoc0.loc5_14.2 => constants.%assoc0.501
+// CHECK:STDOUT:   %HasF.assoc_type => constants.%HasF.assoc_type.dc4
+// CHECK:STDOUT:   %assoc0.loc5_14.2 => constants.%assoc0.a6b
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F.1(constants.%Param, constants.%HasF.facet) {
@@ -310,8 +310,8 @@ class X(U:! type) {
 // CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic]
 // CHECK:STDOUT:   %F.type.2aef59.1: type = fn_type @F.1, @I(%T) [symbolic]
 // CHECK:STDOUT:   %F.bb2dd4.1: %F.type.2aef59.1 = struct_value () [symbolic]
-// CHECK:STDOUT:   %F.assoc_type.003a5c.1: type = assoc_entity_type %I.type.325e65.1, %F.type.2aef59.1 [symbolic]
-// CHECK:STDOUT:   %assoc0.819972.1: %F.assoc_type.003a5c.1 = assoc_entity element0, @I.%F.decl [symbolic]
+// CHECK:STDOUT:   %I.assoc_type.955255.1: type = assoc_entity_type %I.type.325e65.1 [symbolic]
+// CHECK:STDOUT:   %assoc0.fef501.1: %I.assoc_type.955255.1 = assoc_entity element0, @I.%F.decl [symbolic]
 // CHECK:STDOUT:   %U: type = bind_symbolic_name U, 0 [symbolic]
 // CHECK:STDOUT:   %U.patt: type = symbolic_binding_pattern U, 0 [symbolic]
 // CHECK:STDOUT:   %X.type: type = generic_class_type @X [template]
@@ -321,8 +321,8 @@ class X(U:! type) {
 // CHECK:STDOUT:   %require_complete.cfe: <witness> = require_complete_type %I.type.325e65.2 [symbolic]
 // CHECK:STDOUT:   %F.type.2aef59.2: type = fn_type @F.1, @I(%U) [symbolic]
 // CHECK:STDOUT:   %F.bb2dd4.2: %F.type.2aef59.2 = struct_value () [symbolic]
-// CHECK:STDOUT:   %F.assoc_type.003a5c.2: type = assoc_entity_type %I.type.325e65.2, %F.type.2aef59.2 [symbolic]
-// CHECK:STDOUT:   %assoc0.819972.2: %F.assoc_type.003a5c.2 = assoc_entity element0, @I.%F.decl [symbolic]
+// CHECK:STDOUT:   %I.assoc_type.955255.2: type = assoc_entity_type %I.type.325e65.2 [symbolic]
+// CHECK:STDOUT:   %assoc0.fef501.2: %I.assoc_type.955255.2 = assoc_entity element0, @I.%F.decl [symbolic]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (@impl.%F.decl), @impl(%U) [symbolic]
 // CHECK:STDOUT:   %F.type.e88: type = fn_type @F.2, @impl(%U) [symbolic]
 // CHECK:STDOUT:   %F.b02: %F.type.e88 = struct_value () [symbolic]
@@ -372,8 +372,8 @@ class X(U:! type) {
 // CHECK:STDOUT:   %Self.2: %I.type.325e65.1 = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
 // CHECK:STDOUT:   %F.type: type = fn_type @F.1, @I(%T.loc4_13.2) [symbolic = %F.type (constants.%F.type.2aef59.1)]
 // CHECK:STDOUT:   %F: @I.%F.type (%F.type.2aef59.1) = struct_value () [symbolic = %F (constants.%F.bb2dd4.1)]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type @I.%I.type (%I.type.325e65.1), @I.%F.type (%F.type.2aef59.1) [symbolic = %F.assoc_type (constants.%F.assoc_type.003a5c.1)]
-// CHECK:STDOUT:   %assoc0.loc5_25.2: @I.%F.assoc_type (%F.assoc_type.003a5c.1) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc5_25.2 (constants.%assoc0.819972.1)]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type @I.%I.type (%I.type.325e65.1) [symbolic = %I.assoc_type (constants.%I.assoc_type.955255.1)]
+// CHECK:STDOUT:   %assoc0.loc5_25.2: @I.%I.assoc_type (%I.assoc_type.955255.1) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc5_25.2 (constants.%assoc0.fef501.1)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:     %Self.1: @I.%I.type (%I.type.325e65.1) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
@@ -395,7 +395,7 @@ class X(U:! type) {
 // CHECK:STDOUT:       %T.ref: type = name_ref T, @I.%T.loc4_13.1 [symbolic = %T (constants.%T)]
 // CHECK:STDOUT:       %t: @F.1.%T (%T) = bind_name t, %t.param
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %assoc0.loc5_25.1: @I.%F.assoc_type (%F.assoc_type.003a5c.1) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc5_25.2 (constants.%assoc0.819972.1)]
+// CHECK:STDOUT:     %assoc0.loc5_25.1: @I.%I.assoc_type (%I.assoc_type.955255.1) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc5_25.2 (constants.%assoc0.fef501.1)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = %Self.1
@@ -522,8 +522,8 @@ class X(U:! type) {
 // CHECK:STDOUT:   %Self.2 => constants.%Self
 // CHECK:STDOUT:   %F.type => constants.%F.type.2aef59.2
 // CHECK:STDOUT:   %F => constants.%F.bb2dd4.2
-// CHECK:STDOUT:   %F.assoc_type => constants.%F.assoc_type.003a5c.2
-// CHECK:STDOUT:   %assoc0.loc5_25.2 => constants.%assoc0.819972.2
+// CHECK:STDOUT:   %I.assoc_type => constants.%I.assoc_type.955255.2
+// CHECK:STDOUT:   %assoc0.loc5_25.2 => constants.%assoc0.fef501.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl(constants.%U) {

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

@@ -32,8 +32,8 @@ fn InstanceCall(n: i32) {
 // CHECK:STDOUT:   %Self.as_type.716: type = facet_access_type %Self.3c9 [symbolic]
 // CHECK:STDOUT:   %G.type.b60: type = fn_type @G.1 [template]
 // CHECK:STDOUT:   %G.cb0: %G.type.b60 = struct_value () [template]
-// CHECK:STDOUT:   %G.assoc_type: type = assoc_entity_type %Simple.type, %G.type.b60 [template]
-// CHECK:STDOUT:   %assoc0.f1b: %G.assoc_type = assoc_entity element0, @Simple.%G.decl [template]
+// CHECK:STDOUT:   %Simple.assoc_type: type = assoc_entity_type %Simple.type [template]
+// CHECK:STDOUT:   %assoc0.45f: %Simple.assoc_type = assoc_entity element0, @Simple.%G.decl [template]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [template]
 // CHECK:STDOUT:   %impl_witness.85b: <witness> = impl_witness (<error>) [template]
@@ -93,7 +93,7 @@ fn InstanceCall(n: i32) {
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %self: @G.1.%Self.as_type.loc12_14.1 (%Self.as_type.716) = bind_name self, %self.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc0: %G.assoc_type = assoc_entity element0, %G.decl [template = constants.%assoc0.f1b]
+// CHECK:STDOUT:   %assoc0: %Simple.assoc_type = assoc_entity element0, %G.decl [template = constants.%assoc0.45f]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -129,7 +129,7 @@ fn InstanceCall(n: i32) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %n.ref: %i32 = name_ref n, %n
 // CHECK:STDOUT:   %Simple.ref: type = name_ref Simple, file.%Simple.decl [template = constants.%Simple.type]
-// CHECK:STDOUT:   %G.ref: %G.assoc_type = name_ref G, @Simple.%assoc0 [template = constants.%assoc0.f1b]
+// CHECK:STDOUT:   %G.ref: %Simple.assoc_type = name_ref G, @Simple.%assoc0 [template = constants.%assoc0.45f]
 // CHECK:STDOUT:   %impl.elem0: %G.type.b60 = impl_witness_access constants.%impl_witness.85b, element0 [template = <error>]
 // CHECK:STDOUT:   %G.bound: <bound method> = bound_method %n.ref, %impl.elem0
 // CHECK:STDOUT:   return

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

@@ -33,8 +33,8 @@ class C {
 // CHECK:STDOUT:   %Self: %GenericInterface.type.3fe = bind_symbolic_name Self, 1 [symbolic]
 // CHECK:STDOUT:   %F.type.a4b: type = fn_type @F.1, @GenericInterface(%T) [symbolic]
 // CHECK:STDOUT:   %F.3d9: %F.type.a4b = struct_value () [symbolic]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %GenericInterface.type.3fe, %F.type.a4b [symbolic]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @GenericInterface.%F.decl [symbolic]
+// CHECK:STDOUT:   %GenericInterface.assoc_type: type = assoc_entity_type %GenericInterface.type.3fe [symbolic]
+// CHECK:STDOUT:   %assoc0: %GenericInterface.assoc_type = assoc_entity element0, @GenericInterface.%F.decl [symbolic]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %require_complete.70f: <witness> = require_complete_type %GenericInterface.type.3fe [symbolic]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (@impl.%F.decl), @impl(%T) [symbolic]
@@ -79,8 +79,8 @@ class C {
 // CHECK:STDOUT:   %Self.2: %GenericInterface.type.3fe = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
 // CHECK:STDOUT:   %F.type: type = fn_type @F.1, @GenericInterface(%T.loc11_28.2) [symbolic = %F.type (constants.%F.type.a4b)]
 // CHECK:STDOUT:   %F: @GenericInterface.%F.type (%F.type.a4b) = struct_value () [symbolic = %F (constants.%F.3d9)]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type @GenericInterface.%GenericInterface.type (%GenericInterface.type.3fe), @GenericInterface.%F.type (%F.type.a4b) [symbolic = %F.assoc_type (constants.%F.assoc_type)]
-// CHECK:STDOUT:   %assoc0.loc12_13.2: @GenericInterface.%F.assoc_type (%F.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc12_13.2 (constants.%assoc0)]
+// CHECK:STDOUT:   %GenericInterface.assoc_type: type = assoc_entity_type @GenericInterface.%GenericInterface.type (%GenericInterface.type.3fe) [symbolic = %GenericInterface.assoc_type (constants.%GenericInterface.assoc_type)]
+// CHECK:STDOUT:   %assoc0.loc12_13.2: @GenericInterface.%GenericInterface.assoc_type (%GenericInterface.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc12_13.2 (constants.%assoc0)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:     %Self.1: @GenericInterface.%GenericInterface.type (%GenericInterface.type.3fe) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
@@ -92,7 +92,7 @@ class C {
 // CHECK:STDOUT:       %T.ref: type = name_ref T, @GenericInterface.%T.loc11_28.1 [symbolic = %T (constants.%T)]
 // CHECK:STDOUT:       %x: @F.1.%T (%T) = bind_name x, %x.param
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %assoc0.loc12_13.1: @GenericInterface.%F.assoc_type (%F.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc12_13.2 (constants.%assoc0)]
+// CHECK:STDOUT:     %assoc0.loc12_13.1: @GenericInterface.%GenericInterface.assoc_type (%GenericInterface.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc12_13.2 (constants.%assoc0)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = %Self.1
@@ -177,7 +177,7 @@ class C {
 // CHECK:STDOUT:   %Self.2 => constants.%Self
 // CHECK:STDOUT:   %F.type => constants.%F.type.a4b
 // CHECK:STDOUT:   %F => constants.%F.3d9
-// CHECK:STDOUT:   %F.assoc_type => constants.%F.assoc_type
+// CHECK:STDOUT:   %GenericInterface.assoc_type => constants.%GenericInterface.assoc_type
 // CHECK:STDOUT:   %assoc0.loc12_13.2 => constants.%assoc0
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 6 - 8
toolchain/check/testdata/impl/fail_impl_as_scope.carbon

@@ -49,8 +49,8 @@ fn Function() {
 // CHECK:STDOUT:   %Self: %Simple.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %Simple.type, %F.type [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @Simple.%F.decl [template]
+// CHECK:STDOUT:   %Simple.assoc_type: type = assoc_entity_type %Simple.type [template]
+// CHECK:STDOUT:   %assoc0: %Simple.assoc_type = assoc_entity element0, @Simple.%F.decl [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {}
@@ -58,7 +58,7 @@ fn Function() {
 // CHECK:STDOUT: interface @Simple {
 // CHECK:STDOUT:   %Self: %Simple.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %Simple.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -67,7 +67,6 @@ fn Function() {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(@Simple.%Self: %Simple.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -80,8 +79,8 @@ fn Function() {
 // CHECK:STDOUT:   %Self: %Simple.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %Simple.type, %F.type [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @Simple.%F.decl [template]
+// CHECK:STDOUT:   %Simple.assoc_type: type = assoc_entity_type %Simple.type [template]
+// CHECK:STDOUT:   %assoc0: %Simple.assoc_type = assoc_entity element0, @Simple.%F.decl [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {}
@@ -89,7 +88,7 @@ fn Function() {
 // CHECK:STDOUT: interface @Simple {
 // CHECK:STDOUT:   %Self: %Simple.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %Simple.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -98,7 +97,6 @@ fn Function() {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(@Simple.%Self: %Simple.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 9 - 11
toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon

@@ -221,8 +221,8 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT:   %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %F.type.cf0: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.bc6: %F.type.cf0 = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type.ae7: type = assoc_entity_type %I.type, %F.type.cf0 [template]
-// CHECK:STDOUT:   %assoc0.fa7: %F.assoc_type.ae7 = assoc_entity element0, @I.%F.decl [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0.a5e: %I.assoc_type = assoc_entity element0, @I.%F.decl [template]
 // CHECK:STDOUT:   %NoF: type = class_type @NoF [template]
 // CHECK:STDOUT:   %impl_witness.85bcb7.1: <witness> = impl_witness (<error>) [template]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
@@ -255,8 +255,8 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT:   %Self.ccd: %J.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %F.type.c14: type = fn_type @F.5 [template]
 // CHECK:STDOUT:   %F.b71: %F.type.c14 = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type.a73: type = assoc_entity_type %J.type, %F.type.c14 [template]
-// CHECK:STDOUT:   %assoc0.93f: %F.assoc_type.a73 = assoc_entity element0, @J.%F.decl [template]
+// CHECK:STDOUT:   %J.assoc_type: type = assoc_entity_type %J.type [template]
+// CHECK:STDOUT:   %assoc0.ebc: %J.assoc_type = assoc_entity element0, @J.%F.decl [template]
 // CHECK:STDOUT:   %FMissingParam: type = class_type @FMissingParam [template]
 // CHECK:STDOUT:   %impl_witness.85bcb7.7: <witness> = impl_witness (<error>) [template]
 // CHECK:STDOUT:   %F.type.695: type = fn_type @F.6 [template]
@@ -305,8 +305,8 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT:   %array_type.873: type = array_type %int_4, %Self.as_type [symbolic]
 // CHECK:STDOUT:   %F.type.6ed: type = fn_type @F.13 [template]
 // CHECK:STDOUT:   %F.998: %F.type.6ed = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type.4b1: type = assoc_entity_type %SelfNested.type, %F.type.6ed [template]
-// CHECK:STDOUT:   %assoc0.7e7: %F.assoc_type.4b1 = assoc_entity element0, @SelfNested.%F.decl [template]
+// CHECK:STDOUT:   %SelfNested.assoc_type: type = assoc_entity_type %SelfNested.type [template]
+// CHECK:STDOUT:   %assoc0.a58: %SelfNested.assoc_type = assoc_entity element0, @SelfNested.%F.decl [template]
 // CHECK:STDOUT:   %SelfNestedBadParam: type = class_type @SelfNestedBadParam [template]
 // CHECK:STDOUT:   %impl_witness.85bcb7.14: <witness> = impl_witness (<error>) [template]
 // CHECK:STDOUT:   %ptr.4cd: type = ptr_type %SelfNestedBadParam [template]
@@ -386,7 +386,7 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826]
 // CHECK:STDOUT:   %F.decl: %F.type.cf0 = fn_decl @F.1 [template = constants.%F.bc6] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type.ae7 = assoc_entity element0, %F.decl [template = constants.%assoc0.fa7]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0.a5e]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -424,7 +424,7 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT:     %return.param: ref bool = out_param runtime_param2
 // CHECK:STDOUT:     %return: ref bool = return_slot %return.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc0: %F.assoc_type.a73 = assoc_entity element0, %F.decl [template = constants.%assoc0.93f]
+// CHECK:STDOUT:   %assoc0: %J.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0.ebc]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -464,7 +464,7 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT:     %return.param: ref @F.13.%array_type.loc188_52.1 (%array_type.873) = out_param runtime_param1
 // CHECK:STDOUT:     %return: ref @F.13.%array_type.loc188_52.1 (%array_type.873) = return_slot %return.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc0: %F.assoc_type.4b1 = assoc_entity element0, %F.decl [template = constants.%assoc0.7e7]
+// CHECK:STDOUT:   %assoc0: %SelfNested.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0.a58]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -1016,7 +1016,6 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(@I.%Self: %I.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -1029,7 +1028,6 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT: fn @F.4() -> bool;
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.5(@J.%Self: %J.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn[%self.param_patt: bool](%b.param_patt: bool) -> bool;
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

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

@@ -42,8 +42,8 @@ impl i32 as I {
 // CHECK:STDOUT:   %C.dbb: type = class_type @C, @C(%I.type, %Self) [symbolic]
 // CHECK:STDOUT:   %F.type.cf0: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.bc6: %F.type.cf0 = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %I.type, %F.type.cf0 [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @I.%F.decl [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @I.%F.decl [template]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (<error>) [template]
@@ -104,7 +104,7 @@ impl i32 as I {
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %c: @F.1.%C.loc14_17.1 (%C.dbb) = bind_name c, %c.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self

+ 82 - 45
toolchain/check/testdata/impl/fail_todo_use_assoc_const.carbon

@@ -13,17 +13,17 @@ library "[[@TEST_NAME]]";
 
 interface J {
   let U:! type;
-  // CHECK:STDERR: fail_todo_associated_type_in_signature.carbon:[[@LINE+14]]:23: error: cannot implicitly convert from `<associated type in J>` to `type` [ImplicitAsConversionFailure]
+  // CHECK:STDERR: fail_todo_associated_type_in_signature.carbon:[[@LINE+14]]:23: error: cannot implicitly convert from `<associated entity in J>` to `type` [ImplicitAsConversionFailure]
   // CHECK:STDERR:   fn F[self: Self](u: U) -> U;
   // CHECK:STDERR:                       ^
-  // CHECK:STDERR: fail_todo_associated_type_in_signature.carbon:[[@LINE+11]]:23: note: type `<associated type in J>` does not implement interface `Core.ImplicitAs(type)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR: fail_todo_associated_type_in_signature.carbon:[[@LINE+11]]:23: note: type `<associated entity in J>` does not implement interface `Core.ImplicitAs(type)` [MissingImplInMemberAccessNote]
   // CHECK:STDERR:   fn F[self: Self](u: U) -> U;
   // CHECK:STDERR:                       ^
   // CHECK:STDERR:
-  // CHECK:STDERR: fail_todo_associated_type_in_signature.carbon:[[@LINE+7]]:29: error: cannot implicitly convert from `<associated type in J>` to `type` [ImplicitAsConversionFailure]
+  // CHECK:STDERR: fail_todo_associated_type_in_signature.carbon:[[@LINE+7]]:29: error: cannot implicitly convert from `<associated entity in J>` to `type` [ImplicitAsConversionFailure]
   // CHECK:STDERR:   fn F[self: Self](u: U) -> U;
   // CHECK:STDERR:                             ^
-  // CHECK:STDERR: fail_todo_associated_type_in_signature.carbon:[[@LINE+4]]:29: note: type `<associated type in J>` does not implement interface `Core.ImplicitAs(type)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR: fail_todo_associated_type_in_signature.carbon:[[@LINE+4]]:29: note: type `<associated entity in J>` does not implement interface `Core.ImplicitAs(type)` [MissingImplInMemberAccessNote]
   // CHECK:STDERR:   fn F[self: Self](u: U) -> U;
   // CHECK:STDERR:                             ^
   // CHECK:STDERR:
@@ -69,10 +69,10 @@ library "[[@TEST_NAME]]";
 
 interface I {
   let N:! i32;
-  // CHECK:STDERR: fail_todo_associated_int_in_array.carbon:[[@LINE+7]]:32: error: cannot implicitly convert from `<associated i32 in I>` to `Core.IntLiteral` [ImplicitAsConversionFailure]
+  // CHECK:STDERR: fail_todo_associated_int_in_array.carbon:[[@LINE+7]]:32: error: cannot implicitly convert from `<associated entity in I>` to `Core.IntLiteral` [ImplicitAsConversionFailure]
   // CHECK:STDERR:   fn F[self: Self]() -> [bool; N];
   // CHECK:STDERR:                                ^
-  // CHECK:STDERR: fail_todo_associated_int_in_array.carbon:[[@LINE+4]]:32: note: type `<associated i32 in I>` does not implement interface `Core.ImplicitAs(Core.IntLiteral)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR: fail_todo_associated_int_in_array.carbon:[[@LINE+4]]:32: note: type `<associated entity in I>` does not implement interface `Core.ImplicitAs(Core.IntLiteral)` [MissingImplInMemberAccessNote]
   // CHECK:STDERR:   fn F[self: Self]() -> [bool; N];
   // CHECK:STDERR:                                ^
   // CHECK:STDERR:
@@ -88,16 +88,17 @@ impl () as I where .N = 2 {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %J.type: type = facet_type <@J> [template]
 // CHECK:STDOUT:   %Self.ccd: %J.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %J.type, type [template]
-// CHECK:STDOUT:   %assoc0.021: %assoc_type = assoc_entity element0, @J.%U [template]
+// CHECK:STDOUT:   %J.assoc_type: type = assoc_entity_type %J.type [template]
+// CHECK:STDOUT:   %assoc0.1e6: %J.assoc_type = assoc_entity element0, @J.%U [template]
 // CHECK:STDOUT:   %Self.as_type.3df: type = facet_access_type %Self.ccd [symbolic]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.type.c14: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.b71: %F.type.c14 = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %J.type, %F.type.c14 [template]
-// CHECK:STDOUT:   %assoc1: %F.assoc_type = assoc_entity element1, @J.%F.decl [template]
+// CHECK:STDOUT:   %assoc1: %J.assoc_type = assoc_entity element1, @J.%F.decl [template]
 // CHECK:STDOUT:   %.Self: %J.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %J.facet.ad0: %J.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %J_where.type.800: type = facet_type <@J where %impl.elem0 = %empty_struct_type> [template]
@@ -136,7 +137,9 @@ impl () as I where .N = 2 {
 // CHECK:STDOUT:     %J.ref: type = name_ref J, file.%J.decl [template = constants.%J.type]
 // CHECK:STDOUT:     %.Self: %J.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:     %.Self.ref: %J.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %U.ref: %assoc_type = name_ref U, @J.%assoc0 [template = constants.%assoc0.021]
+// CHECK:STDOUT:     %U.ref: %J.assoc_type = name_ref U, @U.%assoc0 [template = constants.%assoc0.1e6]
+// CHECK:STDOUT:     %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc22_20: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %.loc22_26.1: %empty_struct_type = struct_literal ()
@@ -152,11 +155,13 @@ impl () as I where .N = 2 {
 // CHECK:STDOUT:     %J.ref: type = name_ref J, file.%J.decl [template = constants.%J.type]
 // CHECK:STDOUT:     %.Self: %J.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:     %.Self.ref: %J.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %U.ref: %assoc_type = name_ref U, @J.%assoc0 [template = constants.%assoc0.021]
+// CHECK:STDOUT:     %U.ref: %J.assoc_type = name_ref U, @U.%assoc0 [template = constants.%assoc0.1e6]
+// CHECK:STDOUT:     %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc31_19: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %C.ref.loc31_24: type = name_ref C, file.%C.decl [template = constants.%C]
-// CHECK:STDOUT:     %.loc31: type = where_expr %.Self [template = constants.%J_where.type.2f6] {
+// CHECK:STDOUT:     %.loc31_13: type = where_expr %.Self [template = constants.%J_where.type.2f6] {
 // CHECK:STDOUT:       requirement_rewrite %impl.elem0, %C.ref.loc31_24
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:   }
@@ -165,8 +170,9 @@ impl () as I where .N = 2 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @J {
 // CHECK:STDOUT:   %Self: %J.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.ccd]
-// CHECK:STDOUT:   %U: type = assoc_const_decl U [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %U [template = constants.%assoc0.021]
+// CHECK:STDOUT:   %U: type = assoc_const_decl @U [template] {
+// CHECK:STDOUT:     %assoc0: %J.assoc_type = assoc_entity element0, @J.%U [template = constants.%assoc0.1e6]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type.c14 = fn_decl @F.1 [template = constants.%F.b71] {
 // CHECK:STDOUT:     %self.patt: @F.1.%Self.as_type.loc19_14.1 (%Self.as_type.3df) = binding_pattern self
 // CHECK:STDOUT:     %self.param_patt: @F.1.%Self.as_type.loc19_14.1 (%Self.as_type.3df) = value_param_pattern %self.patt, runtime_param0
@@ -175,7 +181,7 @@ impl () as I where .N = 2 {
 // CHECK:STDOUT:     %return.patt: <error> = return_slot_pattern
 // CHECK:STDOUT:     %return.param_patt: <error> = out_param_pattern %return.patt, runtime_param2
 // CHECK:STDOUT:   } {
-// CHECK:STDOUT:     %U.ref.loc19_29: %assoc_type = name_ref U, @J.%assoc0 [template = constants.%assoc0.021]
+// CHECK:STDOUT:     %U.ref.loc19_29: %J.assoc_type = name_ref U, @U.%assoc0 [template = constants.%assoc0.1e6]
 // CHECK:STDOUT:     %.loc19_29: type = converted %U.ref.loc19_29, <error> [template = <error>]
 // CHECK:STDOUT:     %self.param: @F.1.%Self.as_type.loc19_14.1 (%Self.as_type.3df) = value_param runtime_param0
 // CHECK:STDOUT:     %.loc19_14.1: type = splice_block %.loc19_14.2 [symbolic = %Self.as_type.loc19_14.1 (constants.%Self.as_type.3df)] {
@@ -186,22 +192,26 @@ impl () as I where .N = 2 {
 // CHECK:STDOUT:     %self: @F.1.%Self.as_type.loc19_14.1 (%Self.as_type.3df) = bind_name self, %self.param
 // CHECK:STDOUT:     %u.param: <error> = value_param runtime_param1
 // CHECK:STDOUT:     %.1: <error> = splice_block <error> [template = <error>] {
-// CHECK:STDOUT:       %U.ref.loc19_23: %assoc_type = name_ref U, @J.%assoc0 [template = constants.%assoc0.021]
+// CHECK:STDOUT:       %U.ref.loc19_23: %J.assoc_type = name_ref U, @U.%assoc0 [template = constants.%assoc0.1e6]
 // CHECK:STDOUT:       %.loc19_23: type = converted %U.ref.loc19_23, <error> [template = <error>]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %u: <error> = bind_name u, %u.param
 // CHECK:STDOUT:     %return.param: ref <error> = out_param runtime_param2
 // CHECK:STDOUT:     %return: ref <error> = return_slot %return.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc1: %F.assoc_type = assoc_entity element1, %F.decl [template = constants.%assoc1]
+// CHECK:STDOUT:   %assoc1: %J.assoc_type = assoc_entity element1, %F.decl [template = constants.%assoc1]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .U = %assoc0
+// CHECK:STDOUT:   .U = @U.%assoc0
 // CHECK:STDOUT:   .F = %assoc1
 // CHECK:STDOUT:   witness = (%U, %F.decl)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @U(@J.%Self: %J.type) {
+// CHECK:STDOUT:   assoc_const U:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl.1: %.loc22_7.2 as %.loc22_14 {
 // CHECK:STDOUT:   %F.decl: %F.type.159 = fn_decl @F.2 [template = constants.%F.59d] {
 // CHECK:STDOUT:     %self.patt: %empty_tuple.type = binding_pattern self
@@ -231,7 +241,7 @@ impl () as I where .N = 2 {
 // CHECK:STDOUT:   witness = file.%impl_witness.loc22
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: impl @impl.2: %C.ref.loc31_6 as %.loc31 {
+// CHECK:STDOUT: impl @impl.2: %C.ref.loc31_6 as %.loc31_13 {
 // CHECK:STDOUT:   %F.decl: %F.type.01a = fn_decl @F.3 [template = constants.%F.686] {
 // CHECK:STDOUT:     %self.patt: %C = binding_pattern self
 // CHECK:STDOUT:     %self.param_patt: %C = value_param_pattern %self.patt, runtime_param0
@@ -286,11 +296,15 @@ impl () as I where .N = 2 {
 // CHECK:STDOUT:   return %self.ref
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @U(constants.%Self.ccd) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @F.1(constants.%Self.ccd) {
 // CHECK:STDOUT:   %Self => constants.%Self.ccd
 // CHECK:STDOUT:   %Self.as_type.loc19_14.1 => constants.%Self.as_type.3df
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @U(constants.%J.facet.ad0) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @F.1(constants.%J.facet.550) {
 // CHECK:STDOUT:   %Self => constants.%J.facet.550
 // CHECK:STDOUT:   %Self.as_type.loc19_14.1 => constants.%empty_tuple.type
@@ -309,14 +323,15 @@ impl () as I where .N = 2 {
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %struct_type.b.347: type = struct_type {.b: %empty_struct_type} [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %M.type, %struct_type.b.347 [template]
-// CHECK:STDOUT:   %assoc0.fbc: %assoc_type = assoc_entity element0, @M.%Z [template]
+// CHECK:STDOUT:   %M.assoc_type: type = assoc_entity_type %M.type [template]
+// CHECK:STDOUT:   %assoc0.e3d: %M.assoc_type = assoc_entity element0, @M.%Z [template]
 // CHECK:STDOUT:   %G.type.020: type = fn_type @G.1 [template]
 // CHECK:STDOUT:   %G.91c: %G.type.020 = struct_value () [template]
-// CHECK:STDOUT:   %G.assoc_type: type = assoc_entity_type %M.type, %G.type.020 [template]
-// CHECK:STDOUT:   %assoc1: %G.assoc_type = assoc_entity element1, @M.%G.decl [template]
+// CHECK:STDOUT:   %assoc1: %M.assoc_type = assoc_entity element1, @M.%G.decl [template]
 // CHECK:STDOUT:   %.Self: %M.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %M.facet.ba5: %M.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: %struct_type.b.347 = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT:   %empty_struct: %empty_struct_type = struct_value () [template]
 // CHECK:STDOUT:   %struct: %struct_type.b.347 = struct_value (%empty_struct) [template]
@@ -324,7 +339,7 @@ impl () as I where .N = 2 {
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (%struct, @impl.%G.decl) [template]
 // CHECK:STDOUT:   %G.type.aa2: type = fn_type @G.2 [template]
 // CHECK:STDOUT:   %G.816: %G.type.aa2 = struct_value () [template]
-// CHECK:STDOUT:   %M.facet: %M.type = facet_value %empty_tuple.type, %impl_witness [template]
+// CHECK:STDOUT:   %M.facet.940: %M.type = facet_value %empty_tuple.type, %impl_witness [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -348,7 +363,9 @@ impl () as I where .N = 2 {
 // CHECK:STDOUT:     %M.ref: type = name_ref M, file.%M.decl [template = constants.%M.type]
 // CHECK:STDOUT:     %.Self: %M.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:     %.Self.ref: %M.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %Z.ref: %assoc_type = name_ref Z, @M.%assoc0 [template = constants.%assoc0.fbc]
+// CHECK:STDOUT:     %Z.ref: %M.assoc_type = name_ref Z, @Z.%assoc0 [template = constants.%assoc0.e3d]
+// CHECK:STDOUT:     %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc8_20: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0: %struct_type.b.347 = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %.loc8_32: %empty_struct_type = struct_literal ()
@@ -366,8 +383,9 @@ impl () as I where .N = 2 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @M {
 // CHECK:STDOUT:   %Self: %M.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.bcc]
-// CHECK:STDOUT:   %Z: %struct_type.b.347 = assoc_const_decl Z [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %Z [template = constants.%assoc0.fbc]
+// CHECK:STDOUT:   %Z: %struct_type.b.347 = assoc_const_decl @Z [template] {
+// CHECK:STDOUT:     %assoc0: %M.assoc_type = assoc_entity element0, @M.%Z [template = constants.%assoc0.e3d]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:   %G.decl: %G.type.020 = fn_decl @G.1 [template = constants.%G.91c] {
 // CHECK:STDOUT:     %return.patt: %empty_struct_type = return_slot_pattern
 // CHECK:STDOUT:     %return.param_patt: %empty_struct_type = out_param_pattern %return.patt, runtime_param0
@@ -377,15 +395,19 @@ impl () as I where .N = 2 {
 // CHECK:STDOUT:     %return.param: ref %empty_struct_type = out_param runtime_param0
 // CHECK:STDOUT:     %return: ref %empty_struct_type = return_slot %return.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc1: %G.assoc_type = assoc_entity element1, %G.decl [template = constants.%assoc1]
+// CHECK:STDOUT:   %assoc1: %M.assoc_type = assoc_entity element1, %G.decl [template = constants.%assoc1]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .Z = %assoc0
+// CHECK:STDOUT:   .Z = @Z.%assoc0
 // CHECK:STDOUT:   .G = %assoc1
 // CHECK:STDOUT:   witness = (%Z, %G.decl)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @Z(@M.%Self: %M.type) {
+// CHECK:STDOUT:   assoc_const Z:! %struct_type.b.347;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %.loc8_7.2 as %.loc8_14 {
 // CHECK:STDOUT:   %G.decl: %G.type.aa2 = fn_decl @G.2 [template = constants.%G.816] {
 // CHECK:STDOUT:     %return.patt: %empty_struct_type = return_slot_pattern
@@ -403,7 +425,6 @@ impl () as I where .N = 2 {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @G.1(@M.%Self: %M.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn() -> %empty_struct_type;
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -417,9 +438,13 @@ impl () as I where .N = 2 {
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @Z(constants.%Self.bcc) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @G.1(constants.%Self.bcc) {}
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @G.1(constants.%M.facet) {}
+// CHECK:STDOUT: specific @Z(constants.%M.facet.ba5) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @G.1(constants.%M.facet.940) {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_todo_associated_int_in_array.carbon
 // CHECK:STDOUT:
@@ -429,17 +454,18 @@ impl () as I where .N = 2 {
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [template]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %I.type, %i32 [template]
-// CHECK:STDOUT:   %assoc0.9f1: %assoc_type = assoc_entity element0, @I.%N [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0.73c: %I.assoc_type = assoc_entity element0, @I.%N [template]
 // CHECK:STDOUT:   %Self.as_type.b70: type = facet_access_type %Self.826 [symbolic]
 // CHECK:STDOUT:   %Bool.type: type = fn_type @Bool [template]
 // CHECK:STDOUT:   %Bool: %Bool.type = struct_value () [template]
 // CHECK:STDOUT:   %F.type.cf0: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.bc6: %F.type.cf0 = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %I.type, %F.type.cf0 [template]
-// CHECK:STDOUT:   %assoc1: %F.assoc_type = assoc_entity element1, @I.%F.decl [template]
+// CHECK:STDOUT:   %assoc1: %I.assoc_type = assoc_entity element1, @I.%F.decl [template]
 // CHECK:STDOUT:   %.Self: %I.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %I.facet.1f7: %I.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: %i32 = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT:   %int_2.ecc: Core.IntLiteral = int_value 2 [template]
 // CHECK:STDOUT:   %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [template]
@@ -454,7 +480,7 @@ impl () as I where .N = 2 {
 // CHECK:STDOUT:   %array_type: type = array_type %int_2.ecc, bool [template]
 // CHECK:STDOUT:   %F.type.9f6: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.572: %F.type.9f6 = struct_value () [template]
-// CHECK:STDOUT:   %I.facet: %I.type = facet_value %empty_tuple.type, %impl_witness.2c9 [template]
+// CHECK:STDOUT:   %I.facet.7b2: %I.type = facet_value %empty_tuple.type, %impl_witness.2c9 [template]
 // CHECK:STDOUT:   %true: bool = bool_literal true [template]
 // CHECK:STDOUT:   %false: bool = bool_literal false [template]
 // CHECK:STDOUT:   %tuple.type: type = tuple_type (bool, bool) [template]
@@ -486,7 +512,9 @@ impl () as I where .N = 2 {
 // CHECK:STDOUT:     %I.ref: type = name_ref I, file.%I.decl [template = constants.%I.type]
 // CHECK:STDOUT:     %.Self: %I.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:     %.Self.ref: %I.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %N.ref: %assoc_type = name_ref N, @I.%assoc0 [template = constants.%assoc0.9f1]
+// CHECK:STDOUT:     %N.ref: %I.assoc_type = name_ref N, @N.%assoc0 [template = constants.%assoc0.73c]
+// CHECK:STDOUT:     %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc15_20: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0.loc15_20: %i32 = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %int_2: Core.IntLiteral = int_value 2 [template = constants.%int_2.ecc]
@@ -505,8 +533,9 @@ impl () as I where .N = 2 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826]
-// CHECK:STDOUT:   %N: %i32 = assoc_const_decl N [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %N [template = constants.%assoc0.9f1]
+// CHECK:STDOUT:   %N: %i32 = assoc_const_decl @N [template] {
+// CHECK:STDOUT:     %assoc0: %I.assoc_type = assoc_entity element0, @I.%N [template = constants.%assoc0.73c]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type.cf0 = fn_decl @F.1 [template = constants.%F.bc6] {
 // CHECK:STDOUT:     %self.patt: @F.1.%Self.as_type.loc12_14.1 (%Self.as_type.b70) = binding_pattern self
 // CHECK:STDOUT:     %self.param_patt: @F.1.%Self.as_type.loc12_14.1 (%Self.as_type.b70) = value_param_pattern %self.patt, runtime_param0
@@ -514,7 +543,7 @@ impl () as I where .N = 2 {
 // CHECK:STDOUT:     %return.param_patt: <error> = out_param_pattern %return.patt, runtime_param1
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %bool.make_type: init type = call constants.%Bool() [template = bool]
-// CHECK:STDOUT:     %N.ref: %assoc_type = name_ref N, @I.%assoc0 [template = constants.%assoc0.9f1]
+// CHECK:STDOUT:     %N.ref: %I.assoc_type = name_ref N, @N.%assoc0 [template = constants.%assoc0.73c]
 // CHECK:STDOUT:     %.loc12_26.1: type = value_of_initializer %bool.make_type [template = bool]
 // CHECK:STDOUT:     %.loc12_26.2: type = converted %bool.make_type, %.loc12_26.1 [template = bool]
 // CHECK:STDOUT:     %.loc12_32: Core.IntLiteral = converted %N.ref, <error> [template = <error>]
@@ -529,15 +558,19 @@ impl () as I where .N = 2 {
 // CHECK:STDOUT:     %return.param: ref <error> = out_param runtime_param1
 // CHECK:STDOUT:     %return: ref <error> = return_slot %return.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc1: %F.assoc_type = assoc_entity element1, %F.decl [template = constants.%assoc1]
+// CHECK:STDOUT:   %assoc1: %I.assoc_type = assoc_entity element1, %F.decl [template = constants.%assoc1]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .N = %assoc0
+// CHECK:STDOUT:   .N = @N.%assoc0
 // CHECK:STDOUT:   .F = %assoc1
 // CHECK:STDOUT:   witness = (%N, %F.decl)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @N(@I.%Self: %I.type) {
+// CHECK:STDOUT:   assoc_const N:! %i32;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl.44: %.loc15_7.2 as %.loc15_14 {
 // CHECK:STDOUT:   %F.decl: %F.type.9f6 = fn_decl @F.2 [template = constants.%F.572] {
 // CHECK:STDOUT:     %self.patt: %empty_tuple.type = binding_pattern self
@@ -585,13 +618,17 @@ impl () as I where .N = 2 {
 // CHECK:STDOUT:   return %.loc16_57 to %return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @N(constants.%Self.826) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @F.1(constants.%Self.826) {
 // CHECK:STDOUT:   %Self => constants.%Self.826
 // CHECK:STDOUT:   %Self.as_type.loc12_14.1 => constants.%Self.as_type.b70
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @F.1(constants.%I.facet) {
-// CHECK:STDOUT:   %Self => constants.%I.facet
+// CHECK:STDOUT: specific @N(constants.%I.facet.1f7) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F.1(constants.%I.facet.7b2) {
+// CHECK:STDOUT:   %Self => constants.%I.facet.7b2
 // CHECK:STDOUT:   %Self.as_type.loc12_14.1 => constants.%empty_tuple.type
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 3 - 4
toolchain/check/testdata/impl/impl_as.carbon

@@ -28,8 +28,8 @@ class C {
 // CHECK:STDOUT:   %Self: %Simple.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %F.type.e2e: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.df8: %F.type.e2e = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %Simple.type, %F.type.e2e [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @Simple.%F.decl [template]
+// CHECK:STDOUT:   %Simple.assoc_type: type = assoc_entity_type %Simple.type [template]
+// CHECK:STDOUT:   %assoc0: %Simple.assoc_type = assoc_entity element0, @Simple.%F.decl [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (@impl.%F.decl) [template]
 // CHECK:STDOUT:   %F.type.e4b: type = fn_type @F.2 [template]
@@ -61,7 +61,7 @@ class C {
 // CHECK:STDOUT: interface @Simple {
 // CHECK:STDOUT:   %Self: %Simple.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type.e2e = fn_decl @F.1 [template = constants.%F.df8] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %Simple.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -91,7 +91,6 @@ class C {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(@Simple.%Self: %Simple.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 3 - 4
toolchain/check/testdata/impl/impl_forall.carbon

@@ -23,8 +23,8 @@ impl forall [T:! type] T as Simple {
 // CHECK:STDOUT:   %Self: %Simple.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %F.type.e2e: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.df8: %F.type.e2e = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %Simple.type, %F.type.e2e [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @Simple.%F.decl [template]
+// CHECK:STDOUT:   %Simple.assoc_type: type = assoc_entity_type %Simple.type [template]
+// CHECK:STDOUT:   %assoc0: %Simple.assoc_type = assoc_entity element0, @Simple.%F.decl [template]
 // CHECK:STDOUT:   %T: type = bind_symbolic_name T, 0 [symbolic]
 // CHECK:STDOUT:   %T.patt: type = symbolic_binding_pattern T, 0 [symbolic]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (@impl.%F.decl), @impl(%T) [symbolic]
@@ -62,7 +62,7 @@ impl forall [T:! type] T as Simple {
 // CHECK:STDOUT: interface @Simple {
 // CHECK:STDOUT:   %Self: %Simple.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type.e2e = fn_decl @F.1 [template = constants.%F.df8] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %Simple.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -89,7 +89,6 @@ impl forall [T:! type] T as Simple {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(@Simple.%Self: %Simple.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 7 - 8
toolchain/check/testdata/impl/lookup/alias.carbon

@@ -33,8 +33,8 @@ fn G(c: C) {
 // CHECK:STDOUT:   %F.type.b7b: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.f50: %F.type.b7b = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %HasF.type, %F.type.b7b [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @HasF.%F.decl [template]
+// CHECK:STDOUT:   %HasF.assoc_type: type = assoc_entity_type %HasF.type [template]
+// CHECK:STDOUT:   %assoc0: %HasF.assoc_type = assoc_entity element0, @HasF.%F.decl [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [template]
@@ -81,7 +81,7 @@ fn G(c: C) {
 // CHECK:STDOUT: interface @HasF {
 // CHECK:STDOUT:   %Self: %HasF.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type.b7b = fn_decl @F.1 [template = constants.%F.f50] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %HasF.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -99,8 +99,8 @@ fn G(c: C) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C {
 // CHECK:STDOUT:   %HasF.ref: type = name_ref HasF, file.%HasF.decl [template = constants.%HasF.type]
-// CHECK:STDOUT:   %F.ref: %F.assoc_type = name_ref F, @HasF.%assoc0 [template = constants.%assoc0]
-// CHECK:STDOUT:   %G: %F.assoc_type = bind_alias G, @HasF.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:   %F.ref: %HasF.assoc_type = name_ref F, @HasF.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:   %G: %HasF.assoc_type = bind_alias G, @HasF.%assoc0 [template = constants.%assoc0]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [template = constants.%complete_type]
 // CHECK:STDOUT:   complete_type_witness = %complete_type
 // CHECK:STDOUT:
@@ -110,7 +110,6 @@ fn G(c: C) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(@HasF.%Self: %HasF.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -122,11 +121,11 @@ fn G(c: C) {
 // CHECK:STDOUT: fn @G(%c.param_patt: %C) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %C.ref.loc24: type = name_ref C, file.%C.decl [template = constants.%C]
-// CHECK:STDOUT:   %G.ref.loc24: %F.assoc_type = name_ref G, @C.%G [template = constants.%assoc0]
+// CHECK:STDOUT:   %G.ref.loc24: %HasF.assoc_type = name_ref G, @C.%G [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0.loc24: %F.type.b7b = impl_witness_access constants.%impl_witness, element0 [template = constants.%F.dc7]
 // CHECK:STDOUT:   %F.call.loc24: init %empty_tuple.type = call %impl.elem0.loc24()
 // CHECK:STDOUT:   %c.ref: %C = name_ref c, %c
-// CHECK:STDOUT:   %G.ref.loc25: %F.assoc_type = name_ref G, @C.%G [template = constants.%assoc0]
+// CHECK:STDOUT:   %G.ref.loc25: %HasF.assoc_type = name_ref G, @C.%G [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0.loc25: %F.type.b7b = impl_witness_access constants.%impl_witness, element0 [template = constants.%F.dc7]
 // CHECK:STDOUT:   %F.call.loc25: init %empty_tuple.type = call %impl.elem0.loc25()
 // CHECK:STDOUT:   return

+ 7 - 8
toolchain/check/testdata/impl/lookup/fail_alias_impl_not_found.carbon

@@ -36,8 +36,8 @@ fn F(c: C) {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %F.type.cf0: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.bc6: %F.type.cf0 = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %I.type, %F.type.cf0 [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @I.%F.decl [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @I.%F.decl [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [template]
@@ -75,7 +75,7 @@ fn F(c: C) {
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type.cf0 = fn_decl @F.1 [template = constants.%F.bc6] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -85,8 +85,8 @@ fn F(c: C) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C {
 // CHECK:STDOUT:   %I.ref: type = name_ref I, file.%I.decl [template = constants.%I.type]
-// CHECK:STDOUT:   %F.ref: %F.assoc_type = name_ref F, @I.%assoc0 [template = constants.%assoc0]
-// CHECK:STDOUT:   %F: %F.assoc_type = bind_alias F, @I.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:   %F.ref: %I.assoc_type = name_ref F, @I.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:   %F: %I.assoc_type = bind_alias F, @I.%assoc0 [template = constants.%assoc0]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [template = constants.%complete_type]
 // CHECK:STDOUT:   complete_type_witness = %complete_type
 // CHECK:STDOUT:
@@ -96,16 +96,15 @@ fn F(c: C) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(@I.%Self: %I.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.2(%c.param_patt: %C) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %C.ref.loc24: type = name_ref C, file.%C.decl [template = constants.%C]
-// CHECK:STDOUT:   %F.ref.loc24: %F.assoc_type = name_ref F, @C.%F [template = constants.%assoc0]
+// CHECK:STDOUT:   %F.ref.loc24: %I.assoc_type = name_ref F, @C.%F [template = constants.%assoc0]
 // CHECK:STDOUT:   %c.ref: %C = name_ref c, %c
-// CHECK:STDOUT:   %F.ref.loc29: %F.assoc_type = name_ref F, @C.%F [template = constants.%assoc0]
+// CHECK:STDOUT:   %F.ref.loc29: %I.assoc_type = name_ref F, @C.%F [template = constants.%assoc0]
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 4 - 5
toolchain/check/testdata/impl/lookup/fail_todo_undefined_impl.carbon

@@ -43,8 +43,8 @@ impl C as I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %F.type.cf0: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.bc6: %F.type.cf0 = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %I.type, %F.type.cf0 [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @I.%F.decl [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @I.%F.decl [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %impl_witness.85b: <witness> = impl_witness (<error>) [template]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
@@ -96,7 +96,7 @@ impl C as I {
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type.cf0 = fn_decl @F.1 [template = constants.%F.bc6] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -129,14 +129,13 @@ impl C as I {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(@I.%Self: %I.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.2() -> %i32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %C.ref: type = name_ref C, file.%C.decl [template = constants.%C]
-// CHECK:STDOUT:   %F.ref: %F.assoc_type = name_ref F, @I.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:   %F.ref: %I.assoc_type = name_ref F, @I.%assoc0 [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0: %F.type.cf0 = impl_witness_access constants.%impl_witness.85b, element0 [template = <error>]
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }

+ 42 - 47
toolchain/check/testdata/impl/lookup/generic.carbon

@@ -130,8 +130,8 @@ fn G(x: A) {
 // CHECK:STDOUT:   %F.type.b7b: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.f50: %F.type.b7b = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %HasF.type, %F.type.b7b [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @HasF.%F.decl [template]
+// CHECK:STDOUT:   %HasF.assoc_type: type = assoc_entity_type %HasF.type [template]
+// CHECK:STDOUT:   %assoc0: %HasF.assoc_type = assoc_entity element0, @HasF.%F.decl [template]
 // CHECK:STDOUT:   %T: type = bind_symbolic_name T, 0 [symbolic]
 // CHECK:STDOUT:   %T.patt: type = symbolic_binding_pattern T, 0 [symbolic]
 // CHECK:STDOUT:   %impl_witness.d55: <witness> = impl_witness (@impl.%F.decl), @impl(%T) [symbolic]
@@ -188,7 +188,7 @@ fn G(x: A) {
 // CHECK:STDOUT: interface @HasF {
 // CHECK:STDOUT:   %Self: %HasF.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type.b7b = fn_decl @F.1 [template = constants.%F.f50] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %HasF.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -215,7 +215,6 @@ fn G(x: A) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(@HasF.%Self: %HasF.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -232,7 +231,7 @@ fn G(x: A) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %x.ref: %empty_struct_type = name_ref x, %x
 // CHECK:STDOUT:   %HasF.ref: type = name_ref HasF, file.%HasF.decl [template = constants.%HasF.type]
-// CHECK:STDOUT:   %F.ref: %F.assoc_type = name_ref F, @HasF.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:   %F.ref: %HasF.assoc_type = name_ref F, @HasF.%assoc0 [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0: %F.type.b7b = impl_witness_access constants.%impl_witness.d9b, element0 [template = constants.%F.f13]
 // CHECK:STDOUT:   %F.specific_fn: <specific function> = specific_function %impl.elem0, @F.2(constants.%empty_struct_type) [template = constants.%F.specific_fn]
 // CHECK:STDOUT:   %F.call: init %empty_tuple.type = call %F.specific_fn()
@@ -279,8 +278,8 @@ fn G(x: A) {
 // CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic]
 // CHECK:STDOUT:   %F.type.b7b: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.f50: %F.type.b7b = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %HasF.type, %F.type.b7b [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @HasF.%F.decl [template]
+// CHECK:STDOUT:   %HasF.assoc_type: type = assoc_entity_type %HasF.type [template]
+// CHECK:STDOUT:   %assoc0: %HasF.assoc_type = assoc_entity element0, @HasF.%F.decl [template]
 // CHECK:STDOUT:   %T: type = bind_symbolic_name T, 0 [symbolic]
 // CHECK:STDOUT:   %T.patt: type = symbolic_binding_pattern T, 0 [symbolic]
 // CHECK:STDOUT:   %impl_witness.d55: <witness> = impl_witness (@impl.%F.decl), @impl(%T) [symbolic]
@@ -363,7 +362,7 @@ fn G(x: A) {
 // CHECK:STDOUT:     %return.param: ref @F.1.%Self.as_type.loc5_14.1 (%Self.as_type) = out_param runtime_param1
 // CHECK:STDOUT:     %return: ref @F.1.%Self.as_type.loc5_14.1 (%Self.as_type) = return_slot %return.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %HasF.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -425,7 +424,7 @@ fn G(x: A) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %x.ref: %empty_struct_type = name_ref x, %x
 // CHECK:STDOUT:   %HasF.ref: type = name_ref HasF, file.%HasF.decl [template = constants.%HasF.type]
-// CHECK:STDOUT:   %F.ref: %F.assoc_type = name_ref F, @HasF.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:   %F.ref: %HasF.assoc_type = name_ref F, @HasF.%assoc0 [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0: %F.type.b7b = impl_witness_access constants.%impl_witness.d9b, element0 [template = constants.%F.f13]
 // CHECK:STDOUT:   %F.bound: <bound method> = bound_method %x.ref, %impl.elem0
 // CHECK:STDOUT:   %F.specific_fn: <specific function> = specific_function %F.bound, @F.2(constants.%empty_struct_type)
@@ -488,8 +487,8 @@ fn G(x: A) {
 // CHECK:STDOUT:   %F.type.b7b: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.f50: %F.type.b7b = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %HasF.type, %F.type.b7b [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @HasF.%F.decl [template]
+// CHECK:STDOUT:   %HasF.assoc_type: type = assoc_entity_type %HasF.type [template]
+// CHECK:STDOUT:   %assoc0: %HasF.assoc_type = assoc_entity element0, @HasF.%F.decl [template]
 // CHECK:STDOUT:   %T: type = bind_symbolic_name T, 0 [symbolic]
 // CHECK:STDOUT:   %T.patt: type = symbolic_binding_pattern T, 0 [symbolic]
 // CHECK:STDOUT:   %C.type: type = generic_class_type @C [template]
@@ -563,7 +562,7 @@ fn G(x: A) {
 // CHECK:STDOUT: interface @HasF {
 // CHECK:STDOUT:   %Self: %HasF.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type.b7b = fn_decl @F.1 [template = constants.%F.f50] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %HasF.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -606,7 +605,6 @@ fn G(x: A) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(@HasF.%Self: %HasF.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -623,7 +621,7 @@ fn G(x: A) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %x.ref: %C.7a7 = name_ref x, %x
 // CHECK:STDOUT:   %HasF.ref: type = name_ref HasF, file.%HasF.decl [template = constants.%HasF.type]
-// CHECK:STDOUT:   %F.ref: %F.assoc_type = name_ref F, @HasF.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:   %F.ref: %HasF.assoc_type = name_ref F, @HasF.%assoc0 [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0: %F.type.b7b = impl_witness_access constants.%impl_witness.770, element0 [template = constants.%F.c77]
 // CHECK:STDOUT:   %F.specific_fn: <specific function> = specific_function %impl.elem0, @F.2(constants.%empty_struct_type) [template = constants.%F.specific_fn]
 // CHECK:STDOUT:   %F.call: init %empty_tuple.type = call %F.specific_fn()
@@ -690,8 +688,8 @@ fn G(x: A) {
 // CHECK:STDOUT:   %Self: %HasF.type.901 = bind_symbolic_name Self, 1 [symbolic]
 // CHECK:STDOUT:   %F.type.46c: type = fn_type @F.1, @HasF(%T) [symbolic]
 // CHECK:STDOUT:   %F.823: %F.type.46c = struct_value () [symbolic]
-// CHECK:STDOUT:   %F.assoc_type.a8c: type = assoc_entity_type %HasF.type.901, %F.type.46c [symbolic]
-// CHECK:STDOUT:   %assoc0.c51: %F.assoc_type.a8c = assoc_entity element0, @HasF.%F.decl [symbolic]
+// CHECK:STDOUT:   %HasF.assoc_type.595: type = assoc_entity_type %HasF.type.901 [symbolic]
+// CHECK:STDOUT:   %assoc0.35e: %HasF.assoc_type.595 = assoc_entity element0, @HasF.%F.decl [symbolic]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %HasF.type.901 [symbolic]
 // CHECK:STDOUT:   %impl_witness.142: <witness> = impl_witness (@impl.%F.decl), @impl(%T) [symbolic]
@@ -703,8 +701,8 @@ fn G(x: A) {
 // CHECK:STDOUT:   %HasF.type.072: type = facet_type <@HasF, @HasF(%empty_struct_type)> [template]
 // CHECK:STDOUT:   %F.type.b0b: type = fn_type @F.1, @HasF(%empty_struct_type) [template]
 // CHECK:STDOUT:   %F.418: %F.type.b0b = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type.3e1: type = assoc_entity_type %HasF.type.072, %F.type.b0b [template]
-// CHECK:STDOUT:   %assoc0.6fd: %F.assoc_type.3e1 = assoc_entity element0, @HasF.%F.decl [template]
+// CHECK:STDOUT:   %HasF.assoc_type.60b: type = assoc_entity_type %HasF.type.072 [template]
+// CHECK:STDOUT:   %assoc0.46d: %HasF.assoc_type.60b = assoc_entity element0, @HasF.%F.decl [template]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %HasF.type.072 [template]
 // CHECK:STDOUT:   %impl_witness.221: <witness> = impl_witness (@impl.%F.decl), @impl(%empty_struct_type) [template]
 // CHECK:STDOUT:   %F.type.a13: type = fn_type @F.2, @impl(%empty_struct_type) [template]
@@ -768,13 +766,13 @@ fn G(x: A) {
 // CHECK:STDOUT:   %Self.2: %HasF.type.901 = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
 // CHECK:STDOUT:   %F.type: type = fn_type @F.1, @HasF(%T.loc4_16.2) [symbolic = %F.type (constants.%F.type.46c)]
 // CHECK:STDOUT:   %F: @HasF.%F.type (%F.type.46c) = struct_value () [symbolic = %F (constants.%F.823)]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type @HasF.%HasF.type (%HasF.type.901), @HasF.%F.type (%F.type.46c) [symbolic = %F.assoc_type (constants.%F.assoc_type.a8c)]
-// CHECK:STDOUT:   %assoc0.loc5_9.2: @HasF.%F.assoc_type (%F.assoc_type.a8c) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc5_9.2 (constants.%assoc0.c51)]
+// CHECK:STDOUT:   %HasF.assoc_type: type = assoc_entity_type @HasF.%HasF.type (%HasF.type.901) [symbolic = %HasF.assoc_type (constants.%HasF.assoc_type.595)]
+// CHECK:STDOUT:   %assoc0.loc5_9.2: @HasF.%HasF.assoc_type (%HasF.assoc_type.595) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc5_9.2 (constants.%assoc0.35e)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:     %Self.1: @HasF.%HasF.type (%HasF.type.901) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
 // CHECK:STDOUT:     %F.decl: @HasF.%F.type (%F.type.46c) = fn_decl @F.1 [symbolic = @HasF.%F (constants.%F.823)] {} {}
-// CHECK:STDOUT:     %assoc0.loc5_9.1: @HasF.%F.assoc_type (%F.assoc_type.a8c) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc5_9.2 (constants.%assoc0.c51)]
+// CHECK:STDOUT:     %assoc0.loc5_9.1: @HasF.%HasF.assoc_type (%HasF.assoc_type.595) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc5_9.2 (constants.%assoc0.35e)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = %Self.1
@@ -804,7 +802,6 @@ fn G(x: A) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(@HasF.%T.loc4_16.1: type, @HasF.%Self.1: @HasF.%HasF.type (%HasF.type.901)) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -824,8 +821,8 @@ fn G(x: A) {
 // CHECK:STDOUT:   %.loc13_12: %empty_struct_type = struct_literal ()
 // CHECK:STDOUT:   %.loc13_13: type = converted %.loc13_12, constants.%empty_struct_type [template = constants.%empty_struct_type]
 // CHECK:STDOUT:   %HasF.type: type = facet_type <@HasF, @HasF(constants.%empty_struct_type)> [template = constants.%HasF.type.072]
-// CHECK:STDOUT:   %.loc13_14: %F.assoc_type.3e1 = specific_constant @HasF.%assoc0.loc5_9.1, @HasF(constants.%empty_struct_type) [template = constants.%assoc0.6fd]
-// CHECK:STDOUT:   %F.ref: %F.assoc_type.3e1 = name_ref F, %.loc13_14 [template = constants.%assoc0.6fd]
+// CHECK:STDOUT:   %.loc13_14: %HasF.assoc_type.60b = specific_constant @HasF.%assoc0.loc5_9.1, @HasF(constants.%empty_struct_type) [template = constants.%assoc0.46d]
+// CHECK:STDOUT:   %F.ref: %HasF.assoc_type.60b = name_ref F, %.loc13_14 [template = constants.%assoc0.46d]
 // CHECK:STDOUT:   %impl.elem0: %F.type.b0b = impl_witness_access constants.%impl_witness.221, element0 [template = constants.%F.8c6]
 // CHECK:STDOUT:   %F.specific_fn: <specific function> = specific_function %impl.elem0, @F.2(constants.%empty_struct_type) [template = constants.%F.specific_fn]
 // CHECK:STDOUT:   %F.call: init %empty_tuple.type = call %F.specific_fn()
@@ -841,8 +838,8 @@ fn G(x: A) {
 // CHECK:STDOUT:   %Self.2 => constants.%Self
 // CHECK:STDOUT:   %F.type => constants.%F.type.46c
 // CHECK:STDOUT:   %F => constants.%F.823
-// CHECK:STDOUT:   %F.assoc_type => constants.%F.assoc_type.a8c
-// CHECK:STDOUT:   %assoc0.loc5_9.2 => constants.%assoc0.c51
+// CHECK:STDOUT:   %HasF.assoc_type => constants.%HasF.assoc_type.595
+// CHECK:STDOUT:   %assoc0.loc5_9.2 => constants.%assoc0.35e
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F.1(constants.%T, constants.%Self) {}
@@ -878,8 +875,8 @@ fn G(x: A) {
 // CHECK:STDOUT:   %Self.2 => constants.%Self
 // CHECK:STDOUT:   %F.type => constants.%F.type.b0b
 // CHECK:STDOUT:   %F => constants.%F.418
-// CHECK:STDOUT:   %F.assoc_type => constants.%F.assoc_type.3e1
-// CHECK:STDOUT:   %assoc0.loc5_9.2 => constants.%assoc0.6fd
+// CHECK:STDOUT:   %HasF.assoc_type => constants.%HasF.assoc_type.60b
+// CHECK:STDOUT:   %assoc0.loc5_9.2 => constants.%assoc0.46d
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl(constants.%empty_struct_type) {
@@ -905,8 +902,8 @@ fn G(x: A) {
 // CHECK:STDOUT:   %Self: %HasF.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %F.type.b7b: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.f50: %F.type.b7b = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %HasF.type, %F.type.b7b [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @HasF.%F.decl [template]
+// CHECK:STDOUT:   %HasF.assoc_type: type = assoc_entity_type %HasF.type [template]
+// CHECK:STDOUT:   %assoc0: %HasF.assoc_type = assoc_entity element0, @HasF.%F.decl [template]
 // CHECK:STDOUT:   %T: type = bind_symbolic_name T, 0 [symbolic]
 // CHECK:STDOUT:   %T.patt: type = symbolic_binding_pattern T, 0 [symbolic]
 // CHECK:STDOUT:   %U: type = bind_symbolic_name U, 1 [symbolic]
@@ -965,7 +962,7 @@ fn G(x: A) {
 // CHECK:STDOUT: interface @HasF {
 // CHECK:STDOUT:   %Self: %HasF.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type.b7b = fn_decl @F.1 [template = constants.%F.f50] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %HasF.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -994,7 +991,6 @@ fn G(x: A) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(@HasF.%Self: %HasF.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -1011,7 +1007,7 @@ fn G(x: A) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %x.ref: %empty_struct_type = name_ref x, %x
 // CHECK:STDOUT:   %HasF.ref: type = name_ref HasF, file.%HasF.decl [template = constants.%HasF.type]
-// CHECK:STDOUT:   %F.ref: %F.assoc_type = name_ref F, @HasF.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:   %F.ref: %HasF.assoc_type = name_ref F, @HasF.%assoc0 [template = constants.%assoc0]
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -1046,8 +1042,8 @@ fn G(x: A) {
 // CHECK:STDOUT:   %Self: %HasF.type.901 = bind_symbolic_name Self, 1 [symbolic]
 // CHECK:STDOUT:   %F.type.46c: type = fn_type @F.1, @HasF(%T) [symbolic]
 // CHECK:STDOUT:   %F.823: %F.type.46c = struct_value () [symbolic]
-// CHECK:STDOUT:   %F.assoc_type.a8c: type = assoc_entity_type %HasF.type.901, %F.type.46c [symbolic]
-// CHECK:STDOUT:   %assoc0.c51: %F.assoc_type.a8c = assoc_entity element0, @HasF.%F.decl [symbolic]
+// CHECK:STDOUT:   %HasF.assoc_type.595: type = assoc_entity_type %HasF.type.901 [symbolic]
+// CHECK:STDOUT:   %assoc0.35e: %HasF.assoc_type.595 = assoc_entity element0, @HasF.%F.decl [symbolic]
 // CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %HasF.type.901 [symbolic]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (@impl.%F.decl), @impl(%T) [symbolic]
 // CHECK:STDOUT:   %F.type.912: type = fn_type @F.2, @impl(%T) [symbolic]
@@ -1062,8 +1058,8 @@ fn G(x: A) {
 // CHECK:STDOUT:   %HasF.type.2f5: type = facet_type <@HasF, @HasF(%B)> [template]
 // CHECK:STDOUT:   %F.type.1c6: type = fn_type @F.1, @HasF(%B) [template]
 // CHECK:STDOUT:   %F.7cf: %F.type.1c6 = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type.00a: type = assoc_entity_type %HasF.type.2f5, %F.type.1c6 [template]
-// CHECK:STDOUT:   %assoc0.c2a: %F.assoc_type.00a = assoc_entity element0, @HasF.%F.decl [template]
+// CHECK:STDOUT:   %HasF.assoc_type.3e1: type = assoc_entity_type %HasF.type.2f5 [template]
+// CHECK:STDOUT:   %assoc0.8ec: %HasF.assoc_type.3e1 = assoc_entity element0, @HasF.%F.decl [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -1122,13 +1118,13 @@ fn G(x: A) {
 // CHECK:STDOUT:   %Self.2: %HasF.type.901 = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
 // CHECK:STDOUT:   %F.type: type = fn_type @F.1, @HasF(%T.loc4_16.2) [symbolic = %F.type (constants.%F.type.46c)]
 // CHECK:STDOUT:   %F: @HasF.%F.type (%F.type.46c) = struct_value () [symbolic = %F (constants.%F.823)]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type @HasF.%HasF.type (%HasF.type.901), @HasF.%F.type (%F.type.46c) [symbolic = %F.assoc_type (constants.%F.assoc_type.a8c)]
-// CHECK:STDOUT:   %assoc0.loc5_9.2: @HasF.%F.assoc_type (%F.assoc_type.a8c) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc5_9.2 (constants.%assoc0.c51)]
+// CHECK:STDOUT:   %HasF.assoc_type: type = assoc_entity_type @HasF.%HasF.type (%HasF.type.901) [symbolic = %HasF.assoc_type (constants.%HasF.assoc_type.595)]
+// CHECK:STDOUT:   %assoc0.loc5_9.2: @HasF.%HasF.assoc_type (%HasF.assoc_type.595) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc5_9.2 (constants.%assoc0.35e)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:     %Self.1: @HasF.%HasF.type (%HasF.type.901) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
 // CHECK:STDOUT:     %F.decl: @HasF.%F.type (%F.type.46c) = fn_decl @F.1 [symbolic = @HasF.%F (constants.%F.823)] {} {}
-// CHECK:STDOUT:     %assoc0.loc5_9.1: @HasF.%F.assoc_type (%F.assoc_type.a8c) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc5_9.2 (constants.%assoc0.c51)]
+// CHECK:STDOUT:     %assoc0.loc5_9.1: @HasF.%HasF.assoc_type (%HasF.assoc_type.595) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc5_9.2 (constants.%assoc0.35e)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = %Self.1
@@ -1174,7 +1170,6 @@ fn G(x: A) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(@HasF.%T.loc4_16.1: type, @HasF.%Self.1: @HasF.%HasF.type (%HasF.type.901)) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -1193,8 +1188,8 @@ fn G(x: A) {
 // CHECK:STDOUT:   %HasF.ref: %HasF.type.fe3 = name_ref HasF, file.%HasF.decl [template = constants.%HasF.generic]
 // CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B.decl [template = constants.%B]
 // CHECK:STDOUT:   %HasF.type: type = facet_type <@HasF, @HasF(constants.%B)> [template = constants.%HasF.type.2f5]
-// CHECK:STDOUT:   %.loc22: %F.assoc_type.00a = specific_constant @HasF.%assoc0.loc5_9.1, @HasF(constants.%B) [template = constants.%assoc0.c2a]
-// CHECK:STDOUT:   %F.ref: %F.assoc_type.00a = name_ref F, %.loc22 [template = constants.%assoc0.c2a]
+// CHECK:STDOUT:   %.loc22: %HasF.assoc_type.3e1 = specific_constant @HasF.%assoc0.loc5_9.1, @HasF(constants.%B) [template = constants.%assoc0.8ec]
+// CHECK:STDOUT:   %F.ref: %HasF.assoc_type.3e1 = name_ref F, %.loc22 [template = constants.%assoc0.8ec]
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -1207,8 +1202,8 @@ fn G(x: A) {
 // CHECK:STDOUT:   %Self.2 => constants.%Self
 // CHECK:STDOUT:   %F.type => constants.%F.type.46c
 // CHECK:STDOUT:   %F => constants.%F.823
-// CHECK:STDOUT:   %F.assoc_type => constants.%F.assoc_type.a8c
-// CHECK:STDOUT:   %assoc0.loc5_9.2 => constants.%assoc0.c51
+// CHECK:STDOUT:   %HasF.assoc_type => constants.%HasF.assoc_type.595
+// CHECK:STDOUT:   %assoc0.loc5_9.2 => constants.%assoc0.35e
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F.1(constants.%T, constants.%Self) {}
@@ -1244,7 +1239,7 @@ fn G(x: A) {
 // CHECK:STDOUT:   %Self.2 => constants.%Self
 // CHECK:STDOUT:   %F.type => constants.%F.type.1c6
 // CHECK:STDOUT:   %F => constants.%F.7cf
-// CHECK:STDOUT:   %F.assoc_type => constants.%F.assoc_type.00a
-// CHECK:STDOUT:   %assoc0.loc5_9.2 => constants.%assoc0.c2a
+// CHECK:STDOUT:   %HasF.assoc_type => constants.%HasF.assoc_type.3e1
+// CHECK:STDOUT:   %assoc0.loc5_9.2 => constants.%assoc0.8ec
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

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

@@ -35,8 +35,8 @@ fn F(c: C) -> i32 {
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [template]
 // CHECK:STDOUT:   %F.type.cf0: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.bc6: %F.type.cf0 = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %I.type, %F.type.cf0 [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @I.%F.decl [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @I.%F.decl [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (@impl.%F.decl) [template]
 // CHECK:STDOUT:   %F.type.f36: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.4c3: %F.type.f36 = struct_value () [template]
@@ -102,7 +102,7 @@ fn F(c: C) -> i32 {
 // CHECK:STDOUT:     %return.param: ref %i32 = out_param runtime_param1
 // CHECK:STDOUT:     %return: ref %i32 = return_slot %return.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -157,7 +157,7 @@ fn F(c: C) -> i32 {
 // CHECK:STDOUT: fn @F.3(%c.param_patt: %C) -> %i32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %c.ref: %C = name_ref c, %c
-// CHECK:STDOUT:   %F.ref: %F.assoc_type = name_ref F, @I.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:   %F.ref: %I.assoc_type = name_ref F, @I.%assoc0 [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0: %F.type.cf0 = impl_witness_access constants.%impl_witness, element0 [template = constants.%F.4c3]
 // CHECK:STDOUT:   %F.bound: <bound method> = bound_method %c.ref, %impl.elem0
 // CHECK:STDOUT:   %F.call: init %i32 = call %F.bound(%c.ref)

+ 27 - 27
toolchain/check/testdata/impl/lookup/no_prelude/impl_forall.carbon

@@ -53,8 +53,8 @@ fn TestSpecific(a: A({})) -> {} {
 // CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic]
 // CHECK:STDOUT:   %F.type.2aef59.1: type = fn_type @F.1, @I(%U) [symbolic]
 // CHECK:STDOUT:   %F.bb2dd4.1: %F.type.2aef59.1 = struct_value () [symbolic]
-// CHECK:STDOUT:   %F.assoc_type.003a5c.1: type = assoc_entity_type %I.type.325e65.1, %F.type.2aef59.1 [symbolic]
-// CHECK:STDOUT:   %assoc0.819972.1: %F.assoc_type.003a5c.1 = assoc_entity element0, @I.%F.decl [symbolic]
+// CHECK:STDOUT:   %I.assoc_type.955255.1: type = assoc_entity_type %I.type.325e65.1 [symbolic]
+// CHECK:STDOUT:   %assoc0.fef501.1: %I.assoc_type.955255.1 = assoc_entity element0, @I.%F.decl [symbolic]
 // CHECK:STDOUT:   %V: type = bind_symbolic_name V, 0 [symbolic]
 // CHECK:STDOUT:   %V.patt: type = symbolic_binding_pattern V, 0 [symbolic]
 // CHECK:STDOUT:   %A.13025a.2: type = class_type @A, @A(%V) [symbolic]
@@ -62,8 +62,8 @@ fn TestSpecific(a: A({})) -> {} {
 // CHECK:STDOUT:   %require_complete.cfebb2.1: <witness> = require_complete_type %I.type.325e65.2 [symbolic]
 // CHECK:STDOUT:   %F.type.2aef59.2: type = fn_type @F.1, @I(%V) [symbolic]
 // CHECK:STDOUT:   %F.bb2dd4.2: %F.type.2aef59.2 = struct_value () [symbolic]
-// CHECK:STDOUT:   %F.assoc_type.003a5c.2: type = assoc_entity_type %I.type.325e65.2, %F.type.2aef59.2 [symbolic]
-// CHECK:STDOUT:   %assoc0.819972.2: %F.assoc_type.003a5c.2 = assoc_entity element0, @I.%F.decl [symbolic]
+// CHECK:STDOUT:   %I.assoc_type.955255.2: type = assoc_entity_type %I.type.325e65.2 [symbolic]
+// CHECK:STDOUT:   %assoc0.fef501.2: %I.assoc_type.955255.2 = assoc_entity element0, @I.%F.decl [symbolic]
 // CHECK:STDOUT:   %impl_witness.ab3b51.1: <witness> = impl_witness (@impl.%F.decl), @impl(%V) [symbolic]
 // CHECK:STDOUT:   %F.type.0fea45.1: type = fn_type @F.2, @impl(%V) [symbolic]
 // CHECK:STDOUT:   %F.d6ae34.1: %F.type.0fea45.1 = struct_value () [symbolic]
@@ -87,8 +87,8 @@ fn TestSpecific(a: A({})) -> {} {
 // CHECK:STDOUT:   %require_complete.cfebb2.2: <witness> = require_complete_type %I.type.325e65.3 [symbolic]
 // CHECK:STDOUT:   %F.type.2aef59.3: type = fn_type @F.1, @I(%W) [symbolic]
 // CHECK:STDOUT:   %F.bb2dd4.3: %F.type.2aef59.3 = struct_value () [symbolic]
-// CHECK:STDOUT:   %F.assoc_type.003a5c.3: type = assoc_entity_type %I.type.325e65.3, %F.type.2aef59.3 [symbolic]
-// CHECK:STDOUT:   %assoc0.819972.3: %F.assoc_type.003a5c.3 = assoc_entity element0, @I.%F.decl [symbolic]
+// CHECK:STDOUT:   %I.assoc_type.955255.3: type = assoc_entity_type %I.type.325e65.3 [symbolic]
+// CHECK:STDOUT:   %assoc0.fef501.3: %I.assoc_type.955255.3 = assoc_entity element0, @I.%F.decl [symbolic]
 // CHECK:STDOUT:   %impl_witness.ab3b51.2: <witness> = impl_witness (@impl.%F.decl), @impl(%W) [symbolic]
 // CHECK:STDOUT:   %F.type.0fea45.2: type = fn_type @F.2, @impl(%W) [symbolic]
 // CHECK:STDOUT:   %F.d6ae34.2: %F.type.0fea45.2 = struct_value () [symbolic]
@@ -103,8 +103,8 @@ fn TestSpecific(a: A({})) -> {} {
 // CHECK:STDOUT:   %I.type.885: type = facet_type <@I, @I(%empty_struct_type)> [template]
 // CHECK:STDOUT:   %F.type.684: type = fn_type @F.1, @I(%empty_struct_type) [template]
 // CHECK:STDOUT:   %F.a8d: %F.type.684 = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type.6a8: type = assoc_entity_type %I.type.885, %F.type.684 [template]
-// CHECK:STDOUT:   %assoc0.d32: %F.assoc_type.6a8 = assoc_entity element0, @I.%F.decl [template]
+// CHECK:STDOUT:   %I.assoc_type.67f: type = assoc_entity_type %I.type.885 [template]
+// CHECK:STDOUT:   %assoc0.639: %I.assoc_type.67f = assoc_entity element0, @I.%F.decl [template]
 // CHECK:STDOUT:   %complete_type.788: <witness> = complete_type_witness %I.type.885 [template]
 // CHECK:STDOUT:   %impl_witness.f35: <witness> = impl_witness (@impl.%F.decl), @impl(%empty_struct_type) [template]
 // CHECK:STDOUT:   %F.type.875: type = fn_type @F.2, @impl(%empty_struct_type) [template]
@@ -198,8 +198,8 @@ fn TestSpecific(a: A({})) -> {} {
 // CHECK:STDOUT:   %Self.2: %I.type.325e65.1 = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
 // CHECK:STDOUT:   %F.type: type = fn_type @F.1, @I(%U.loc6_13.2) [symbolic = %F.type (constants.%F.type.2aef59.1)]
 // CHECK:STDOUT:   %F: @I.%F.type (%F.type.2aef59.1) = struct_value () [symbolic = %F (constants.%F.bb2dd4.1)]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type @I.%I.type (%I.type.325e65.1), @I.%F.type (%F.type.2aef59.1) [symbolic = %F.assoc_type (constants.%F.assoc_type.003a5c.1)]
-// CHECK:STDOUT:   %assoc0.loc7_26.2: @I.%F.assoc_type (%F.assoc_type.003a5c.1) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc7_26.2 (constants.%assoc0.819972.1)]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type @I.%I.type (%I.type.325e65.1) [symbolic = %I.assoc_type (constants.%I.assoc_type.955255.1)]
+// CHECK:STDOUT:   %assoc0.loc7_26.2: @I.%I.assoc_type (%I.assoc_type.955255.1) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc7_26.2 (constants.%assoc0.fef501.1)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:     %Self.1: @I.%I.type (%I.type.325e65.1) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
@@ -221,7 +221,7 @@ fn TestSpecific(a: A({})) -> {} {
 // CHECK:STDOUT:       %return.param: ref @F.1.%U (%U) = out_param runtime_param1
 // CHECK:STDOUT:       %return: ref @F.1.%U (%U) = return_slot %return.param
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %assoc0.loc7_26.1: @I.%F.assoc_type (%F.assoc_type.003a5c.1) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc7_26.2 (constants.%assoc0.819972.1)]
+// CHECK:STDOUT:     %assoc0.loc7_26.1: @I.%I.assoc_type (%I.assoc_type.955255.1) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc7_26.2 (constants.%assoc0.fef501.1)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = %Self.1
@@ -327,11 +327,11 @@ fn TestSpecific(a: A({})) -> {} {
 // CHECK:STDOUT:   %require_complete.loc16_27: <witness> = require_complete_type @TestGeneric.%A.loc16_32.2 (%A.13025a.3) [symbolic = %require_complete.loc16_27 (constants.%require_complete.5b8aee.2)]
 // CHECK:STDOUT:   %I.type.loc17_16.2: type = facet_type <@I, @I(%W.loc16_16.2)> [symbolic = %I.type.loc17_16.2 (constants.%I.type.325e65.3)]
 // CHECK:STDOUT:   %require_complete.loc17: <witness> = require_complete_type @TestGeneric.%I.type.loc17_16.2 (%I.type.325e65.3) [symbolic = %require_complete.loc17 (constants.%require_complete.cfebb2.2)]
-// CHECK:STDOUT:   %F.type.loc17_17: type = fn_type @F.1, @I(%W.loc16_16.2) [symbolic = %F.type.loc17_17 (constants.%F.type.2aef59.3)]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type @TestGeneric.%I.type.loc17_16.2 (%I.type.325e65.3), @TestGeneric.%F.type.loc17_17 (%F.type.2aef59.3) [symbolic = %F.assoc_type (constants.%F.assoc_type.003a5c.3)]
-// CHECK:STDOUT:   %assoc0: @TestGeneric.%F.assoc_type (%F.assoc_type.003a5c.3) = assoc_entity element0, @I.%F.decl [symbolic = %assoc0 (constants.%assoc0.819972.3)]
-// CHECK:STDOUT:   %F.type.loc17_11: type = fn_type @F.2, @impl(%W.loc16_16.2) [symbolic = %F.type.loc17_11 (constants.%F.type.0fea45.2)]
-// CHECK:STDOUT:   %F: @TestGeneric.%F.type.loc17_11 (%F.type.0fea45.2) = struct_value () [symbolic = %F (constants.%F.d6ae34.2)]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type @TestGeneric.%I.type.loc17_16.2 (%I.type.325e65.3) [symbolic = %I.assoc_type (constants.%I.assoc_type.955255.3)]
+// CHECK:STDOUT:   %assoc0: @TestGeneric.%I.assoc_type (%I.assoc_type.955255.3) = assoc_entity element0, @I.%F.decl [symbolic = %assoc0 (constants.%assoc0.fef501.3)]
+// CHECK:STDOUT:   %F.type.loc17_11.1: type = fn_type @F.1, @I(%W.loc16_16.2) [symbolic = %F.type.loc17_11.1 (constants.%F.type.2aef59.3)]
+// CHECK:STDOUT:   %F.type.loc17_11.2: type = fn_type @F.2, @impl(%W.loc16_16.2) [symbolic = %F.type.loc17_11.2 (constants.%F.type.0fea45.2)]
+// CHECK:STDOUT:   %F: @TestGeneric.%F.type.loc17_11.2 (%F.type.0fea45.2) = struct_value () [symbolic = %F (constants.%F.d6ae34.2)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn[%W.param_patt: type](%a.param_patt: @TestGeneric.%A.loc16_32.2 (%A.13025a.3)) -> @TestGeneric.%W.loc16_16.2 (%W) {
 // CHECK:STDOUT:   !entry:
@@ -339,9 +339,9 @@ fn TestSpecific(a: A({})) -> {} {
 // CHECK:STDOUT:     %I.ref: %I.type.dac = name_ref I, file.%I.decl [template = constants.%I.generic]
 // CHECK:STDOUT:     %W.ref.loc17: type = name_ref W, %W.loc16_16.1 [symbolic = %W.loc16_16.2 (constants.%W)]
 // CHECK:STDOUT:     %I.type.loc17_16.1: type = facet_type <@I, @I(constants.%W)> [symbolic = %I.type.loc17_16.2 (constants.%I.type.325e65.3)]
-// CHECK:STDOUT:     %.loc17_17: @TestGeneric.%F.assoc_type (%F.assoc_type.003a5c.3) = specific_constant @I.%assoc0.loc7_26.1, @I(constants.%W) [symbolic = %assoc0 (constants.%assoc0.819972.3)]
-// CHECK:STDOUT:     %F.ref: @TestGeneric.%F.assoc_type (%F.assoc_type.003a5c.3) = name_ref F, %.loc17_17 [symbolic = %assoc0 (constants.%assoc0.819972.3)]
-// CHECK:STDOUT:     %impl.elem0: @TestGeneric.%F.type.loc17_17 (%F.type.2aef59.3) = impl_witness_access constants.%impl_witness.ab3b51.2, element0 [symbolic = %F (constants.%F.d6ae34.2)]
+// CHECK:STDOUT:     %.loc17_17: @TestGeneric.%I.assoc_type (%I.assoc_type.955255.3) = specific_constant @I.%assoc0.loc7_26.1, @I(constants.%W) [symbolic = %assoc0 (constants.%assoc0.fef501.3)]
+// CHECK:STDOUT:     %F.ref: @TestGeneric.%I.assoc_type (%I.assoc_type.955255.3) = name_ref F, %.loc17_17 [symbolic = %assoc0 (constants.%assoc0.fef501.3)]
+// CHECK:STDOUT:     %impl.elem0: @TestGeneric.%F.type.loc17_11.1 (%F.type.2aef59.3) = impl_witness_access constants.%impl_witness.ab3b51.2, element0 [symbolic = %F (constants.%F.d6ae34.2)]
 // CHECK:STDOUT:     %F.bound: <bound method> = bound_method %a.ref, %impl.elem0
 // CHECK:STDOUT:     %F.specific_fn: <specific function> = specific_function %F.bound, @F.2(constants.%W)
 // CHECK:STDOUT:     %F.call: init @TestGeneric.%W.loc16_16.2 (%W) = call %F.specific_fn(%a.ref)
@@ -358,8 +358,8 @@ fn TestSpecific(a: A({})) -> {} {
 // CHECK:STDOUT:   %.loc21_16: %empty_struct_type = struct_literal ()
 // CHECK:STDOUT:   %.loc21_17: type = converted %.loc21_16, constants.%empty_struct_type [template = constants.%empty_struct_type]
 // CHECK:STDOUT:   %I.type: type = facet_type <@I, @I(constants.%empty_struct_type)> [template = constants.%I.type.885]
-// CHECK:STDOUT:   %.loc21_18: %F.assoc_type.6a8 = specific_constant @I.%assoc0.loc7_26.1, @I(constants.%empty_struct_type) [template = constants.%assoc0.d32]
-// CHECK:STDOUT:   %F.ref: %F.assoc_type.6a8 = name_ref F, %.loc21_18 [template = constants.%assoc0.d32]
+// CHECK:STDOUT:   %.loc21_18: %I.assoc_type.67f = specific_constant @I.%assoc0.loc7_26.1, @I(constants.%empty_struct_type) [template = constants.%assoc0.639]
+// CHECK:STDOUT:   %F.ref: %I.assoc_type.67f = name_ref F, %.loc21_18 [template = constants.%assoc0.639]
 // CHECK:STDOUT:   %impl.elem0: %F.type.684 = impl_witness_access constants.%impl_witness.f35, element0 [template = constants.%F.158]
 // CHECK:STDOUT:   %F.bound: <bound method> = bound_method %a.ref, %impl.elem0
 // CHECK:STDOUT:   %F.specific_fn: <specific function> = specific_function %F.bound, @F.2(constants.%empty_struct_type)
@@ -415,8 +415,8 @@ fn TestSpecific(a: A({})) -> {} {
 // CHECK:STDOUT:   %Self.2 => constants.%Self
 // CHECK:STDOUT:   %F.type => constants.%F.type.2aef59.2
 // CHECK:STDOUT:   %F => constants.%F.bb2dd4.2
-// CHECK:STDOUT:   %F.assoc_type => constants.%F.assoc_type.003a5c.2
-// CHECK:STDOUT:   %assoc0.loc7_26.2 => constants.%assoc0.819972.2
+// CHECK:STDOUT:   %I.assoc_type => constants.%I.assoc_type.955255.2
+// CHECK:STDOUT:   %assoc0.loc7_26.2 => constants.%assoc0.fef501.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl(constants.%V) {
@@ -481,8 +481,8 @@ fn TestSpecific(a: A({})) -> {} {
 // CHECK:STDOUT:   %Self.2 => constants.%Self
 // CHECK:STDOUT:   %F.type => constants.%F.type.2aef59.3
 // CHECK:STDOUT:   %F => constants.%F.bb2dd4.3
-// CHECK:STDOUT:   %F.assoc_type => constants.%F.assoc_type.003a5c.3
-// CHECK:STDOUT:   %assoc0.loc7_26.2 => constants.%assoc0.819972.3
+// CHECK:STDOUT:   %I.assoc_type => constants.%I.assoc_type.955255.3
+// CHECK:STDOUT:   %assoc0.loc7_26.2 => constants.%assoc0.fef501.3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl(constants.%W) {
@@ -533,8 +533,8 @@ fn TestSpecific(a: A({})) -> {} {
 // CHECK:STDOUT:   %Self.2 => constants.%Self
 // CHECK:STDOUT:   %F.type => constants.%F.type.684
 // CHECK:STDOUT:   %F => constants.%F.a8d
-// CHECK:STDOUT:   %F.assoc_type => constants.%F.assoc_type.6a8
-// CHECK:STDOUT:   %assoc0.loc7_26.2 => constants.%assoc0.d32
+// CHECK:STDOUT:   %I.assoc_type => constants.%I.assoc_type.67f
+// CHECK:STDOUT:   %assoc0.loc7_26.2 => constants.%assoc0.639
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl(constants.%empty_struct_type) {

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

@@ -197,8 +197,8 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %Self: %HasF.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %F.type.b7b: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.f50: %F.type.b7b = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %HasF.type, %F.type.b7b [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @HasF.%F.decl [template]
+// CHECK:STDOUT:   %HasF.assoc_type: type = assoc_entity_type %HasF.type [template]
+// CHECK:STDOUT:   %assoc0: %HasF.assoc_type = assoc_entity element0, @HasF.%F.decl [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [template]
@@ -225,7 +225,7 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: interface @HasF {
 // CHECK:STDOUT:   %Self: %HasF.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type.b7b = fn_decl @F.1 [template = constants.%F.f50] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %HasF.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -250,7 +250,6 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(@HasF.%Self: %HasF.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -270,8 +269,8 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %Self.d42: %HasG.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %G.type.d27: type = fn_type @G.1 [template]
 // CHECK:STDOUT:   %G.688: %G.type.d27 = struct_value () [template]
-// CHECK:STDOUT:   %G.assoc_type: type = assoc_entity_type %HasG.type, %G.type.d27 [template]
-// CHECK:STDOUT:   %assoc0: %G.assoc_type = assoc_entity element0, @HasG.%G.decl [template]
+// CHECK:STDOUT:   %HasG.assoc_type: type = assoc_entity_type %HasG.type [template]
+// CHECK:STDOUT:   %assoc0: %HasG.assoc_type = assoc_entity element0, @HasG.%G.decl [template]
 // CHECK:STDOUT:   %D: type = class_type @D [template]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [template]
@@ -305,7 +304,7 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %PackageA.import_ref.2c4 = import_ref PackageA//default, inst25 [no loc], unloaded
 // CHECK:STDOUT:   %PackageA.HasF: type = import_ref PackageA//default, HasF, loaded [template = constants.%HasF.type]
 // CHECK:STDOUT:   %PackageA.import_ref.28c = import_ref PackageA//default, inst15 [no loc], unloaded
-// CHECK:STDOUT:   %PackageA.import_ref.798 = import_ref PackageA//default, loc5_9, unloaded
+// CHECK:STDOUT:   %PackageA.import_ref.a2a = import_ref PackageA//default, loc5_9, unloaded
 // CHECK:STDOUT:   %PackageA.F: %F.type.dbc = import_ref PackageA//default, F, loaded [template = constants.%F.a2b]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -340,7 +339,7 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: interface @HasG {
 // CHECK:STDOUT:   %Self: %HasG.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.d42]
 // CHECK:STDOUT:   %G.decl: %G.type.d27 = fn_decl @G.1 [template = constants.%G.688] {} {}
-// CHECK:STDOUT:   %assoc0: %G.assoc_type = assoc_entity element0, %G.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %HasG.assoc_type = assoc_entity element0, %G.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -351,7 +350,7 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: interface @HasF [from "package_a.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = imports.%PackageA.import_ref.28c
-// CHECK:STDOUT:   .F = imports.%PackageA.import_ref.798
+// CHECK:STDOUT:   .F = imports.%PackageA.import_ref.a2a
 // CHECK:STDOUT:   witness = (imports.%PackageA.F)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -395,7 +394,6 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @G.1(@HasG.%Self: %HasG.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -405,7 +403,6 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(constants.%Self.cf3: %HasF.type) [from "package_a.carbon"] {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -440,10 +437,10 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %TestCF: %TestCF.type = struct_value () [template]
 // CHECK:STDOUT:   %HasF.type: type = facet_type <@HasF> [template]
 // CHECK:STDOUT:   %Self: %HasF.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %F.type.dbc: type = fn_type @F.1 [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %HasF.type, %F.type.dbc [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, imports.%PackageA.import_ref.13e [template]
+// CHECK:STDOUT:   %HasF.assoc_type: type = assoc_entity_type %HasF.type [template]
+// CHECK:STDOUT:   %assoc0: %HasF.assoc_type = assoc_entity element0, imports.%PackageA.import_ref.ab2 [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (imports.%PackageA.import_ref.148) [template]
+// CHECK:STDOUT:   %F.type.dbc: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.type.4e3: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.857: %F.type.4e3 = struct_value () [template]
 // CHECK:STDOUT: }
@@ -459,7 +456,7 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %PackageA.import_ref.2c4 = import_ref PackageA//default, inst25 [no loc], unloaded
 // CHECK:STDOUT:   %PackageA.HasF: type = import_ref PackageA//default, HasF, loaded [template = constants.%HasF.type]
 // CHECK:STDOUT:   %PackageA.import_ref.28c = import_ref PackageA//default, inst15 [no loc], unloaded
-// CHECK:STDOUT:   %PackageA.import_ref.5f1: %F.assoc_type = import_ref PackageA//default, loc5_9, loaded [template = constants.%assoc0]
+// CHECK:STDOUT:   %PackageA.import_ref.566: %HasF.assoc_type = import_ref PackageA//default, loc5_9, loaded [template = constants.%assoc0]
 // CHECK:STDOUT:   %PackageA.F = import_ref PackageA//default, F, unloaded
 // CHECK:STDOUT:   %PackageA.import_ref.a71: <witness> = import_ref PackageA//default, loc11_16, loaded [template = constants.%impl_witness]
 // CHECK:STDOUT:   %PackageA.import_ref.29a: type = import_ref PackageA//default, loc11_6, loaded [template = constants.%C]
@@ -488,7 +485,7 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: interface @HasF [from "package_a.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = imports.%PackageA.import_ref.28c
-// CHECK:STDOUT:   .F = imports.%PackageA.import_ref.5f1
+// CHECK:STDOUT:   .F = imports.%PackageA.import_ref.566
 // CHECK:STDOUT:   witness = (imports.%PackageA.F)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -509,14 +506,13 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %c.ref: %C = name_ref c, %c
 // CHECK:STDOUT:   %PackageA.ref.loc7: <namespace> = name_ref PackageA, imports.%PackageA [template = imports.%PackageA]
 // CHECK:STDOUT:   %HasF.ref: type = name_ref HasF, imports.%PackageA.HasF [template = constants.%HasF.type]
-// CHECK:STDOUT:   %F.ref: %F.assoc_type = name_ref F, imports.%PackageA.import_ref.5f1 [template = constants.%assoc0]
+// CHECK:STDOUT:   %F.ref: %HasF.assoc_type = name_ref F, imports.%PackageA.import_ref.566 [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0: %F.type.dbc = impl_witness_access constants.%impl_witness, element0 [template = constants.%F.857]
 // CHECK:STDOUT:   %F.call: init %empty_tuple.type = call %impl.elem0()
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(constants.%Self: %HasF.type) [from "package_a.carbon"] {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -535,12 +531,12 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %TestDF: %TestDF.type = struct_value () [template]
 // CHECK:STDOUT:   %HasF.type: type = facet_type <@HasF> [template]
 // CHECK:STDOUT:   %Self.cf3: %HasF.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %F.type.dbc: type = fn_type @F.1 [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %HasF.type, %F.type.dbc [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, imports.%PackageA.import_ref.13e [template]
+// CHECK:STDOUT:   %HasF.assoc_type: type = assoc_entity_type %HasF.type [template]
+// CHECK:STDOUT:   %assoc0: %HasF.assoc_type = assoc_entity element0, imports.%PackageA.import_ref.ab2 [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %HasG.type: type = facet_type <@HasG> [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (imports.%PackageB.import_ref.0cd) [template]
+// CHECK:STDOUT:   %F.type.dbc: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.type.394: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.1fc: %F.type.394 = struct_value () [template]
 // CHECK:STDOUT: }
@@ -559,7 +555,7 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %PackageB.import_ref.cab = import_ref PackageB//default, inst27 [no loc], unloaded
 // CHECK:STDOUT:   %PackageA.HasF: type = import_ref PackageA//default, HasF, loaded [template = constants.%HasF.type]
 // CHECK:STDOUT:   %PackageA.import_ref.28c = import_ref PackageA//default, inst15 [no loc], unloaded
-// CHECK:STDOUT:   %PackageA.import_ref.5f1: %F.assoc_type = import_ref PackageA//default, loc5_9, loaded [template = constants.%assoc0]
+// CHECK:STDOUT:   %PackageA.import_ref.566: %HasF.assoc_type = import_ref PackageA//default, loc5_9, loaded [template = constants.%assoc0]
 // CHECK:STDOUT:   %PackageA.F = import_ref PackageA//default, F, unloaded
 // CHECK:STDOUT:   %PackageA.import_ref.0e8 = import_ref PackageA//default, loc11_16, unloaded
 // CHECK:STDOUT:   %PackageA.import_ref.8f2: <witness> = import_ref PackageA//default, loc8_10, loaded [template = constants.%complete_type]
@@ -568,7 +564,7 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %PackageA.import_ref.e8c: type = import_ref PackageA//default, loc11_11, loaded [template = constants.%HasF.type]
 // CHECK:STDOUT:   %PackageB.import_ref.fa0 = import_ref PackageB//default, loc13_25, unloaded
 // CHECK:STDOUT:   %PackageB.import_ref.5d8 = import_ref PackageB//default, inst17 [no loc], unloaded
-// CHECK:STDOUT:   %PackageB.import_ref.c30 = import_ref PackageB//default, loc7_9, unloaded
+// CHECK:STDOUT:   %PackageB.import_ref.ed7 = import_ref PackageB//default, loc7_9, unloaded
 // CHECK:STDOUT:   %PackageB.G = import_ref PackageB//default, G, unloaded
 // CHECK:STDOUT:   %PackageB.import_ref.dfb: type = import_ref PackageB//default, loc13_14, loaded [template = constants.%C]
 // CHECK:STDOUT:   %PackageB.import_ref.cee586.1: type = import_ref PackageB//default, loc13_20, loaded [template = constants.%HasG.type]
@@ -604,14 +600,14 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: interface @HasF [from "package_a.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = imports.%PackageA.import_ref.28c
-// CHECK:STDOUT:   .F = imports.%PackageA.import_ref.5f1
+// CHECK:STDOUT:   .F = imports.%PackageA.import_ref.566
 // CHECK:STDOUT:   witness = (imports.%PackageA.F)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @HasG [from "package_b.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = imports.%PackageB.import_ref.5d8
-// CHECK:STDOUT:   .G = imports.%PackageB.import_ref.c30
+// CHECK:STDOUT:   .G = imports.%PackageB.import_ref.ed7
 // CHECK:STDOUT:   witness = (imports.%PackageB.G)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -654,14 +650,13 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %d.ref: %D = name_ref d, %d
 // CHECK:STDOUT:   %PackageA.ref: <namespace> = name_ref PackageA, imports.%PackageA [template = imports.%PackageA]
 // CHECK:STDOUT:   %HasF.ref: type = name_ref HasF, imports.%PackageA.HasF [template = constants.%HasF.type]
-// CHECK:STDOUT:   %F.ref: %F.assoc_type = name_ref F, imports.%PackageA.import_ref.5f1 [template = constants.%assoc0]
+// CHECK:STDOUT:   %F.ref: %HasF.assoc_type = name_ref F, imports.%PackageA.import_ref.566 [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0: %F.type.dbc = impl_witness_access constants.%impl_witness, element0 [template = constants.%F.1fc]
 // CHECK:STDOUT:   %F.call: init %empty_tuple.type = call %impl.elem0()
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(constants.%Self.cf3: %HasF.type) [from "package_a.carbon"] {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -680,12 +675,12 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %TestCG: %TestCG.type = struct_value () [template]
 // CHECK:STDOUT:   %HasG.type: type = facet_type <@HasG> [template]
 // CHECK:STDOUT:   %Self.fcb: %HasG.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %G.type.d9e: type = fn_type @G.1 [template]
-// CHECK:STDOUT:   %G.assoc_type: type = assoc_entity_type %HasG.type, %G.type.d9e [template]
-// CHECK:STDOUT:   %assoc0: %G.assoc_type = assoc_entity element0, imports.%PackageB.import_ref.d9c [template]
+// CHECK:STDOUT:   %HasG.assoc_type: type = assoc_entity_type %HasG.type [template]
+// CHECK:STDOUT:   %assoc0: %HasG.assoc_type = assoc_entity element0, imports.%PackageB.import_ref.70a [template]
 // CHECK:STDOUT:   %HasF.type: type = facet_type <@HasF> [template]
 // CHECK:STDOUT:   %D: type = class_type @D [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (imports.%PackageB.import_ref.9ec) [template]
+// CHECK:STDOUT:   %G.type.d9e: type = fn_type @G.1 [template]
 // CHECK:STDOUT:   %G.type.18e: type = fn_type @G.2 [template]
 // CHECK:STDOUT:   %G.dbb: %G.type.18e = struct_value () [template]
 // CHECK:STDOUT: }
@@ -704,11 +699,11 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %PackageA.import_ref.2c4 = import_ref PackageA//default, inst25 [no loc], unloaded
 // CHECK:STDOUT:   %PackageB.HasG: type = import_ref PackageB//default, HasG, loaded [template = constants.%HasG.type]
 // CHECK:STDOUT:   %PackageB.import_ref.5d8 = import_ref PackageB//default, inst17 [no loc], unloaded
-// CHECK:STDOUT:   %PackageB.import_ref.d8a: %G.assoc_type = import_ref PackageB//default, loc7_9, loaded [template = constants.%assoc0]
+// CHECK:STDOUT:   %PackageB.import_ref.604: %HasG.assoc_type = import_ref PackageB//default, loc7_9, loaded [template = constants.%assoc0]
 // CHECK:STDOUT:   %PackageB.G = import_ref PackageB//default, G, unloaded
 // CHECK:STDOUT:   %PackageA.import_ref.0e8 = import_ref PackageA//default, loc11_16, unloaded
 // CHECK:STDOUT:   %PackageA.import_ref.28c = import_ref PackageA//default, inst15 [no loc], unloaded
-// CHECK:STDOUT:   %PackageA.import_ref.798 = import_ref PackageA//default, loc5_9, unloaded
+// CHECK:STDOUT:   %PackageA.import_ref.a2a = import_ref PackageA//default, loc5_9, unloaded
 // CHECK:STDOUT:   %PackageA.F = import_ref PackageA//default, F, unloaded
 // CHECK:STDOUT:   %PackageA.import_ref.29a: type = import_ref PackageA//default, loc11_6, loaded [template = constants.%C]
 // CHECK:STDOUT:   %PackageA.import_ref.e8c: type = import_ref PackageA//default, loc11_11, loaded [template = constants.%HasF.type]
@@ -749,14 +744,14 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: interface @HasG [from "package_b.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = imports.%PackageB.import_ref.5d8
-// CHECK:STDOUT:   .G = imports.%PackageB.import_ref.d8a
+// CHECK:STDOUT:   .G = imports.%PackageB.import_ref.604
 // CHECK:STDOUT:   witness = (imports.%PackageB.G)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @HasF [from "package_a.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = imports.%PackageA.import_ref.28c
-// CHECK:STDOUT:   .F = imports.%PackageA.import_ref.798
+// CHECK:STDOUT:   .F = imports.%PackageA.import_ref.a2a
 // CHECK:STDOUT:   witness = (imports.%PackageA.F)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -799,14 +794,13 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %c.ref: %C = name_ref c, %c
 // CHECK:STDOUT:   %PackageB.ref: <namespace> = name_ref PackageB, imports.%PackageB [template = imports.%PackageB]
 // CHECK:STDOUT:   %HasG.ref: type = name_ref HasG, imports.%PackageB.HasG [template = constants.%HasG.type]
-// CHECK:STDOUT:   %G.ref: %G.assoc_type = name_ref G, imports.%PackageB.import_ref.d8a [template = constants.%assoc0]
+// CHECK:STDOUT:   %G.ref: %HasG.assoc_type = name_ref G, imports.%PackageB.import_ref.604 [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0: %G.type.d9e = impl_witness_access constants.%impl_witness, element0 [template = constants.%G.dbb]
 // CHECK:STDOUT:   %G.call: init %empty_tuple.type = call %impl.elem0()
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @G.1(constants.%Self.fcb: %HasG.type) [from "package_b.carbon"] {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -825,12 +819,12 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %TestDG: %TestDG.type = struct_value () [template]
 // CHECK:STDOUT:   %HasG.type: type = facet_type <@HasG> [template]
 // CHECK:STDOUT:   %Self.fcb: %HasG.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %G.type.d9e: type = fn_type @G.1 [template]
-// CHECK:STDOUT:   %G.assoc_type: type = assoc_entity_type %HasG.type, %G.type.d9e [template]
-// CHECK:STDOUT:   %assoc0: %G.assoc_type = assoc_entity element0, imports.%PackageB.import_ref.d9c [template]
+// CHECK:STDOUT:   %HasG.assoc_type: type = assoc_entity_type %HasG.type [template]
+// CHECK:STDOUT:   %assoc0: %HasG.assoc_type = assoc_entity element0, imports.%PackageB.import_ref.70a [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %HasF.type: type = facet_type <@HasF> [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (imports.%PackageB.import_ref.b0a) [template]
+// CHECK:STDOUT:   %G.type.d9e: type = fn_type @G.1 [template]
 // CHECK:STDOUT:   %G.type.405: type = fn_type @G.2 [template]
 // CHECK:STDOUT:   %G.703: %G.type.405 = struct_value () [template]
 // CHECK:STDOUT: }
@@ -846,7 +840,7 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %PackageB.import_ref.cab = import_ref PackageB//default, inst27 [no loc], unloaded
 // CHECK:STDOUT:   %PackageB.HasG: type = import_ref PackageB//default, HasG, loaded [template = constants.%HasG.type]
 // CHECK:STDOUT:   %PackageB.import_ref.5d8 = import_ref PackageB//default, inst17 [no loc], unloaded
-// CHECK:STDOUT:   %PackageB.import_ref.d8a: %G.assoc_type = import_ref PackageB//default, loc7_9, loaded [template = constants.%assoc0]
+// CHECK:STDOUT:   %PackageB.import_ref.604: %HasG.assoc_type = import_ref PackageB//default, loc7_9, loaded [template = constants.%assoc0]
 // CHECK:STDOUT:   %PackageB.G = import_ref PackageB//default, G, unloaded
 // CHECK:STDOUT:   %PackageB.import_ref.fa0 = import_ref PackageB//default, loc13_25, unloaded
 // CHECK:STDOUT:   %PackageB.import_ref.8db: <witness> = import_ref PackageB//default, inst35 [indirect], loaded [template = constants.%complete_type]
@@ -855,7 +849,7 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %PackageB.import_ref.cee586.1: type = import_ref PackageB//default, loc13_20, loaded [template = constants.%HasG.type]
 // CHECK:STDOUT:   %PackageB.import_ref.7db = import_ref PackageB//default, loc18_25, unloaded
 // CHECK:STDOUT:   %PackageB.import_ref.96f = import_ref PackageB//default, inst53 [indirect], unloaded
-// CHECK:STDOUT:   %PackageB.import_ref.e4b = import_ref PackageB//default, inst54 [indirect], unloaded
+// CHECK:STDOUT:   %PackageB.import_ref.b30 = import_ref PackageB//default, inst54 [indirect], unloaded
 // CHECK:STDOUT:   %PackageB.F = import_ref PackageB//default, F, unloaded
 // CHECK:STDOUT:   %PackageB.import_ref.aa9f8a.1: type = import_ref PackageB//default, loc18_6, loaded [template = constants.%D]
 // CHECK:STDOUT:   %PackageB.import_ref.831: type = import_ref PackageB//default, loc18_19, loaded [template = constants.%HasF.type]
@@ -886,14 +880,14 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: interface @HasG [from "package_b.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = imports.%PackageB.import_ref.5d8
-// CHECK:STDOUT:   .G = imports.%PackageB.import_ref.d8a
+// CHECK:STDOUT:   .G = imports.%PackageB.import_ref.604
 // CHECK:STDOUT:   witness = (imports.%PackageB.G)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @HasF [from "package_b.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = imports.%PackageB.import_ref.96f
-// CHECK:STDOUT:   .F = imports.%PackageB.import_ref.e4b
+// CHECK:STDOUT:   .F = imports.%PackageB.import_ref.b30
 // CHECK:STDOUT:   witness = (imports.%PackageB.F)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -931,14 +925,13 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %d.ref: %D = name_ref d, %d
 // CHECK:STDOUT:   %PackageB.ref.loc7: <namespace> = name_ref PackageB, imports.%PackageB [template = imports.%PackageB]
 // CHECK:STDOUT:   %HasG.ref: type = name_ref HasG, imports.%PackageB.HasG [template = constants.%HasG.type]
-// CHECK:STDOUT:   %G.ref: %G.assoc_type = name_ref G, imports.%PackageB.import_ref.d8a [template = constants.%assoc0]
+// CHECK:STDOUT:   %G.ref: %HasG.assoc_type = name_ref G, imports.%PackageB.import_ref.604 [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0: %G.type.d9e = impl_witness_access constants.%impl_witness, element0 [template = constants.%G.703]
 // CHECK:STDOUT:   %G.call: init %empty_tuple.type = call %impl.elem0()
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @G.1(constants.%Self.fcb: %HasG.type) [from "package_b.carbon"] {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -954,8 +947,8 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %H.type.474: type = fn_type @H.1 [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %H.c1d: %H.type.474 = struct_value () [template]
-// CHECK:STDOUT:   %H.assoc_type: type = assoc_entity_type %Z.type, %H.type.474 [template]
-// CHECK:STDOUT:   %assoc0: %H.assoc_type = assoc_entity element0, @Z.%H.decl [template]
+// CHECK:STDOUT:   %Z.assoc_type: type = assoc_entity_type %Z.type [template]
+// CHECK:STDOUT:   %assoc0: %Z.assoc_type = assoc_entity element0, @Z.%H.decl [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (@impl.%H.decl) [template]
 // CHECK:STDOUT:   %H.type.707: type = fn_type @H.2 [template]
 // CHECK:STDOUT:   %H.8d7: %H.type.707 = struct_value () [template]
@@ -978,7 +971,7 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: interface @Z {
 // CHECK:STDOUT:   %Self: %Z.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %H.decl: %H.type.474 = fn_decl @H.1 [template = constants.%H.c1d] {} {}
-// CHECK:STDOUT:   %assoc0: %H.assoc_type = assoc_entity element0, %H.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %Z.assoc_type = assoc_entity element0, %H.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -995,7 +988,6 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @H.1(@Z.%Self: %Z.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -1016,10 +1008,10 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %J: %J.type = struct_value () [template]
 // CHECK:STDOUT:   %Z.type: type = facet_type <@Z> [template]
 // CHECK:STDOUT:   %Self: %Z.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %H.type.386: type = fn_type @H.1 [template]
-// CHECK:STDOUT:   %H.assoc_type: type = assoc_entity_type %Z.type, %H.type.386 [template]
-// CHECK:STDOUT:   %assoc0: %H.assoc_type = assoc_entity element0, imports.%PackageAssociatedInterface.import_ref.d97 [template]
+// CHECK:STDOUT:   %Z.assoc_type: type = assoc_entity_type %Z.type [template]
+// CHECK:STDOUT:   %assoc0: %Z.assoc_type = assoc_entity element0, imports.%PackageAssociatedInterface.import_ref.250 [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (imports.%PackageAssociatedInterface.import_ref.6d7) [template]
+// CHECK:STDOUT:   %H.type.386: type = fn_type @H.1 [template]
 // CHECK:STDOUT:   %H.type.ab3: type = fn_type @H.2 [template]
 // CHECK:STDOUT:   %H.c25: %H.type.ab3 = struct_value () [template]
 // CHECK:STDOUT: }
@@ -1031,7 +1023,7 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %PackageAssociatedInterface.Z: type = import_ref PackageAssociatedInterface//default, Z, loaded [template = constants.%Z.type]
 // CHECK:STDOUT:   %PackageAssociatedInterface.import_ref.f88 = import_ref PackageAssociatedInterface//default, inst15 [no loc], unloaded
-// CHECK:STDOUT:   %PackageAssociatedInterface.import_ref.150: %H.assoc_type = import_ref PackageAssociatedInterface//default, loc5_9, loaded [template = constants.%assoc0]
+// CHECK:STDOUT:   %PackageAssociatedInterface.import_ref.ddc: %Z.assoc_type = import_ref PackageAssociatedInterface//default, loc5_9, loaded [template = constants.%assoc0]
 // CHECK:STDOUT:   %PackageAssociatedInterface.H = import_ref PackageAssociatedInterface//default, H, unloaded
 // CHECK:STDOUT:   %PackageAssociatedInterface.import_ref.998: <witness> = import_ref PackageAssociatedInterface//default, loc8_14, loaded [template = constants.%impl_witness]
 // CHECK:STDOUT:   %PackageAssociatedInterface.import_ref.e5c: type = import_ref PackageAssociatedInterface//default, loc8_7, loaded [template = constants.%empty_tuple.type]
@@ -1050,7 +1042,7 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: interface @Z [from "associated_interface.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = imports.%PackageAssociatedInterface.import_ref.f88
-// CHECK:STDOUT:   .H = imports.%PackageAssociatedInterface.import_ref.150
+// CHECK:STDOUT:   .H = imports.%PackageAssociatedInterface.import_ref.ddc
 // CHECK:STDOUT:   witness = (imports.%PackageAssociatedInterface.H)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -1064,14 +1056,13 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %.loc7: %empty_tuple.type = tuple_literal ()
 // CHECK:STDOUT:   %PackageAssociatedInterface.ref: <namespace> = name_ref PackageAssociatedInterface, imports.%PackageAssociatedInterface [template = imports.%PackageAssociatedInterface]
 // CHECK:STDOUT:   %Z.ref: type = name_ref Z, imports.%PackageAssociatedInterface.Z [template = constants.%Z.type]
-// CHECK:STDOUT:   %H.ref: %H.assoc_type = name_ref H, imports.%PackageAssociatedInterface.import_ref.150 [template = constants.%assoc0]
+// CHECK:STDOUT:   %H.ref: %Z.assoc_type = name_ref H, imports.%PackageAssociatedInterface.import_ref.ddc [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0: %H.type.386 = impl_witness_access constants.%impl_witness, element0 [template = constants.%H.c25]
 // CHECK:STDOUT:   %H.call: init %empty_tuple.type = call %impl.elem0()
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @H.1(constants.%Self: %Z.type) [from "associated_interface.carbon"] {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -1095,8 +1086,8 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %Self: %Y.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %K.type: type = fn_type @K [template]
 // CHECK:STDOUT:   %K: %K.type = struct_value () [template]
-// CHECK:STDOUT:   %K.assoc_type: type = assoc_entity_type %Y.type, %K.type [template]
-// CHECK:STDOUT:   %assoc0: %K.assoc_type = assoc_entity element0, @Y.%K.decl [template]
+// CHECK:STDOUT:   %Y.assoc_type: type = assoc_entity_type %Y.type [template]
+// CHECK:STDOUT:   %assoc0: %Y.assoc_type = assoc_entity element0, @Y.%K.decl [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -1122,7 +1113,7 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: interface @Y {
 // CHECK:STDOUT:   %Self: %Y.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %K.decl: %K.type = fn_decl @K [template = constants.%K] {} {}
-// CHECK:STDOUT:   %assoc0: %K.assoc_type = assoc_entity element0, %K.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %Y.assoc_type = assoc_entity element0, %K.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -1195,8 +1186,8 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %L.type: type = fn_type @L [template]
 // CHECK:STDOUT:   %L: %L.type = struct_value () [template]
 // CHECK:STDOUT:   %AnyParam.val: %AnyParam.241 = struct_value () [template]
-// CHECK:STDOUT:   %K.assoc_type: type = assoc_entity_type %Y.type, %K.type.311 [template]
-// CHECK:STDOUT:   %assoc0: %K.assoc_type = assoc_entity element0, imports.%PackageHasParam.import_ref.d37 [template]
+// CHECK:STDOUT:   %Y.assoc_type: type = assoc_entity_type %Y.type [template]
+// CHECK:STDOUT:   %assoc0: %Y.assoc_type = assoc_entity element0, imports.%PackageHasParam.import_ref.ce2 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -1210,7 +1201,7 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %PackageHasParam.import_ref.601 = import_ref PackageHasParam//default, inst34 [no loc], unloaded
 // CHECK:STDOUT:   %PackageHasParam.Y: type = import_ref PackageHasParam//default, Y, loaded [template = constants.%Y.type]
 // CHECK:STDOUT:   %PackageHasParam.import_ref.dc1 = import_ref PackageHasParam//default, inst40 [no loc], unloaded
-// CHECK:STDOUT:   %PackageHasParam.import_ref.df6: %K.assoc_type = import_ref PackageHasParam//default, loc7_10, loaded [template = constants.%assoc0]
+// CHECK:STDOUT:   %PackageHasParam.import_ref.5e7: %Y.assoc_type = import_ref PackageHasParam//default, loc7_10, loaded [template = constants.%assoc0]
 // CHECK:STDOUT:   %PackageHasParam.K: %K.type.311 = import_ref PackageHasParam//default, K, loaded [template = constants.%K.7a1]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -1260,7 +1251,7 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: interface @Y [from "has_param.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = imports.%PackageHasParam.import_ref.dc1
-// CHECK:STDOUT:   .K = imports.%PackageHasParam.import_ref.df6
+// CHECK:STDOUT:   .K = imports.%PackageHasParam.import_ref.5e7
 // CHECK:STDOUT:   witness = (imports.%PackageHasParam.K)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -1320,7 +1311,7 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %obj.ref: ref %AnyParam.241 = name_ref obj, %obj
 // CHECK:STDOUT:   %PackageHasParam.ref.loc14: <namespace> = name_ref PackageHasParam, imports.%PackageHasParam [template = imports.%PackageHasParam]
 // CHECK:STDOUT:   %Y.ref: type = name_ref Y, imports.%PackageHasParam.Y [template = constants.%Y.type]
-// CHECK:STDOUT:   %K.ref: %K.assoc_type = name_ref K, imports.%PackageHasParam.import_ref.df6 [template = constants.%assoc0]
+// CHECK:STDOUT:   %K.ref: %Y.assoc_type = name_ref K, imports.%PackageHasParam.import_ref.5e7 [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0: %K.type.311 = impl_witness_access constants.%impl_witness, element0 [template = constants.%K.2e9]
 // CHECK:STDOUT:   %K.call: init %empty_tuple.type = call %impl.elem0()
 // CHECK:STDOUT:   return
@@ -1377,10 +1368,10 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %AnyParam.val: %AnyParam.861 = struct_value () [template]
 // CHECK:STDOUT:   %Y.type: type = facet_type <@Y> [template]
 // CHECK:STDOUT:   %Self.f64: %Y.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %K.type.311: type = fn_type @K.1 [template]
-// CHECK:STDOUT:   %K.assoc_type: type = assoc_entity_type %Y.type, %K.type.311 [template]
-// CHECK:STDOUT:   %assoc0: %K.assoc_type = assoc_entity element0, imports.%PackageHasParam.import_ref.d37 [template]
+// CHECK:STDOUT:   %Y.assoc_type: type = assoc_entity_type %Y.type [template]
+// CHECK:STDOUT:   %assoc0: %Y.assoc_type = assoc_entity element0, imports.%PackageHasParam.import_ref.ce2 [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (imports.%PackageGenericInterface.import_ref.456) [template]
+// CHECK:STDOUT:   %K.type.311: type = fn_type @K.1 [template]
 // CHECK:STDOUT:   %K.type.7f9: type = fn_type @K.2 [template]
 // CHECK:STDOUT:   %K.c3c: %K.type.7f9 = struct_value () [template]
 // CHECK:STDOUT: }
@@ -1402,7 +1393,7 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %PackageGenericInterface.import_ref.c3b = import_ref PackageGenericInterface//default, inst28 [no loc], unloaded
 // CHECK:STDOUT:   %PackageHasParam.Y: type = import_ref PackageHasParam//default, Y, loaded [template = constants.%Y.type]
 // CHECK:STDOUT:   %PackageHasParam.import_ref.dc1 = import_ref PackageHasParam//default, inst40 [no loc], unloaded
-// CHECK:STDOUT:   %PackageHasParam.import_ref.df6: %K.assoc_type = import_ref PackageHasParam//default, loc7_10, loaded [template = constants.%assoc0]
+// CHECK:STDOUT:   %PackageHasParam.import_ref.5e7: %Y.assoc_type = import_ref PackageHasParam//default, loc7_10, loaded [template = constants.%assoc0]
 // CHECK:STDOUT:   %PackageHasParam.K = import_ref PackageHasParam//default, K, unloaded
 // CHECK:STDOUT:   %PackageGenericInterface.import_ref.ca8: <witness> = import_ref PackageGenericInterface//default, loc8_70, loaded [template = constants.%impl_witness]
 // CHECK:STDOUT:   %PackageGenericInterface.import_ref.321: type = import_ref PackageGenericInterface//default, loc8_47, loaded [template = constants.%AnyParam.861]
@@ -1438,7 +1429,7 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: interface @Y [from "has_param.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = imports.%PackageHasParam.import_ref.dc1
-// CHECK:STDOUT:   .K = imports.%PackageHasParam.import_ref.df6
+// CHECK:STDOUT:   .K = imports.%PackageHasParam.import_ref.5e7
 // CHECK:STDOUT:   witness = (imports.%PackageHasParam.K)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -1485,7 +1476,7 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %obj.ref: ref %AnyParam.861 = name_ref obj, %obj
 // CHECK:STDOUT:   %PackageHasParam.ref.loc10: <namespace> = name_ref PackageHasParam, imports.%PackageHasParam [template = imports.%PackageHasParam]
 // CHECK:STDOUT:   %Y.ref: type = name_ref Y, imports.%PackageHasParam.Y [template = constants.%Y.type]
-// CHECK:STDOUT:   %K.ref: %K.assoc_type = name_ref K, imports.%PackageHasParam.import_ref.df6 [template = constants.%assoc0]
+// CHECK:STDOUT:   %K.ref: %Y.assoc_type = name_ref K, imports.%PackageHasParam.import_ref.5e7 [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0: %K.type.311 = impl_witness_access constants.%impl_witness, element0 [template = constants.%K.c3c]
 // CHECK:STDOUT:   %K.call: init %empty_tuple.type = call %impl.elem0()
 // CHECK:STDOUT:   return
@@ -1554,8 +1545,8 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %F.type.cf0: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.bc6: %F.type.cf0 = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %I.type, %F.type.cf0 [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @I.%F.decl [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @I.%F.decl [template]
 // CHECK:STDOUT:   %tuple.type.c53: type = tuple_type (type, type, type, type, type, type, type, type) [template]
 // CHECK:STDOUT:   %tuple.type.15d: type = tuple_type (%Extra1.type, %Extra2.type, %Extra3.type, %Extra4.type, %Extra5.type, %Extra6.type, %Extra7.type, %Extra8.type) [template]
 // CHECK:STDOUT:   %C.69b: type = class_type @C, @C(%tuple.type.15d) [template]
@@ -1679,7 +1670,7 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826]
 // CHECK:STDOUT:   %F.decl: %F.type.cf0 = fn_decl @F.1 [template = constants.%F.bc6] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -1711,7 +1702,6 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(@I.%Self: %I.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -1747,10 +1737,8 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %Test.type: type = fn_type @Test [template]
 // CHECK:STDOUT:   %Test: %Test.type = struct_value () [template]
 // CHECK:STDOUT:   %I.type: type = facet_type <@I> [template]
-// CHECK:STDOUT:   %Self.013: %I.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %F.type: type = fn_type @F [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %I.type, %F.type [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, imports.%HasExtraInterfaces.import_ref.777 [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, imports.%HasExtraInterfaces.import_ref.777 [template]
 // CHECK:STDOUT:   %Extra8.type: type = facet_type <@Extra8> [template]
 // CHECK:STDOUT:   %Extra7.type: type = facet_type <@Extra7> [template]
 // CHECK:STDOUT:   %Extra6.type: type = facet_type <@Extra6> [template]
@@ -1774,7 +1762,7 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %HasExtraInterfaces.import_ref.4c0 = import_ref HasExtraInterfaces//default, inst57 [no loc], unloaded
 // CHECK:STDOUT:   %HasExtraInterfaces.I: type = import_ref HasExtraInterfaces//default, I, loaded [template = constants.%I.type]
 // CHECK:STDOUT:   %HasExtraInterfaces.import_ref.e5d = import_ref HasExtraInterfaces//default, inst63 [no loc], unloaded
-// CHECK:STDOUT:   %HasExtraInterfaces.import_ref.fd4: %F.assoc_type = import_ref HasExtraInterfaces//default, loc14_21, loaded [template = constants.%assoc0]
+// CHECK:STDOUT:   %HasExtraInterfaces.import_ref.9cd: %I.assoc_type = import_ref HasExtraInterfaces//default, loc14_21, loaded [template = constants.%assoc0]
 // CHECK:STDOUT:   %HasExtraInterfaces.F = import_ref HasExtraInterfaces//default, F, unloaded
 // CHECK:STDOUT:   %HasExtraInterfaces.import_ref.1c8 = import_ref HasExtraInterfaces//default, loc16_79, unloaded
 // CHECK:STDOUT:   %HasExtraInterfaces.import_ref.9c8 = import_ref HasExtraInterfaces//default, inst43 [no loc], unloaded
@@ -1812,7 +1800,7 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: interface @I [from "has_extra_interfaces.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = imports.%HasExtraInterfaces.import_ref.e5d
-// CHECK:STDOUT:   .F = imports.%HasExtraInterfaces.import_ref.fd4
+// CHECK:STDOUT:   .F = imports.%HasExtraInterfaces.import_ref.9cd
 // CHECK:STDOUT:   witness = (imports.%HasExtraInterfaces.F)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -1888,15 +1876,10 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT:   %c.ref: %C.42e = name_ref c, %c
 // CHECK:STDOUT:   %HasExtraInterfaces.ref.loc12: <namespace> = name_ref HasExtraInterfaces, imports.%HasExtraInterfaces [template = imports.%HasExtraInterfaces]
 // CHECK:STDOUT:   %I.ref: type = name_ref I, imports.%HasExtraInterfaces.I [template = constants.%I.type]
-// CHECK:STDOUT:   %F.ref: %F.assoc_type = name_ref F, imports.%HasExtraInterfaces.import_ref.fd4 [template = constants.%assoc0]
+// CHECK:STDOUT:   %F.ref: %I.assoc_type = name_ref F, imports.%HasExtraInterfaces.import_ref.9cd [template = constants.%assoc0]
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: generic fn @F(constants.%Self.013: %I.type) [from "has_extra_interfaces.carbon"] {
-// CHECK:STDOUT:
-// CHECK:STDOUT:   fn();
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
 // CHECK:STDOUT: specific @C(constants.%T) {
 // CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT:   %T.patt => constants.%T
@@ -1909,8 +1892,6 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @F(constants.%Self.013) {}
-// CHECK:STDOUT:
 // CHECK:STDOUT: specific @C(constants.%tuple.type) {
 // CHECK:STDOUT:   %T => constants.%tuple.type
 // CHECK:STDOUT:   %T.patt => constants.%tuple.type

+ 53 - 58
toolchain/check/testdata/impl/lookup/no_prelude/specific_args.carbon

@@ -62,8 +62,8 @@ fn H(c: C(InClassArgs)) { c.(I(X).F)(); }
 // CHECK:STDOUT:   %Self: %I.type.325 = bind_symbolic_name Self, 1 [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F, @I(%T) [symbolic]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [symbolic]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %I.type.325, %F.type [symbolic]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @I.%F.decl [symbolic]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type.325 [symbolic]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @I.%F.decl [symbolic]
 // CHECK:STDOUT:   %C.type: type = generic_class_type @C [template]
 // CHECK:STDOUT:   %C.generic: %C.type = struct_value () [template]
 // CHECK:STDOUT:   %C: type = class_type @C, @C(%T) [symbolic]
@@ -104,13 +104,13 @@ fn H(c: C(InClassArgs)) { c.(I(X).F)(); }
 // CHECK:STDOUT:   %Self.2: %I.type.325 = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
 // CHECK:STDOUT:   %F.type: type = fn_type @F, @I(%T.loc4_13.2) [symbolic = %F.type (constants.%F.type)]
 // CHECK:STDOUT:   %F: @I.%F.type (%F.type) = struct_value () [symbolic = %F (constants.%F)]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type @I.%I.type (%I.type.325), @I.%F.type (%F.type) [symbolic = %F.assoc_type (constants.%F.assoc_type)]
-// CHECK:STDOUT:   %assoc0.loc4_31.2: @I.%F.assoc_type (%F.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc4_31.2 (constants.%assoc0)]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type @I.%I.type (%I.type.325) [symbolic = %I.assoc_type (constants.%I.assoc_type)]
+// CHECK:STDOUT:   %assoc0.loc4_31.2: @I.%I.assoc_type (%I.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc4_31.2 (constants.%assoc0)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:     %Self.1: @I.%I.type (%I.type.325) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
 // CHECK:STDOUT:     %F.decl: @I.%F.type (%F.type) = fn_decl @F [symbolic = @I.%F (constants.%F)] {} {}
-// CHECK:STDOUT:     %assoc0.loc4_31.1: @I.%F.assoc_type (%F.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc4_31.2 (constants.%assoc0)]
+// CHECK:STDOUT:     %assoc0.loc4_31.1: @I.%I.assoc_type (%I.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc4_31.2 (constants.%assoc0)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = %Self.1
@@ -143,7 +143,6 @@ fn H(c: C(InClassArgs)) { c.(I(X).F)(); }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(@I.%T.loc4_13.1: type, @I.%Self.1: @I.%I.type (%I.type.325)) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -176,13 +175,13 @@ fn H(c: C(InClassArgs)) { c.(I(X).F)(); }
 // CHECK:STDOUT:   %T.patt: type = symbolic_binding_pattern T, 0 [symbolic]
 // CHECK:STDOUT:   %F.type.2ae: type = fn_type @F.1, @I(%T) [symbolic]
 // CHECK:STDOUT:   %F.bb2: %F.type.2ae = struct_value () [symbolic]
-// CHECK:STDOUT:   %F.assoc_type.003: type = assoc_entity_type %I.type.325, %F.type.2ae [symbolic]
-// CHECK:STDOUT:   %assoc0.ed5: %F.assoc_type.003 = assoc_entity element0, imports.%Main.import_ref.479 [symbolic]
+// CHECK:STDOUT:   %I.assoc_type.955: type = assoc_entity_type %I.type.325 [symbolic]
+// CHECK:STDOUT:   %assoc0.249: %I.assoc_type.955 = assoc_entity element0, imports.%Main.import_ref.479 [symbolic]
 // CHECK:STDOUT:   %I.type.e45: type = facet_type <@I, @I(%InInterfaceArgs)> [template]
 // CHECK:STDOUT:   %F.type.14f: type = fn_type @F.1, @I(%InInterfaceArgs) [template]
 // CHECK:STDOUT:   %F.b81: %F.type.14f = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type.992: type = assoc_entity_type %I.type.e45, %F.type.14f [template]
-// CHECK:STDOUT:   %assoc0.ad0: %F.assoc_type.992 = assoc_entity element0, imports.%Main.import_ref.479 [template]
+// CHECK:STDOUT:   %I.assoc_type.9f3: type = assoc_entity_type %I.type.e45 [template]
+// CHECK:STDOUT:   %assoc0.055: %I.assoc_type.9f3 = assoc_entity element0, imports.%Main.import_ref.479 [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (@impl.%F.decl) [template]
 // CHECK:STDOUT:   %F.type.b63: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.d5f: %F.type.b63 = struct_value () [template]
@@ -196,7 +195,7 @@ fn H(c: C(InClassArgs)) { c.(I(X).F)(); }
 // CHECK:STDOUT:   %Main.import_ref.8f2: <witness> = import_ref Main//types, loc7_10, loaded [template = constants.%complete_type]
 // CHECK:STDOUT:   %Main.import_ref.acf = import_ref Main//types, inst54 [no loc], unloaded
 // CHECK:STDOUT:   %Main.import_ref.884 = import_ref Main//types, inst26 [no loc], unloaded
-// CHECK:STDOUT:   %Main.import_ref.182 = import_ref Main//types, loc4_31, unloaded
+// CHECK:STDOUT:   %Main.import_ref.cbe = import_ref Main//types, loc4_31, unloaded
 // CHECK:STDOUT:   %Main.F: @I.%F.type (%F.type.2ae) = import_ref Main//types, F, loaded [symbolic = @I.%F (constants.%F.bb2)]
 // CHECK:STDOUT:   %Main.import_ref.479 = import_ref Main//types, loc4_31, unloaded
 // CHECK:STDOUT: }
@@ -228,13 +227,13 @@ fn H(c: C(InClassArgs)) { c.(I(X).F)(); }
 // CHECK:STDOUT:   %Self: %I.type.325 = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self)]
 // CHECK:STDOUT:   %F.type: type = fn_type @F.1, @I(%T) [symbolic = %F.type (constants.%F.type.2ae)]
 // CHECK:STDOUT:   %F: @I.%F.type (%F.type.2ae) = struct_value () [symbolic = %F (constants.%F.bb2)]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type @I.%I.type (%I.type.325), @I.%F.type (%F.type.2ae) [symbolic = %F.assoc_type (constants.%F.assoc_type.003)]
-// CHECK:STDOUT:   %assoc0: @I.%F.assoc_type (%F.assoc_type.003) = assoc_entity element0, imports.%Main.import_ref.479 [symbolic = %assoc0 (constants.%assoc0.ed5)]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type @I.%I.type (%I.type.325) [symbolic = %I.assoc_type (constants.%I.assoc_type.955)]
+// CHECK:STDOUT:   %assoc0: @I.%I.assoc_type (%I.assoc_type.955) = assoc_entity element0, imports.%Main.import_ref.479 [symbolic = %assoc0 (constants.%assoc0.249)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = imports.%Main.import_ref.884
-// CHECK:STDOUT:     .F = imports.%Main.import_ref.182
+// CHECK:STDOUT:     .F = imports.%Main.import_ref.cbe
 // CHECK:STDOUT:     witness = (imports.%Main.F)
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -263,7 +262,6 @@ fn H(c: C(InClassArgs)) { c.(I(X).F)(); }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(constants.%T: type, constants.%Self: %I.type.325) [from "types.carbon"] {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -290,8 +288,8 @@ fn H(c: C(InClassArgs)) { c.(I(X).F)(); }
 // CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT:   %F.type => constants.%F.type.14f
 // CHECK:STDOUT:   %F => constants.%F.b81
-// CHECK:STDOUT:   %F.assoc_type => constants.%F.assoc_type.992
-// CHECK:STDOUT:   %assoc0 => constants.%assoc0.ad0
+// CHECK:STDOUT:   %I.assoc_type => constants.%I.assoc_type.9f3
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.055
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F.1(constants.%InInterfaceArgs, constants.%I.facet) {}
@@ -313,15 +311,15 @@ fn H(c: C(InClassArgs)) { c.(I(X).F)(); }
 // CHECK:STDOUT:   %T.patt: type = symbolic_binding_pattern T, 0 [symbolic]
 // CHECK:STDOUT:   %F.type.2ae: type = fn_type @F.1, @I(%T) [symbolic]
 // CHECK:STDOUT:   %F.bb2: %F.type.2ae = struct_value () [symbolic]
-// CHECK:STDOUT:   %F.assoc_type.003: type = assoc_entity_type %I.type.325, %F.type.2ae [symbolic]
-// CHECK:STDOUT:   %assoc0.ed59f4.1: %F.assoc_type.003 = assoc_entity element0, imports.%Main.import_ref.479b0f.1 [symbolic]
+// CHECK:STDOUT:   %I.assoc_type.955: type = assoc_entity_type %I.type.325 [symbolic]
+// CHECK:STDOUT:   %assoc0.62c: %I.assoc_type.955 = assoc_entity element0, imports.%Main.import_ref.e54 [symbolic]
 // CHECK:STDOUT:   %InInterfaceArgs: type = class_type @InInterfaceArgs [template]
 // CHECK:STDOUT:   %I.type.e45: type = facet_type <@I, @I(%InInterfaceArgs)> [template]
 // CHECK:STDOUT:   %F.type.14f: type = fn_type @F.1, @I(%InInterfaceArgs) [template]
 // CHECK:STDOUT:   %F.b81: %F.type.14f = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type.992: type = assoc_entity_type %I.type.e45, %F.type.14f [template]
-// CHECK:STDOUT:   %assoc0.ad0: %F.assoc_type.992 = assoc_entity element0, imports.%Main.import_ref.479b0f.1 [template]
-// CHECK:STDOUT:   %assoc0.ed59f4.2: %F.assoc_type.003 = assoc_entity element0, imports.%Main.import_ref.479b0f.2 [symbolic]
+// CHECK:STDOUT:   %I.assoc_type.9f3: type = assoc_entity_type %I.type.e45 [template]
+// CHECK:STDOUT:   %assoc0.0fc: %I.assoc_type.9f3 = assoc_entity element0, imports.%Main.import_ref.e54 [template]
+// CHECK:STDOUT:   %assoc0.249: %I.assoc_type.955 = assoc_entity element0, imports.%Main.import_ref.479 [symbolic]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (imports.%Main.import_ref.7f5) [template]
 // CHECK:STDOUT:   %F.type.b63: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.d5f: %F.type.b63 = struct_value () [template]
@@ -335,9 +333,9 @@ fn H(c: C(InClassArgs)) { c.(I(X).F)(); }
 // CHECK:STDOUT:   %Main.import_ref.8f24d3.1: <witness> = import_ref Main//types, loc7_10, loaded [template = constants.%complete_type]
 // CHECK:STDOUT:   %Main.import_ref.acf = import_ref Main//types, inst54 [no loc], unloaded
 // CHECK:STDOUT:   %Main.import_ref.884 = import_ref Main//types, inst26 [no loc], unloaded
-// CHECK:STDOUT:   %Main.import_ref.4ed: @I.%F.assoc_type (%F.assoc_type.003) = import_ref Main//types, loc4_31, loaded [symbolic = @I.%assoc0 (constants.%assoc0.ed59f4.2)]
+// CHECK:STDOUT:   %Main.import_ref.cd3: @I.%I.assoc_type (%I.assoc_type.955) = import_ref Main//types, loc4_31, loaded [symbolic = @I.%assoc0 (constants.%assoc0.249)]
 // CHECK:STDOUT:   %Main.F = import_ref Main//types, F, unloaded
-// CHECK:STDOUT:   %Main.import_ref.479b0f.1 = import_ref Main//types, loc4_31, unloaded
+// CHECK:STDOUT:   %Main.import_ref.e54: @I.%F.type (%F.type.2ae) = import_ref Main//types, loc4_31, loaded [symbolic = @I.%F (constants.%F.bb2)]
 // CHECK:STDOUT:   %Main.import_ref.8f24d3.2: <witness> = import_ref Main//impl_in_interface_args, loc5_24, loaded [template = constants.%complete_type]
 // CHECK:STDOUT:   %Main.import_ref.bf8 = import_ref Main//impl_in_interface_args, inst18 [no loc], unloaded
 // CHECK:STDOUT:   %Main.import_ref.f9f: <witness> = import_ref Main//impl_in_interface_args, loc7_30, loaded [template = constants.%impl_witness]
@@ -373,13 +371,13 @@ fn H(c: C(InClassArgs)) { c.(I(X).F)(); }
 // CHECK:STDOUT:   %Self: %I.type.325 = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self)]
 // CHECK:STDOUT:   %F.type: type = fn_type @F.1, @I(%T) [symbolic = %F.type (constants.%F.type.2ae)]
 // CHECK:STDOUT:   %F: @I.%F.type (%F.type.2ae) = struct_value () [symbolic = %F (constants.%F.bb2)]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type @I.%I.type (%I.type.325), @I.%F.type (%F.type.2ae) [symbolic = %F.assoc_type (constants.%F.assoc_type.003)]
-// CHECK:STDOUT:   %assoc0: @I.%F.assoc_type (%F.assoc_type.003) = assoc_entity element0, imports.%Main.import_ref.479b0f.1 [symbolic = %assoc0 (constants.%assoc0.ed59f4.1)]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type @I.%I.type (%I.type.325) [symbolic = %I.assoc_type (constants.%I.assoc_type.955)]
+// CHECK:STDOUT:   %assoc0: @I.%I.assoc_type (%I.assoc_type.955) = assoc_entity element0, imports.%Main.import_ref.e54 [symbolic = %assoc0 (constants.%assoc0.62c)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = imports.%Main.import_ref.884
-// CHECK:STDOUT:     .F = imports.%Main.import_ref.4ed
+// CHECK:STDOUT:     .F = imports.%Main.import_ref.cd3
 // CHECK:STDOUT:     witness = (imports.%Main.F)
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -409,15 +407,14 @@ fn H(c: C(InClassArgs)) { c.(I(X).F)(); }
 // CHECK:STDOUT:   %I.ref: %I.type.dac = name_ref I, imports.%Main.I [template = constants.%I.generic]
 // CHECK:STDOUT:   %InInterfaceArgs.ref: type = name_ref InInterfaceArgs, imports.%Main.InInterfaceArgs [template = constants.%InInterfaceArgs]
 // CHECK:STDOUT:   %I.type: type = facet_type <@I, @I(constants.%InInterfaceArgs)> [template = constants.%I.type.e45]
-// CHECK:STDOUT:   %.loc6: %F.assoc_type.992 = specific_constant imports.%Main.import_ref.4ed, @I(constants.%InInterfaceArgs) [template = constants.%assoc0.ad0]
-// CHECK:STDOUT:   %F.ref: %F.assoc_type.992 = name_ref F, %.loc6 [template = constants.%assoc0.ad0]
+// CHECK:STDOUT:   %.loc6: %I.assoc_type.9f3 = specific_constant imports.%Main.import_ref.cd3, @I(constants.%InInterfaceArgs) [template = constants.%assoc0.0fc]
+// CHECK:STDOUT:   %F.ref: %I.assoc_type.9f3 = name_ref F, %.loc6 [template = constants.%assoc0.0fc]
 // CHECK:STDOUT:   %impl.elem0: %F.type.14f = impl_witness_access constants.%impl_witness, element0 [template = constants.%F.d5f]
 // CHECK:STDOUT:   %F.call: init %empty_tuple.type = call %impl.elem0()
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(constants.%T: type, constants.%Self: %I.type.325) [from "types.carbon"] {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -441,8 +438,8 @@ fn H(c: C(InClassArgs)) { c.(I(X).F)(); }
 // CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT:   %F.type => constants.%F.type.14f
 // CHECK:STDOUT:   %F => constants.%F.b81
-// CHECK:STDOUT:   %F.assoc_type => constants.%F.assoc_type.992
-// CHECK:STDOUT:   %assoc0 => constants.%assoc0.ad0
+// CHECK:STDOUT:   %I.assoc_type => constants.%I.assoc_type.9f3
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.0fc
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- impl_in_class_args.carbon
@@ -462,14 +459,14 @@ fn H(c: C(InClassArgs)) { c.(I(X).F)(); }
 // CHECK:STDOUT:   %Self: %I.type.325 = bind_symbolic_name Self, 1 [symbolic]
 // CHECK:STDOUT:   %F.type.2ae: type = fn_type @F.1, @I(%T) [symbolic]
 // CHECK:STDOUT:   %F.bb2: %F.type.2ae = struct_value () [symbolic]
-// CHECK:STDOUT:   %F.assoc_type.003: type = assoc_entity_type %I.type.325, %F.type.2ae [symbolic]
-// CHECK:STDOUT:   %assoc0.ed5: %F.assoc_type.003 = assoc_entity element0, imports.%Main.import_ref.479 [symbolic]
+// CHECK:STDOUT:   %I.assoc_type.955: type = assoc_entity_type %I.type.325 [symbolic]
+// CHECK:STDOUT:   %assoc0.249: %I.assoc_type.955 = assoc_entity element0, imports.%Main.import_ref.479 [symbolic]
 // CHECK:STDOUT:   %X: type = class_type @X [template]
 // CHECK:STDOUT:   %I.type.45c: type = facet_type <@I, @I(%X)> [template]
 // CHECK:STDOUT:   %F.type.56a: type = fn_type @F.1, @I(%X) [template]
 // CHECK:STDOUT:   %F.a79: %F.type.56a = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type.2e0: type = assoc_entity_type %I.type.45c, %F.type.56a [template]
-// CHECK:STDOUT:   %assoc0.ef3: %F.assoc_type.2e0 = assoc_entity element0, imports.%Main.import_ref.479 [template]
+// CHECK:STDOUT:   %I.assoc_type.a7e: type = assoc_entity_type %I.type.45c [template]
+// CHECK:STDOUT:   %assoc0.7c6: %I.assoc_type.a7e = assoc_entity element0, imports.%Main.import_ref.479 [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (@impl.%F.decl) [template]
 // CHECK:STDOUT:   %F.type.fab: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.7ab: %F.type.fab = struct_value () [template]
@@ -483,7 +480,7 @@ fn H(c: C(InClassArgs)) { c.(I(X).F)(); }
 // CHECK:STDOUT:   %Main.import_ref.8f24d3.1: <witness> = import_ref Main//types, loc5_20, loaded [template = constants.%complete_type]
 // CHECK:STDOUT:   %Main.import_ref.4c0 = import_ref Main//types, inst49 [no loc], unloaded
 // CHECK:STDOUT:   %Main.import_ref.884 = import_ref Main//types, inst26 [no loc], unloaded
-// CHECK:STDOUT:   %Main.import_ref.182 = import_ref Main//types, loc4_31, unloaded
+// CHECK:STDOUT:   %Main.import_ref.cbe = import_ref Main//types, loc4_31, unloaded
 // CHECK:STDOUT:   %Main.F: @I.%F.type (%F.type.2ae) = import_ref Main//types, F, loaded [symbolic = @I.%F (constants.%F.bb2)]
 // CHECK:STDOUT:   %Main.import_ref.479 = import_ref Main//types, loc4_31, unloaded
 // CHECK:STDOUT:   %Main.import_ref.8f24d3.2: <witness> = import_ref Main//types, loc7_10, loaded [template = constants.%complete_type]
@@ -519,13 +516,13 @@ fn H(c: C(InClassArgs)) { c.(I(X).F)(); }
 // CHECK:STDOUT:   %Self: %I.type.325 = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self)]
 // CHECK:STDOUT:   %F.type: type = fn_type @F.1, @I(%T) [symbolic = %F.type (constants.%F.type.2ae)]
 // CHECK:STDOUT:   %F: @I.%F.type (%F.type.2ae) = struct_value () [symbolic = %F (constants.%F.bb2)]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type @I.%I.type (%I.type.325), @I.%F.type (%F.type.2ae) [symbolic = %F.assoc_type (constants.%F.assoc_type.003)]
-// CHECK:STDOUT:   %assoc0: @I.%F.assoc_type (%F.assoc_type.003) = assoc_entity element0, imports.%Main.import_ref.479 [symbolic = %assoc0 (constants.%assoc0.ed5)]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type @I.%I.type (%I.type.325) [symbolic = %I.assoc_type (constants.%I.assoc_type.955)]
+// CHECK:STDOUT:   %assoc0: @I.%I.assoc_type (%I.assoc_type.955) = assoc_entity element0, imports.%Main.import_ref.479 [symbolic = %assoc0 (constants.%assoc0.249)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = imports.%Main.import_ref.884
-// CHECK:STDOUT:     .F = imports.%Main.import_ref.182
+// CHECK:STDOUT:     .F = imports.%Main.import_ref.cbe
 // CHECK:STDOUT:     witness = (imports.%Main.F)
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -568,7 +565,6 @@ fn H(c: C(InClassArgs)) { c.(I(X).F)(); }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(constants.%T: type, constants.%Self: %I.type.325) [from "types.carbon"] {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -605,8 +601,8 @@ fn H(c: C(InClassArgs)) { c.(I(X).F)(); }
 // CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT:   %F.type => constants.%F.type.56a
 // CHECK:STDOUT:   %F => constants.%F.a79
-// CHECK:STDOUT:   %F.assoc_type => constants.%F.assoc_type.2e0
-// CHECK:STDOUT:   %assoc0 => constants.%assoc0.ef3
+// CHECK:STDOUT:   %I.assoc_type => constants.%I.assoc_type.a7e
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.7c6
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F.1(constants.%X, constants.%I.facet) {}
@@ -631,15 +627,15 @@ fn H(c: C(InClassArgs)) { c.(I(X).F)(); }
 // CHECK:STDOUT:   %Self: %I.type.325 = bind_symbolic_name Self, 1 [symbolic]
 // CHECK:STDOUT:   %F.type.2ae: type = fn_type @F.1, @I(%T) [symbolic]
 // CHECK:STDOUT:   %F.bb2: %F.type.2ae = struct_value () [symbolic]
-// CHECK:STDOUT:   %F.assoc_type.003: type = assoc_entity_type %I.type.325, %F.type.2ae [symbolic]
-// CHECK:STDOUT:   %assoc0.ed59f4.1: %F.assoc_type.003 = assoc_entity element0, imports.%Main.import_ref.479b0f.1 [symbolic]
+// CHECK:STDOUT:   %I.assoc_type.955: type = assoc_entity_type %I.type.325 [symbolic]
+// CHECK:STDOUT:   %assoc0.62c: %I.assoc_type.955 = assoc_entity element0, imports.%Main.import_ref.e54 [symbolic]
 // CHECK:STDOUT:   %X: type = class_type @X [template]
 // CHECK:STDOUT:   %I.type.45c: type = facet_type <@I, @I(%X)> [template]
 // CHECK:STDOUT:   %F.type.56a: type = fn_type @F.1, @I(%X) [template]
 // CHECK:STDOUT:   %F.a79: %F.type.56a = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type.2e0: type = assoc_entity_type %I.type.45c, %F.type.56a [template]
-// CHECK:STDOUT:   %assoc0.ef3: %F.assoc_type.2e0 = assoc_entity element0, imports.%Main.import_ref.479b0f.1 [template]
-// CHECK:STDOUT:   %assoc0.ed59f4.2: %F.assoc_type.003 = assoc_entity element0, imports.%Main.import_ref.479b0f.2 [symbolic]
+// CHECK:STDOUT:   %I.assoc_type.a7e: type = assoc_entity_type %I.type.45c [template]
+// CHECK:STDOUT:   %assoc0.ba0: %I.assoc_type.a7e = assoc_entity element0, imports.%Main.import_ref.e54 [template]
+// CHECK:STDOUT:   %assoc0.249: %I.assoc_type.955 = assoc_entity element0, imports.%Main.import_ref.479 [symbolic]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (imports.%Main.import_ref.ae4) [template]
 // CHECK:STDOUT:   %F.type.fab: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.7ab: %F.type.fab = struct_value () [template]
@@ -655,9 +651,9 @@ fn H(c: C(InClassArgs)) { c.(I(X).F)(); }
 // CHECK:STDOUT:   %Main.import_ref.8f24d3.2: <witness> = import_ref Main//impl_in_class_args, loc5_20, loaded [template = constants.%complete_type]
 // CHECK:STDOUT:   %Main.import_ref.683 = import_ref Main//impl_in_class_args, inst18 [no loc], unloaded
 // CHECK:STDOUT:   %Main.import_ref.884 = import_ref Main//types, inst26 [no loc], unloaded
-// CHECK:STDOUT:   %Main.import_ref.4ed: @I.%F.assoc_type (%F.assoc_type.003) = import_ref Main//types, loc4_31, loaded [symbolic = @I.%assoc0 (constants.%assoc0.ed59f4.2)]
+// CHECK:STDOUT:   %Main.import_ref.cd3: @I.%I.assoc_type (%I.assoc_type.955) = import_ref Main//types, loc4_31, loaded [symbolic = @I.%assoc0 (constants.%assoc0.249)]
 // CHECK:STDOUT:   %Main.F = import_ref Main//types, F, unloaded
-// CHECK:STDOUT:   %Main.import_ref.479b0f.1 = import_ref Main//types, loc4_31, unloaded
+// CHECK:STDOUT:   %Main.import_ref.e54: @I.%F.type (%F.type.2ae) = import_ref Main//types, loc4_31, loaded [symbolic = @I.%F (constants.%F.bb2)]
 // CHECK:STDOUT:   %Main.import_ref.8f24d3.3: <witness> = import_ref Main//types, loc7_10, loaded [template = constants.%complete_type]
 // CHECK:STDOUT:   %Main.import_ref.acf = import_ref Main//types, inst54 [no loc], unloaded
 // CHECK:STDOUT:   %Main.import_ref.6de: <witness> = import_ref Main//impl_in_class_args, loc7_29, loaded [template = constants.%impl_witness]
@@ -697,13 +693,13 @@ fn H(c: C(InClassArgs)) { c.(I(X).F)(); }
 // CHECK:STDOUT:   %Self: %I.type.325 = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self)]
 // CHECK:STDOUT:   %F.type: type = fn_type @F.1, @I(%T) [symbolic = %F.type (constants.%F.type.2ae)]
 // CHECK:STDOUT:   %F: @I.%F.type (%F.type.2ae) = struct_value () [symbolic = %F (constants.%F.bb2)]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type @I.%I.type (%I.type.325), @I.%F.type (%F.type.2ae) [symbolic = %F.assoc_type (constants.%F.assoc_type.003)]
-// CHECK:STDOUT:   %assoc0: @I.%F.assoc_type (%F.assoc_type.003) = assoc_entity element0, imports.%Main.import_ref.479b0f.1 [symbolic = %assoc0 (constants.%assoc0.ed59f4.1)]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type @I.%I.type (%I.type.325) [symbolic = %I.assoc_type (constants.%I.assoc_type.955)]
+// CHECK:STDOUT:   %assoc0: @I.%I.assoc_type (%I.assoc_type.955) = assoc_entity element0, imports.%Main.import_ref.e54 [symbolic = %assoc0 (constants.%assoc0.62c)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = imports.%Main.import_ref.884
-// CHECK:STDOUT:     .F = imports.%Main.import_ref.4ed
+// CHECK:STDOUT:     .F = imports.%Main.import_ref.cd3
 // CHECK:STDOUT:     witness = (imports.%Main.F)
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -747,15 +743,14 @@ fn H(c: C(InClassArgs)) { c.(I(X).F)(); }
 // CHECK:STDOUT:   %I.ref: %I.type.dac = name_ref I, imports.%Main.I [template = constants.%I.generic]
 // CHECK:STDOUT:   %X.ref: type = name_ref X, imports.%Main.X [template = constants.%X]
 // CHECK:STDOUT:   %I.type: type = facet_type <@I, @I(constants.%X)> [template = constants.%I.type.45c]
-// CHECK:STDOUT:   %.loc6_34: %F.assoc_type.2e0 = specific_constant imports.%Main.import_ref.4ed, @I(constants.%X) [template = constants.%assoc0.ef3]
-// CHECK:STDOUT:   %F.ref: %F.assoc_type.2e0 = name_ref F, %.loc6_34 [template = constants.%assoc0.ef3]
+// CHECK:STDOUT:   %.loc6_34: %I.assoc_type.a7e = specific_constant imports.%Main.import_ref.cd3, @I(constants.%X) [template = constants.%assoc0.ba0]
+// CHECK:STDOUT:   %F.ref: %I.assoc_type.a7e = name_ref F, %.loc6_34 [template = constants.%assoc0.ba0]
 // CHECK:STDOUT:   %impl.elem0: %F.type.56a = impl_witness_access constants.%impl_witness, element0 [template = constants.%F.7ab]
 // CHECK:STDOUT:   %F.call: init %empty_tuple.type = call %impl.elem0()
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(constants.%T: type, constants.%Self: %I.type.325) [from "types.carbon"] {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -791,7 +786,7 @@ fn H(c: C(InClassArgs)) { c.(I(X).F)(); }
 // CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT:   %F.type => constants.%F.type.56a
 // CHECK:STDOUT:   %F => constants.%F.a79
-// CHECK:STDOUT:   %F.assoc_type => constants.%F.assoc_type.2e0
-// CHECK:STDOUT:   %assoc0 => constants.%assoc0.ef3
+// CHECK:STDOUT:   %I.assoc_type => constants.%I.assoc_type.a7e
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.ba0
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 11 - 14
toolchain/check/testdata/impl/lookup/transitive.carbon

@@ -50,8 +50,8 @@ fn Call() {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %I.type, %F.type [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @I.%F.decl [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @I.%F.decl [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -73,7 +73,7 @@ fn Call() {
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -82,7 +82,6 @@ fn Call() {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(@I.%Self: %I.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -111,7 +110,7 @@ fn Call() {
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Main.import_ref.e5d = import_ref Main//i, inst17 [no loc], unloaded
-// CHECK:STDOUT:   %Main.import_ref.4a0 = import_ref Main//i, loc4_21, unloaded
+// CHECK:STDOUT:   %Main.import_ref.1e0 = import_ref Main//i, loc4_21, unloaded
 // CHECK:STDOUT:   %Main.F: %F.type.cf0 = import_ref Main//i, F, loaded [template = constants.%F.bc6]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -134,7 +133,7 @@ fn Call() {
 // CHECK:STDOUT: interface @I [from "i.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = imports.%Main.import_ref.e5d
-// CHECK:STDOUT:   .F = imports.%Main.import_ref.4a0
+// CHECK:STDOUT:   .F = imports.%Main.import_ref.1e0
 // CHECK:STDOUT:   witness = (imports.%Main.F)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -155,7 +154,6 @@ fn Call() {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(constants.%Self: %I.type) [from "i.carbon"] {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -228,10 +226,10 @@ fn Call() {
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [template]
 // CHECK:STDOUT:   %I.type: type = facet_type <@I> [template]
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %F.type.cf0: type = fn_type @F.1 [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %I.type, %F.type.cf0 [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, imports.%Main.import_ref.777 [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, imports.%Main.import_ref.e03 [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (imports.%Main.import_ref.742) [template]
+// CHECK:STDOUT:   %F.type.cf0: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.type.5d6: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.a2e: %F.type.5d6 = struct_value () [template]
 // CHECK:STDOUT: }
@@ -246,7 +244,7 @@ fn Call() {
 // CHECK:STDOUT:   %Main.import_ref.8db: <witness> = import_ref Main//get, inst21 [indirect], loaded [template = constants.%complete_type]
 // CHECK:STDOUT:   %Main.import_ref.6a9 = import_ref Main//get, inst22 [indirect], unloaded
 // CHECK:STDOUT:   %Main.import_ref.e5d = import_ref Main//i, inst17 [no loc], unloaded
-// CHECK:STDOUT:   %Main.import_ref.b5b: %F.assoc_type = import_ref Main//i, loc4_21, loaded [template = constants.%assoc0]
+// CHECK:STDOUT:   %Main.import_ref.bcb: %I.assoc_type = import_ref Main//i, loc4_21, loaded [template = constants.%assoc0]
 // CHECK:STDOUT:   %Main.F = import_ref Main//i, F, unloaded
 // CHECK:STDOUT:   %Main.import_ref.e53: <witness> = import_ref Main//c, loc7_13, loaded [template = constants.%impl_witness]
 // CHECK:STDOUT:   %Main.import_ref.29a: type = import_ref Main//c, loc7_6, loaded [template = constants.%C]
@@ -268,7 +266,7 @@ fn Call() {
 // CHECK:STDOUT: interface @I [from "i.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = imports.%Main.import_ref.e5d
-// CHECK:STDOUT:   .F = imports.%Main.import_ref.b5b
+// CHECK:STDOUT:   .F = imports.%Main.import_ref.bcb
 // CHECK:STDOUT:   witness = (imports.%Main.F)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -290,7 +288,7 @@ fn Call() {
 // CHECK:STDOUT:   %.loc9: ref %C = temporary_storage
 // CHECK:STDOUT:   %Get.call: init %C = call %Get.ref() to %.loc9
 // CHECK:STDOUT:   %I.ref: type = name_ref I, imports.%Main.I [template = constants.%I.type]
-// CHECK:STDOUT:   %F.ref: %F.assoc_type = name_ref F, imports.%Main.import_ref.b5b [template = constants.%assoc0]
+// CHECK:STDOUT:   %F.ref: %I.assoc_type = name_ref F, imports.%Main.import_ref.bcb [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0: %F.type.cf0 = impl_witness_access constants.%impl_witness, element0 [template = constants.%F.a2e]
 // CHECK:STDOUT:   %F.call: init %empty_tuple.type = call %impl.elem0()
 // CHECK:STDOUT:   return
@@ -299,7 +297,6 @@ fn Call() {
 // CHECK:STDOUT: fn @Get() -> %C [from "get.carbon"];
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(constants.%Self: %I.type) [from "i.carbon"] {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 30 - 38
toolchain/check/testdata/impl/multiple_extend.carbon

@@ -168,14 +168,14 @@ fn P(o: O) {
 // CHECK:STDOUT:   %F.type.b7b: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.f50: %F.type.b7b = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %HasF.type, %F.type.b7b [template]
-// CHECK:STDOUT:   %assoc0.fe8: %F.assoc_type = assoc_entity element0, @HasF.%F.decl [template]
+// CHECK:STDOUT:   %HasF.assoc_type: type = assoc_entity_type %HasF.type [template]
+// CHECK:STDOUT:   %assoc0.992: %HasF.assoc_type = assoc_entity element0, @HasF.%F.decl [template]
 // CHECK:STDOUT:   %HasG.type: type = facet_type <@HasG> [template]
 // CHECK:STDOUT:   %Self.d42: %HasG.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %G.type.d27: type = fn_type @G.1 [template]
 // CHECK:STDOUT:   %G.688: %G.type.d27 = struct_value () [template]
-// CHECK:STDOUT:   %G.assoc_type: type = assoc_entity_type %HasG.type, %G.type.d27 [template]
-// CHECK:STDOUT:   %assoc0.27f: %G.assoc_type = assoc_entity element0, @HasG.%G.decl [template]
+// CHECK:STDOUT:   %HasG.assoc_type: type = assoc_entity_type %HasG.type [template]
+// CHECK:STDOUT:   %assoc0.58a: %HasG.assoc_type = assoc_entity element0, @HasG.%G.decl [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %impl_witness.329: <witness> = impl_witness (@impl.1.%F.decl) [template]
 // CHECK:STDOUT:   %F.type.a65: type = fn_type @F.2 [template]
@@ -223,7 +223,7 @@ fn P(o: O) {
 // CHECK:STDOUT: interface @HasF {
 // CHECK:STDOUT:   %Self: %HasF.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.f0c]
 // CHECK:STDOUT:   %F.decl: %F.type.b7b = fn_decl @F.1 [template = constants.%F.f50] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0.fe8]
+// CHECK:STDOUT:   %assoc0: %HasF.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0.992]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -234,7 +234,7 @@ fn P(o: O) {
 // CHECK:STDOUT: interface @HasG {
 // CHECK:STDOUT:   %Self: %HasG.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.d42]
 // CHECK:STDOUT:   %G.decl: %G.type.d27 = fn_decl @G.1 [template = constants.%G.688] {} {}
-// CHECK:STDOUT:   %assoc0: %G.assoc_type = assoc_entity element0, %G.decl [template = constants.%assoc0.27f]
+// CHECK:STDOUT:   %assoc0: %HasG.assoc_type = assoc_entity element0, %G.decl [template = constants.%assoc0.58a]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -279,12 +279,10 @@ fn P(o: O) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(@HasF.%Self: %HasF.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @G.1(@HasG.%Self: %HasG.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -301,19 +299,19 @@ fn P(o: O) {
 // CHECK:STDOUT: fn @H(%c.param_patt: %C) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %C.ref.loc22: type = name_ref C, file.%C.decl [template = constants.%C]
-// CHECK:STDOUT:   %F.ref.loc22: %F.assoc_type = name_ref F, @HasF.%assoc0 [template = constants.%assoc0.fe8]
+// CHECK:STDOUT:   %F.ref.loc22: %HasF.assoc_type = name_ref F, @HasF.%assoc0 [template = constants.%assoc0.992]
 // CHECK:STDOUT:   %impl.elem0.loc22: %F.type.b7b = impl_witness_access constants.%impl_witness.329, element0 [template = constants.%F.ad8]
 // CHECK:STDOUT:   %F.call.loc22: init %empty_tuple.type = call %impl.elem0.loc22()
 // CHECK:STDOUT:   %c.ref.loc23: %C = name_ref c, %c
-// CHECK:STDOUT:   %F.ref.loc23: %F.assoc_type = name_ref F, @HasF.%assoc0 [template = constants.%assoc0.fe8]
+// CHECK:STDOUT:   %F.ref.loc23: %HasF.assoc_type = name_ref F, @HasF.%assoc0 [template = constants.%assoc0.992]
 // CHECK:STDOUT:   %impl.elem0.loc23: %F.type.b7b = impl_witness_access constants.%impl_witness.329, element0 [template = constants.%F.ad8]
 // CHECK:STDOUT:   %F.call.loc23: init %empty_tuple.type = call %impl.elem0.loc23()
 // CHECK:STDOUT:   %C.ref.loc24: type = name_ref C, file.%C.decl [template = constants.%C]
-// CHECK:STDOUT:   %G.ref.loc24: %G.assoc_type = name_ref G, @HasG.%assoc0 [template = constants.%assoc0.27f]
+// CHECK:STDOUT:   %G.ref.loc24: %HasG.assoc_type = name_ref G, @HasG.%assoc0 [template = constants.%assoc0.58a]
 // CHECK:STDOUT:   %impl.elem0.loc24: %G.type.d27 = impl_witness_access constants.%impl_witness.42a, element0 [template = constants.%G.957]
 // CHECK:STDOUT:   %G.call.loc24: init %empty_tuple.type = call %impl.elem0.loc24()
 // CHECK:STDOUT:   %c.ref.loc25: %C = name_ref c, %c
-// CHECK:STDOUT:   %G.ref.loc25: %G.assoc_type = name_ref G, @HasG.%assoc0 [template = constants.%assoc0.27f]
+// CHECK:STDOUT:   %G.ref.loc25: %HasG.assoc_type = name_ref G, @HasG.%assoc0 [template = constants.%assoc0.58a]
 // CHECK:STDOUT:   %impl.elem0.loc25: %G.type.d27 = impl_witness_access constants.%impl_witness.42a, element0 [template = constants.%G.957]
 // CHECK:STDOUT:   %G.call.loc25: init %empty_tuple.type = call %impl.elem0.loc25()
 // CHECK:STDOUT:   return
@@ -334,14 +332,14 @@ fn P(o: O) {
 // CHECK:STDOUT:   %Self.90d: %HasA1.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %A.type.9c4: type = fn_type @A.1 [template]
 // CHECK:STDOUT:   %A.c3c: %A.type.9c4 = struct_value () [template]
-// CHECK:STDOUT:   %A.assoc_type.668: type = assoc_entity_type %HasA1.type, %A.type.9c4 [template]
-// CHECK:STDOUT:   %assoc0.41e: %A.assoc_type.668 = assoc_entity element0, @HasA1.%A.decl [template]
+// CHECK:STDOUT:   %HasA1.assoc_type: type = assoc_entity_type %HasA1.type [template]
+// CHECK:STDOUT:   %assoc0.b5a: %HasA1.assoc_type = assoc_entity element0, @HasA1.%A.decl [template]
 // CHECK:STDOUT:   %HasA2.type: type = facet_type <@HasA2> [template]
 // CHECK:STDOUT:   %Self.bdc: %HasA2.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %A.type.f71: type = fn_type @A.2 [template]
 // CHECK:STDOUT:   %A.0eb: %A.type.f71 = struct_value () [template]
-// CHECK:STDOUT:   %A.assoc_type.bac: type = assoc_entity_type %HasA2.type, %A.type.f71 [template]
-// CHECK:STDOUT:   %assoc0.c44: %A.assoc_type.bac = assoc_entity element0, @HasA2.%A.decl [template]
+// CHECK:STDOUT:   %HasA2.assoc_type: type = assoc_entity_type %HasA2.type [template]
+// CHECK:STDOUT:   %assoc0.6ed: %HasA2.assoc_type = assoc_entity element0, @HasA2.%A.decl [template]
 // CHECK:STDOUT:   %D: type = class_type @D [template]
 // CHECK:STDOUT:   %impl_witness.73a: <witness> = impl_witness (@impl.1.%A.decl) [template]
 // CHECK:STDOUT:   %A.type.468: type = fn_type @A.3 [template]
@@ -389,7 +387,7 @@ fn P(o: O) {
 // CHECK:STDOUT: interface @HasA1 {
 // CHECK:STDOUT:   %Self: %HasA1.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.90d]
 // CHECK:STDOUT:   %A.decl: %A.type.9c4 = fn_decl @A.1 [template = constants.%A.c3c] {} {}
-// CHECK:STDOUT:   %assoc0: %A.assoc_type.668 = assoc_entity element0, %A.decl [template = constants.%assoc0.41e]
+// CHECK:STDOUT:   %assoc0: %HasA1.assoc_type = assoc_entity element0, %A.decl [template = constants.%assoc0.b5a]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -400,7 +398,7 @@ fn P(o: O) {
 // CHECK:STDOUT: interface @HasA2 {
 // CHECK:STDOUT:   %Self: %HasA2.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.bdc]
 // CHECK:STDOUT:   %A.decl: %A.type.f71 = fn_decl @A.2 [template = constants.%A.0eb] {} {}
-// CHECK:STDOUT:   %assoc0: %A.assoc_type.bac = assoc_entity element0, %A.decl [template = constants.%assoc0.c44]
+// CHECK:STDOUT:   %assoc0: %HasA2.assoc_type = assoc_entity element0, %A.decl [template = constants.%assoc0.6ed]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -445,12 +443,10 @@ fn P(o: O) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @A.1(@HasA1.%Self: %HasA1.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @A.2(@HasA2.%Self: %HasA2.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -489,8 +485,8 @@ fn P(o: O) {
 // CHECK:STDOUT:   %I.type.9bd: type = fn_type @I.1 [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %I.0a6: %I.type.9bd = struct_value () [template]
-// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %HasI.type, %I.type.9bd [template]
-// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @HasI.%I.decl [template]
+// CHECK:STDOUT:   %HasI.assoc_type: type = assoc_entity_type %HasI.type [template]
+// CHECK:STDOUT:   %assoc0: %HasI.assoc_type = assoc_entity element0, @HasI.%I.decl [template]
 // CHECK:STDOUT:   %B: type = class_type @B [template]
 // CHECK:STDOUT:   %J.type: type = fn_type @J [template]
 // CHECK:STDOUT:   %J: %J.type = struct_value () [template]
@@ -540,7 +536,7 @@ fn P(o: O) {
 // CHECK:STDOUT: interface @HasI {
 // CHECK:STDOUT:   %Self: %HasI.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %I.decl: %I.type.9bd = fn_decl @I.1 [template = constants.%I.0a6] {} {}
-// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, %I.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %HasI.assoc_type = assoc_entity element0, %I.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -585,7 +581,6 @@ fn P(o: O) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @I.1(@HasI.%Self: %HasI.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -602,11 +597,11 @@ fn P(o: O) {
 // CHECK:STDOUT: fn @H(%e.param_patt: %E) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %E.ref.loc20: type = name_ref E, file.%E.decl [template = constants.%E]
-// CHECK:STDOUT:   %I.ref.loc20: %I.assoc_type = name_ref I, @HasI.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:   %I.ref.loc20: %HasI.assoc_type = name_ref I, @HasI.%assoc0 [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0.loc20: %I.type.9bd = impl_witness_access constants.%impl_witness, element0 [template = constants.%I.e74]
 // CHECK:STDOUT:   %I.call.loc20: init %empty_tuple.type = call %impl.elem0.loc20()
 // CHECK:STDOUT:   %e.ref.loc21: %E = name_ref e, %e
-// CHECK:STDOUT:   %I.ref.loc21: %I.assoc_type = name_ref I, @HasI.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:   %I.ref.loc21: %HasI.assoc_type = name_ref I, @HasI.%assoc0 [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0.loc21: %I.type.9bd = impl_witness_access constants.%impl_witness, element0 [template = constants.%I.e74]
 // CHECK:STDOUT:   %I.call.loc21: init %empty_tuple.type = call %impl.elem0.loc21()
 // CHECK:STDOUT:   %E.ref.loc22: type = name_ref E, file.%E.decl [template = constants.%E]
@@ -634,8 +629,8 @@ fn P(o: O) {
 // CHECK:STDOUT:   %Self: %HasK.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %K.type.76f: type = fn_type @K.2 [template]
 // CHECK:STDOUT:   %K.c0e: %K.type.76f = struct_value () [template]
-// CHECK:STDOUT:   %K.assoc_type: type = assoc_entity_type %HasK.type, %K.type.76f [template]
-// CHECK:STDOUT:   %assoc0: %K.assoc_type = assoc_entity element0, @HasK.%K.decl [template]
+// CHECK:STDOUT:   %HasK.assoc_type: type = assoc_entity_type %HasK.type [template]
+// CHECK:STDOUT:   %assoc0: %HasK.assoc_type = assoc_entity element0, @HasK.%K.decl [template]
 // CHECK:STDOUT:   %L: type = class_type @L [template]
 // CHECK:STDOUT:   %L.elem: type = unbound_element_type %L, %Base [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (@impl.%K.decl) [template]
@@ -680,7 +675,7 @@ fn P(o: O) {
 // CHECK:STDOUT: interface @HasK {
 // CHECK:STDOUT:   %Self: %HasK.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %K.decl: %K.type.76f = fn_decl @K.2 [template = constants.%K.c0e] {} {}
-// CHECK:STDOUT:   %assoc0: %K.assoc_type = assoc_entity element0, %K.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %HasK.assoc_type = assoc_entity element0, %K.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -730,7 +725,6 @@ fn P(o: O) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @K.2(@HasK.%Self: %HasK.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -765,14 +759,14 @@ fn P(o: O) {
 // CHECK:STDOUT:   %Self.e0b: %HasN1.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %N.type.3da: type = fn_type @N.2 [template]
 // CHECK:STDOUT:   %N.a51: %N.type.3da = struct_value () [template]
-// CHECK:STDOUT:   %N.assoc_type.d5e: type = assoc_entity_type %HasN1.type, %N.type.3da [template]
-// CHECK:STDOUT:   %assoc0.25b: %N.assoc_type.d5e = assoc_entity element0, @HasN1.%N.decl [template]
+// CHECK:STDOUT:   %HasN1.assoc_type: type = assoc_entity_type %HasN1.type [template]
+// CHECK:STDOUT:   %assoc0.46d: %HasN1.assoc_type = assoc_entity element0, @HasN1.%N.decl [template]
 // CHECK:STDOUT:   %HasN2.type: type = facet_type <@HasN2> [template]
 // CHECK:STDOUT:   %Self.e6e: %HasN2.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %N.type.0aa: type = fn_type @N.3 [template]
 // CHECK:STDOUT:   %N.1a4: %N.type.0aa = struct_value () [template]
-// CHECK:STDOUT:   %N.assoc_type.385: type = assoc_entity_type %HasN2.type, %N.type.0aa [template]
-// CHECK:STDOUT:   %assoc0.196: %N.assoc_type.385 = assoc_entity element0, @HasN2.%N.decl [template]
+// CHECK:STDOUT:   %HasN2.assoc_type: type = assoc_entity_type %HasN2.type [template]
+// CHECK:STDOUT:   %assoc0.9ae: %HasN2.assoc_type = assoc_entity element0, @HasN2.%N.decl [template]
 // CHECK:STDOUT:   %O: type = class_type @O [template]
 // CHECK:STDOUT:   %O.elem: type = unbound_element_type %O, %NBase [template]
 // CHECK:STDOUT:   %impl_witness.982: <witness> = impl_witness (@impl.1.%N.decl) [template]
@@ -825,7 +819,7 @@ fn P(o: O) {
 // CHECK:STDOUT: interface @HasN1 {
 // CHECK:STDOUT:   %Self: %HasN1.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.e0b]
 // CHECK:STDOUT:   %N.decl: %N.type.3da = fn_decl @N.2 [template = constants.%N.a51] {} {}
-// CHECK:STDOUT:   %assoc0: %N.assoc_type.d5e = assoc_entity element0, %N.decl [template = constants.%assoc0.25b]
+// CHECK:STDOUT:   %assoc0: %HasN1.assoc_type = assoc_entity element0, %N.decl [template = constants.%assoc0.46d]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -836,7 +830,7 @@ fn P(o: O) {
 // CHECK:STDOUT: interface @HasN2 {
 // CHECK:STDOUT:   %Self: %HasN2.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.e6e]
 // CHECK:STDOUT:   %N.decl: %N.type.0aa = fn_decl @N.3 [template = constants.%N.1a4] {} {}
-// CHECK:STDOUT:   %assoc0: %N.assoc_type.385 = assoc_entity element0, %N.decl [template = constants.%assoc0.196]
+// CHECK:STDOUT:   %assoc0: %HasN2.assoc_type = assoc_entity element0, %N.decl [template = constants.%assoc0.9ae]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -902,12 +896,10 @@ fn P(o: O) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @N.2(@HasN1.%Self: %HasN1.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @N.3(@HasN2.%Self: %HasN2.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 3 - 4
toolchain/check/testdata/impl/no_prelude/basic.carbon

@@ -25,8 +25,8 @@ impl C as Simple {
 // CHECK:STDOUT:   %Self: %Simple.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %F.type.e2e: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.df8: %F.type.e2e = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %Simple.type, %F.type.e2e [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @Simple.%F.decl [template]
+// CHECK:STDOUT:   %Simple.assoc_type: type = assoc_entity_type %Simple.type [template]
+// CHECK:STDOUT:   %assoc0: %Simple.assoc_type = assoc_entity element0, @Simple.%F.decl [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [template]
@@ -53,7 +53,7 @@ impl C as Simple {
 // CHECK:STDOUT: interface @Simple {
 // CHECK:STDOUT:   %Self: %Simple.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type.e2e = fn_decl @F.1 [template = constants.%F.df8] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %Simple.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -78,7 +78,6 @@ impl C as Simple {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(@Simple.%Self: %Simple.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 13 - 6
toolchain/check/testdata/impl/no_prelude/fail_impl_bad_assoc_const.carbon

@@ -13,7 +13,7 @@ interface I { let T:! type; }
 // CHECK:STDERR: fail_impl_bad_assoc_const.carbon:[[@LINE+7]]:12: error: associated constant T not given a value in impl of interface I [ImplAssociatedConstantNeedsValue]
 // CHECK:STDERR: impl () as I {}
 // CHECK:STDERR:            ^
-// CHECK:STDERR: fail_impl_bad_assoc_const.carbon:[[@LINE-5]]:19: note: associated constant T declared here [AssociatedConstantHere]
+// CHECK:STDERR: fail_impl_bad_assoc_const.carbon:[[@LINE-5]]:19: note: associated constant declared here [AssociatedConstantHere]
 // CHECK:STDERR: interface I { let T:! type; }
 // CHECK:STDERR:                   ^~~~~~~~
 // CHECK:STDERR:
@@ -24,8 +24,8 @@ impl () as I {}
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %I.type: type = facet_type <@I> [template]
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %I.type, type [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, @I.%T [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (<error>) [template]
 // CHECK:STDOUT: }
@@ -45,17 +45,24 @@ impl () as I {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %T: type = assoc_const_decl T [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %T [template = constants.%assoc0]
+// CHECK:STDOUT:   %T: type = assoc_const_decl @T [template] {
+// CHECK:STDOUT:     %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [template = constants.%assoc0]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .T = %assoc0
+// CHECK:STDOUT:   .T = @T.%assoc0
 // CHECK:STDOUT:   witness = (%T)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @T(@I.%Self: %I.type) {
+// CHECK:STDOUT:   assoc_const T:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %.loc20_7.2 as %I.ref {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   witness = file.%impl_witness
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @T(constants.%Self) {}
+// CHECK:STDOUT:

+ 290 - 92
toolchain/check/testdata/impl/no_prelude/impl_assoc_const.carbon

@@ -163,11 +163,13 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %I.type: type = facet_type <@I> [template]
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %I.type, type [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, @I.%T [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %.Self: %I.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %I.facet: %I.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %I_where.type: type = facet_type <@I where %impl.elem0 = %empty_struct_type> [template]
@@ -185,7 +187,9 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:     %I.ref: type = name_ref I, file.%I.decl [template = constants.%I.type]
 // CHECK:STDOUT:     %.Self: %I.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:     %.Self.ref: %I.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %T.ref: %assoc_type = name_ref T, @I.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %T.ref: %I.assoc_type = name_ref T, @T.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc5_20: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %.loc5_26.1: %empty_struct_type = struct_literal ()
@@ -199,30 +203,41 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %T: type = assoc_const_decl T [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %T [template = constants.%assoc0]
+// CHECK:STDOUT:   %T: type = assoc_const_decl @T [template] {
+// CHECK:STDOUT:     %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [template = constants.%assoc0]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .T = %assoc0
+// CHECK:STDOUT:   .T = @T.%assoc0
 // CHECK:STDOUT:   witness = (%T)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @T(@I.%Self: %I.type) {
+// CHECK:STDOUT:   assoc_const T:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %.loc5_7.2 as %.loc5_14 {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   witness = file.%impl_witness
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @T(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @T(constants.%I.facet) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: --- redecl.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %I2.type: type = facet_type <@I2> [template]
 // CHECK:STDOUT:   %Self: %I2.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %I2.type, type [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, @I2.%T2 [template]
+// CHECK:STDOUT:   %I2.assoc_type: type = assoc_entity_type %I2.type [template]
+// CHECK:STDOUT:   %assoc0: %I2.assoc_type = assoc_entity element0, @I2.%T2 [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %.Self: %I2.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %I2.facet: %I2.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %I2_where.type: type = facet_type <@I2 where %impl.elem0 = %empty_struct_type> [template]
@@ -240,7 +255,9 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:     %I2.ref.loc5: type = name_ref I2, file.%I2.decl [template = constants.%I2.type]
 // CHECK:STDOUT:     %.Self.1: %I2.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:     %.Self.ref.loc5: %I2.type = name_ref .Self, %.Self.1 [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %T2.ref.loc5: %assoc_type = name_ref T2, @I2.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %T2.ref.loc5: %I2.assoc_type = name_ref T2, @T2.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %.Self.as_type.loc5: type = facet_access_type %.Self.ref.loc5 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc5_21: type = converted %.Self.ref.loc5, %.Self.as_type.loc5 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit.loc5: <witness> = facet_access_witness %.Self.ref.loc5 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0.loc5: type = impl_witness_access %.Self.as_wit.loc5, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %.loc5_28.1: %empty_struct_type = struct_literal ()
@@ -256,7 +273,9 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:     %I2.ref.loc6: type = name_ref I2, file.%I2.decl [template = constants.%I2.type]
 // CHECK:STDOUT:     %.Self.2: %I2.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:     %.Self.ref.loc6: %I2.type = name_ref .Self, %.Self.2 [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %T2.ref.loc6: %assoc_type = name_ref T2, @I2.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %T2.ref.loc6: %I2.assoc_type = name_ref T2, @T2.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %.Self.as_type.loc6: type = facet_access_type %.Self.ref.loc6 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc6_21: type = converted %.Self.ref.loc6, %.Self.as_type.loc6 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit.loc6: <witness> = facet_access_witness %.Self.ref.loc6 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0.loc6: type = impl_witness_access %.Self.as_wit.loc6, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %.loc6_28.1: %empty_struct_type = struct_literal ()
@@ -269,31 +288,42 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @I2 {
 // CHECK:STDOUT:   %Self: %I2.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %T2: type = assoc_const_decl T2 [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %T2 [template = constants.%assoc0]
+// CHECK:STDOUT:   %T2: type = assoc_const_decl @T2 [template] {
+// CHECK:STDOUT:     %assoc0: %I2.assoc_type = assoc_entity element0, @I2.%T2 [template = constants.%assoc0]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .T2 = %assoc0
+// CHECK:STDOUT:   .T2 = @T2.%assoc0
 // CHECK:STDOUT:   witness = (%T2)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @T2(@I2.%Self: %I2.type) {
+// CHECK:STDOUT:   assoc_const T2:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %.loc5_7.2 as %.loc5_15 {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   witness = file.%impl_witness
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @T2(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @T2(constants.%I2.facet) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: --- redecl_adds_rewrites.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %I3.type: type = facet_type <@I3> [template]
 // CHECK:STDOUT:   %Self: %I3.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %I3.type, type [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, @I3.%T3 [template]
+// CHECK:STDOUT:   %I3.assoc_type: type = assoc_entity_type %I3.type [template]
+// CHECK:STDOUT:   %assoc0: %I3.assoc_type = assoc_entity element0, @I3.%T3 [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (%empty_struct_type) [template]
 // CHECK:STDOUT:   %.Self: %I3.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %I3.facet: %I3.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %I3_where.type: type = facet_type <@I3 where %impl.elem0 = %empty_struct_type> [template]
@@ -316,7 +346,9 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:     %I3.ref.loc6: type = name_ref I3, file.%I3.decl [template = constants.%I3.type]
 // CHECK:STDOUT:     %.Self: %I3.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:     %.Self.ref: %I3.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %T3.ref: %assoc_type = name_ref T3, @I3.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %T3.ref: %I3.assoc_type = name_ref T3, @T3.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc6_21: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %.loc6_28.1: %empty_struct_type = struct_literal ()
@@ -329,30 +361,41 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @I3 {
 // CHECK:STDOUT:   %Self: %I3.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %T3: type = assoc_const_decl T3 [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %T3 [template = constants.%assoc0]
+// CHECK:STDOUT:   %T3: type = assoc_const_decl @T3 [template] {
+// CHECK:STDOUT:     %assoc0: %I3.assoc_type = assoc_entity element0, @I3.%T3 [template = constants.%assoc0]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .T3 = %assoc0
+// CHECK:STDOUT:   .T3 = @T3.%assoc0
 // CHECK:STDOUT:   witness = (%T3)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @T3(@I3.%Self: %I3.type) {
+// CHECK:STDOUT:   assoc_const T3:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %.loc5_7.2 as %I3.ref.loc5 {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   witness = file.%impl_witness
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @T3(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @T3(constants.%I3.facet) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_mismatch.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %J.type: type = facet_type <@J> [template]
 // CHECK:STDOUT:   %Self: %J.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %J.type, type [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, @J.%U [template]
+// CHECK:STDOUT:   %J.assoc_type: type = assoc_entity_type %J.type [template]
+// CHECK:STDOUT:   %assoc0: %J.assoc_type = assoc_entity element0, @J.%U [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %.Self: %J.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %J.facet: %J.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %J_where.type.800: type = facet_type <@J where %impl.elem0 = %empty_struct_type> [template]
@@ -371,7 +414,9 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:     %J.ref.loc5: type = name_ref J, file.%J.decl [template = constants.%J.type]
 // CHECK:STDOUT:     %.Self.1: %J.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:     %.Self.ref.loc5: %J.type = name_ref .Self, %.Self.1 [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %U.ref.loc5: %assoc_type = name_ref U, @J.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %U.ref.loc5: %J.assoc_type = name_ref U, @U.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %.Self.as_type.loc5: type = facet_access_type %.Self.ref.loc5 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc5_20: type = converted %.Self.ref.loc5, %.Self.as_type.loc5 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit.loc5: <witness> = facet_access_witness %.Self.ref.loc5 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0.loc5: type = impl_witness_access %.Self.as_wit.loc5, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %.loc5_26.1: %empty_struct_type = struct_literal ()
@@ -387,7 +432,9 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:     %J.ref.loc13: type = name_ref J, file.%J.decl [template = constants.%J.type]
 // CHECK:STDOUT:     %.Self.2: %J.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:     %.Self.ref.loc13: %J.type = name_ref .Self, %.Self.2 [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %U.ref.loc13: %assoc_type = name_ref U, @J.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %U.ref.loc13: %J.assoc_type = name_ref U, @U.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %.Self.as_type.loc13: type = facet_access_type %.Self.ref.loc13 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc13_20: type = converted %.Self.ref.loc13, %.Self.as_type.loc13 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit.loc13: <witness> = facet_access_witness %.Self.ref.loc13 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0.loc13: type = impl_witness_access %.Self.as_wit.loc13, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %.loc13_26.1: %empty_tuple.type = tuple_literal ()
@@ -400,32 +447,43 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @J {
 // CHECK:STDOUT:   %Self: %J.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %U: type = assoc_const_decl U [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %U [template = constants.%assoc0]
+// CHECK:STDOUT:   %U: type = assoc_const_decl @U [template] {
+// CHECK:STDOUT:     %assoc0: %J.assoc_type = assoc_entity element0, @J.%U [template = constants.%assoc0]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .U = %assoc0
+// CHECK:STDOUT:   .U = @U.%assoc0
 // CHECK:STDOUT:   witness = (%U)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @U(@J.%Self: %J.type) {
+// CHECK:STDOUT:   assoc_const U:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %.loc5_7.2 as %.loc5_14 {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   witness = file.%impl_witness
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @U(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @U(constants.%J.facet) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_mismatch_bad_value.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %I4.type: type = facet_type <@I4> [template]
 // CHECK:STDOUT:   %Self: %I4.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %I4.type, type [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, @I4.%T4 [template]
-// CHECK:STDOUT:   %assoc1: %assoc_type = assoc_entity element1, @I4.%T5 [template]
-// CHECK:STDOUT:   %assoc2: %assoc_type = assoc_entity element2, @I4.%T6 [template]
+// CHECK:STDOUT:   %I4.assoc_type: type = assoc_entity_type %I4.type [template]
+// CHECK:STDOUT:   %assoc0: %I4.assoc_type = assoc_entity element0, @I4.%T4 [template]
+// CHECK:STDOUT:   %assoc1: %I4.assoc_type = assoc_entity element1, @I4.%T5 [template]
+// CHECK:STDOUT:   %assoc2: %I4.assoc_type = assoc_entity element2, @I4.%T6 [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %.Self: %I4.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %I4.facet: %I4.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT:   %impl.elem1: type = impl_witness_access %.Self.as_wit, element1 [symbolic]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
@@ -445,19 +503,25 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:     %I4.ref.loc21: type = name_ref I4, file.%I4.decl [template = constants.%I4.type]
 // CHECK:STDOUT:     %.Self.1: %I4.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:     %.Self.ref.loc21_21: %I4.type = name_ref .Self, %.Self.1 [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %T4.ref.loc21: %assoc_type = name_ref T4, @I4.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %T4.ref.loc21: %I4.assoc_type = name_ref T4, @T4.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %.Self.as_type.loc21_21: type = facet_access_type %.Self.ref.loc21_21 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc21_21: type = converted %.Self.ref.loc21_21, %.Self.as_type.loc21_21 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit.loc21_21: <witness> = facet_access_witness %.Self.ref.loc21_21 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0.loc21: type = impl_witness_access %.Self.as_wit.loc21_21, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %BAD1.ref: <error> = name_ref BAD1, <error> [template = <error>]
 // CHECK:STDOUT:     %.Self.ref.loc21_36: %I4.type = name_ref .Self, %.Self.1 [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %T5.ref.loc21: %assoc_type = name_ref T5, @I4.%assoc1 [template = constants.%assoc1]
+// CHECK:STDOUT:     %T5.ref.loc21: %I4.assoc_type = name_ref T5, @T5.%assoc1 [template = constants.%assoc1]
+// CHECK:STDOUT:     %.Self.as_type.loc21_36: type = facet_access_type %.Self.ref.loc21_36 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc21_36: type = converted %.Self.ref.loc21_36, %.Self.as_type.loc21_36 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit.loc21_36: <witness> = facet_access_witness %.Self.ref.loc21_36 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem1.loc21: type = impl_witness_access %.Self.as_wit.loc21_36, element1 [symbolic = constants.%impl.elem1]
 // CHECK:STDOUT:     %.loc21_48.1: %empty_struct_type = struct_literal ()
 // CHECK:STDOUT:     %.loc21_48.2: type = converted %.loc21_48.1, constants.%empty_struct_type [template = constants.%empty_struct_type]
 // CHECK:STDOUT:     %struct_type.a: type = struct_type {.a: %empty_struct_type} [template = constants.%struct_type.a]
 // CHECK:STDOUT:     %.Self.ref.loc21_55: %I4.type = name_ref .Self, %.Self.1 [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %T6.ref.loc21: %assoc_type = name_ref T6, @I4.%assoc2 [template = constants.%assoc2]
+// CHECK:STDOUT:     %T6.ref.loc21: %I4.assoc_type = name_ref T6, @T6.%assoc2 [template = constants.%assoc2]
+// CHECK:STDOUT:     %.Self.as_type.loc21_55: type = facet_access_type %.Self.ref.loc21_55 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc21_55: type = converted %.Self.ref.loc21_55, %.Self.as_type.loc21_55 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit.loc21_55: <witness> = facet_access_witness %.Self.ref.loc21_55 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem2.loc21: type = impl_witness_access %.Self.as_wit.loc21_55, element2 [symbolic = constants.%impl.elem2]
 // CHECK:STDOUT:     %BAD2.ref: <error> = name_ref BAD2, <error> [template = <error>]
@@ -473,19 +537,25 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:     %I4.ref.loc31: type = name_ref I4, file.%I4.decl [template = constants.%I4.type]
 // CHECK:STDOUT:     %.Self.2: %I4.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:     %.Self.ref.loc31_21: %I4.type = name_ref .Self, %.Self.2 [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %T4.ref.loc31: %assoc_type = name_ref T4, @I4.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %T4.ref.loc31: %I4.assoc_type = name_ref T4, @T4.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %.Self.as_type.loc31_21: type = facet_access_type %.Self.ref.loc31_21 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc31_21: type = converted %.Self.ref.loc31_21, %.Self.as_type.loc31_21 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit.loc31_21: <witness> = facet_access_witness %.Self.ref.loc31_21 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0.loc31: type = impl_witness_access %.Self.as_wit.loc31_21, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %.loc31_33.1: %empty_struct_type = struct_literal ()
 // CHECK:STDOUT:     %.loc31_33.2: type = converted %.loc31_33.1, constants.%empty_struct_type [template = constants.%empty_struct_type]
 // CHECK:STDOUT:     %struct_type.b: type = struct_type {.b: %empty_struct_type} [template = constants.%struct_type.b]
 // CHECK:STDOUT:     %.Self.ref.loc31_40: %I4.type = name_ref .Self, %.Self.2 [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %T5.ref.loc31: %assoc_type = name_ref T5, @I4.%assoc1 [template = constants.%assoc1]
+// CHECK:STDOUT:     %T5.ref.loc31: %I4.assoc_type = name_ref T5, @T5.%assoc1 [template = constants.%assoc1]
+// CHECK:STDOUT:     %.Self.as_type.loc31_40: type = facet_access_type %.Self.ref.loc31_40 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc31_40: type = converted %.Self.ref.loc31_40, %.Self.as_type.loc31_40 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit.loc31_40: <witness> = facet_access_witness %.Self.ref.loc31_40 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem1.loc31: type = impl_witness_access %.Self.as_wit.loc31_40, element1 [symbolic = constants.%impl.elem1]
 // CHECK:STDOUT:     %BAD3.ref: <error> = name_ref BAD3, <error> [template = <error>]
 // CHECK:STDOUT:     %.Self.ref.loc31_55: %I4.type = name_ref .Self, %.Self.2 [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %T6.ref.loc31: %assoc_type = name_ref T6, @I4.%assoc2 [template = constants.%assoc2]
+// CHECK:STDOUT:     %T6.ref.loc31: %I4.assoc_type = name_ref T6, @T6.%assoc2 [template = constants.%assoc2]
+// CHECK:STDOUT:     %.Self.as_type.loc31_55: type = facet_access_type %.Self.ref.loc31_55 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc31_55: type = converted %.Self.ref.loc31_55, %.Self.as_type.loc31_55 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit.loc31_55: <witness> = facet_access_witness %.Self.ref.loc31_55 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem2.loc31: type = impl_witness_access %.Self.as_wit.loc31_55, element2 [symbolic = constants.%impl.elem2]
 // CHECK:STDOUT:     %BAD4.ref: <error> = name_ref BAD4, <error> [template = <error>]
@@ -499,36 +569,65 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @I4 {
 // CHECK:STDOUT:   %Self: %I4.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %T4: type = assoc_const_decl T4 [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %T4 [template = constants.%assoc0]
-// CHECK:STDOUT:   %T5: type = assoc_const_decl T5 [template]
-// CHECK:STDOUT:   %assoc1: %assoc_type = assoc_entity element1, %T5 [template = constants.%assoc1]
-// CHECK:STDOUT:   %T6: type = assoc_const_decl T6 [template]
-// CHECK:STDOUT:   %assoc2: %assoc_type = assoc_entity element2, %T6 [template = constants.%assoc2]
+// CHECK:STDOUT:   %T4: type = assoc_const_decl @T4 [template] {
+// CHECK:STDOUT:     %assoc0: %I4.assoc_type = assoc_entity element0, @I4.%T4 [template = constants.%assoc0]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %T5: type = assoc_const_decl @T5 [template] {
+// CHECK:STDOUT:     %assoc1: %I4.assoc_type = assoc_entity element1, @I4.%T5 [template = constants.%assoc1]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %T6: type = assoc_const_decl @T6 [template] {
+// CHECK:STDOUT:     %assoc2: %I4.assoc_type = assoc_entity element2, @I4.%T6 [template = constants.%assoc2]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .T4 = %assoc0
-// CHECK:STDOUT:   .T5 = %assoc1
-// CHECK:STDOUT:   .T6 = %assoc2
+// CHECK:STDOUT:   .T4 = @T4.%assoc0
+// CHECK:STDOUT:   .T5 = @T5.%assoc1
+// CHECK:STDOUT:   .T6 = @T6.%assoc2
 // CHECK:STDOUT:   witness = (%T4, %T5, %T6)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @T4(@I4.%Self: %I4.type) {
+// CHECK:STDOUT:   assoc_const T4:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @T5(@I4.%Self: %I4.type) {
+// CHECK:STDOUT:   assoc_const T5:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @T6(@I4.%Self: %I4.type) {
+// CHECK:STDOUT:   assoc_const T6:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %.loc21_7.2 as %.loc21_15 {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   witness = <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @T4(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @T5(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @T6(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @T4(constants.%I4.facet) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @T5(constants.%I4.facet) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @T6(constants.%I4.facet) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_missing_on_definition.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %K.type: type = facet_type <@K> [template]
 // CHECK:STDOUT:   %Self: %K.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %K.type, type [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, @K.%V [template]
+// CHECK:STDOUT:   %K.assoc_type: type = assoc_entity_type %K.type [template]
+// CHECK:STDOUT:   %assoc0: %K.assoc_type = assoc_entity element0, @K.%V [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %.Self: %K.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %K.facet: %K.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %K_where.type: type = facet_type <@K where %impl.elem0 = %empty_struct_type> [template]
@@ -546,7 +645,9 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:     %K.ref.loc5: type = name_ref K, file.%K.decl [template = constants.%K.type]
 // CHECK:STDOUT:     %.Self: %K.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:     %.Self.ref: %K.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %V.ref: %assoc_type = name_ref V, @K.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %V.ref: %K.assoc_type = name_ref V, @V.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc5_20: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %.loc5_26.1: %empty_struct_type = struct_literal ()
@@ -565,30 +666,41 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @K {
 // CHECK:STDOUT:   %Self: %K.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %V: type = assoc_const_decl V [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %V [template = constants.%assoc0]
+// CHECK:STDOUT:   %V: type = assoc_const_decl @V [template] {
+// CHECK:STDOUT:     %assoc0: %K.assoc_type = assoc_entity element0, @K.%V [template = constants.%assoc0]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .V = %assoc0
+// CHECK:STDOUT:   .V = @V.%assoc0
 // CHECK:STDOUT:   witness = (%V)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @V(@K.%Self: %K.type) {
+// CHECK:STDOUT:   assoc_const V:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %.loc5_7.2 as %.loc5_14 {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   witness = file.%impl_witness
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @V(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @V(constants.%K.facet) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_two_different.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %L.type: type = facet_type <@L> [template]
 // CHECK:STDOUT:   %Self: %L.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %L.type, type [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, @L.%W [template]
+// CHECK:STDOUT:   %L.assoc_type: type = assoc_entity_type %L.type [template]
+// CHECK:STDOUT:   %assoc0: %L.assoc_type = assoc_entity element0, @L.%W [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %.Self: %L.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %L.facet: %L.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %L_where.type: type = facet_type <@L where %impl.elem0 = %empty_tuple.type and %impl.elem0 = %empty_struct_type> [template]
@@ -606,13 +718,17 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:     %L.ref: type = name_ref L, file.%L.decl [template = constants.%L.type]
 // CHECK:STDOUT:     %.Self: %L.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:     %.Self.ref.loc9_20: %L.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %W.ref.loc9_20: %assoc_type = name_ref W, @L.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %W.ref.loc9_20: %L.assoc_type = name_ref W, @W.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %.Self.as_type.loc9_20: type = facet_access_type %.Self.ref.loc9_20 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc9_20: type = converted %.Self.ref.loc9_20, %.Self.as_type.loc9_20 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit.loc9_20: <witness> = facet_access_witness %.Self.ref.loc9_20 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0.loc9_20: type = impl_witness_access %.Self.as_wit.loc9_20, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %.loc9_26.1: %empty_struct_type = struct_literal ()
 // CHECK:STDOUT:     %.loc9_26.2: type = converted %.loc9_26.1, constants.%empty_struct_type [template = constants.%empty_struct_type]
 // CHECK:STDOUT:     %.Self.ref.loc9_32: %L.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %W.ref.loc9_32: %assoc_type = name_ref W, @L.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %W.ref.loc9_32: %L.assoc_type = name_ref W, @W.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %.Self.as_type.loc9_32: type = facet_access_type %.Self.ref.loc9_32 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc9_32: type = converted %.Self.ref.loc9_32, %.Self.as_type.loc9_32 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit.loc9_32: <witness> = facet_access_witness %.Self.ref.loc9_32 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0.loc9_32: type = impl_witness_access %.Self.as_wit.loc9_32, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %.loc9_38.1: %empty_tuple.type = tuple_literal ()
@@ -627,30 +743,41 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @L {
 // CHECK:STDOUT:   %Self: %L.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %W: type = assoc_const_decl W [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %W [template = constants.%assoc0]
+// CHECK:STDOUT:   %W: type = assoc_const_decl @W [template] {
+// CHECK:STDOUT:     %assoc0: %L.assoc_type = assoc_entity element0, @L.%W [template = constants.%assoc0]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .W = %assoc0
+// CHECK:STDOUT:   .W = @W.%assoc0
 // CHECK:STDOUT:   witness = (%W)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @W(@L.%Self: %L.type) {
+// CHECK:STDOUT:   assoc_const W:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %.loc9_7.2 as %.loc9_14 {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   witness = file.%impl_witness
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @W(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @W(constants.%L.facet) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_two_different_first_bad.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %L2.type: type = facet_type <@L2> [template]
 // CHECK:STDOUT:   %Self: %L2.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %L2.type, type [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, @L2.%W2 [template]
+// CHECK:STDOUT:   %L2.assoc_type: type = assoc_entity_type %L2.type [template]
+// CHECK:STDOUT:   %assoc0: %L2.assoc_type = assoc_entity element0, @L2.%W2 [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %.Self: %L2.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %L2.facet: %L2.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -665,12 +792,16 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:     %L2.ref: type = name_ref L2, file.%L2.decl [template = constants.%L2.type]
 // CHECK:STDOUT:     %.Self: %L2.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:     %.Self.ref.loc9_21: %L2.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %W2.ref.loc9_21: %assoc_type = name_ref W2, @L2.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %W2.ref.loc9_21: %L2.assoc_type = name_ref W2, @W2.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %.Self.as_type.loc9_21: type = facet_access_type %.Self.ref.loc9_21 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc9_21: type = converted %.Self.ref.loc9_21, %.Self.as_type.loc9_21 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit.loc9_21: <witness> = facet_access_witness %.Self.ref.loc9_21 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0.loc9_21: type = impl_witness_access %.Self.as_wit.loc9_21, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %BAD5.ref: <error> = name_ref BAD5, <error> [template = <error>]
 // CHECK:STDOUT:     %.Self.ref.loc9_36: %L2.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %W2.ref.loc9_36: %assoc_type = name_ref W2, @L2.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %W2.ref.loc9_36: %L2.assoc_type = name_ref W2, @W2.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %.Self.as_type.loc9_36: type = facet_access_type %.Self.ref.loc9_36 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc9_36: type = converted %.Self.ref.loc9_36, %.Self.as_type.loc9_36 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit.loc9_36: <witness> = facet_access_witness %.Self.ref.loc9_36 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0.loc9_36: type = impl_witness_access %.Self.as_wit.loc9_36, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %.loc9_43.1: %empty_tuple.type = tuple_literal ()
@@ -684,30 +815,41 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @L2 {
 // CHECK:STDOUT:   %Self: %L2.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %W2: type = assoc_const_decl W2 [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %W2 [template = constants.%assoc0]
+// CHECK:STDOUT:   %W2: type = assoc_const_decl @W2 [template] {
+// CHECK:STDOUT:     %assoc0: %L2.assoc_type = assoc_entity element0, @L2.%W2 [template = constants.%assoc0]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .W2 = %assoc0
+// CHECK:STDOUT:   .W2 = @W2.%assoc0
 // CHECK:STDOUT:   witness = (%W2)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @W2(@L2.%Self: %L2.type) {
+// CHECK:STDOUT:   assoc_const W2:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %.loc9_7.2 as %.loc9_15 {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   witness = <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @W2(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @W2(constants.%L2.facet) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_two_different_second_bad.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %L3.type: type = facet_type <@L3> [template]
 // CHECK:STDOUT:   %Self: %L3.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %L3.type, type [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, @L3.%W3 [template]
+// CHECK:STDOUT:   %L3.assoc_type: type = assoc_entity_type %L3.type [template]
+// CHECK:STDOUT:   %assoc0: %L3.assoc_type = assoc_entity element0, @L3.%W3 [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %.Self: %L3.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %L3.facet: %L3.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT: }
@@ -723,13 +865,17 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:     %L3.ref: type = name_ref L3, file.%L3.decl [template = constants.%L3.type]
 // CHECK:STDOUT:     %.Self: %L3.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:     %.Self.ref.loc9_21: %L3.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %W3.ref.loc9_21: %assoc_type = name_ref W3, @L3.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %W3.ref.loc9_21: %L3.assoc_type = name_ref W3, @W3.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %.Self.as_type.loc9_21: type = facet_access_type %.Self.ref.loc9_21 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc9_21: type = converted %.Self.ref.loc9_21, %.Self.as_type.loc9_21 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit.loc9_21: <witness> = facet_access_witness %.Self.ref.loc9_21 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0.loc9_21: type = impl_witness_access %.Self.as_wit.loc9_21, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %.loc9_28.1: %empty_struct_type = struct_literal ()
 // CHECK:STDOUT:     %.loc9_28.2: type = converted %.loc9_28.1, constants.%empty_struct_type [template = constants.%empty_struct_type]
 // CHECK:STDOUT:     %.Self.ref.loc9_34: %L3.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %W3.ref.loc9_34: %assoc_type = name_ref W3, @L3.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %W3.ref.loc9_34: %L3.assoc_type = name_ref W3, @W3.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %.Self.as_type.loc9_34: type = facet_access_type %.Self.ref.loc9_34 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc9_34: type = converted %.Self.ref.loc9_34, %.Self.as_type.loc9_34 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit.loc9_34: <witness> = facet_access_witness %.Self.ref.loc9_34 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0.loc9_34: type = impl_witness_access %.Self.as_wit.loc9_34, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %BAD6.ref: <error> = name_ref BAD6, <error> [template = <error>]
@@ -742,30 +888,41 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @L3 {
 // CHECK:STDOUT:   %Self: %L3.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %W3: type = assoc_const_decl W3 [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %W3 [template = constants.%assoc0]
+// CHECK:STDOUT:   %W3: type = assoc_const_decl @W3 [template] {
+// CHECK:STDOUT:     %assoc0: %L3.assoc_type = assoc_entity element0, @L3.%W3 [template = constants.%assoc0]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .W3 = %assoc0
+// CHECK:STDOUT:   .W3 = @W3.%assoc0
 // CHECK:STDOUT:   witness = (%W3)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @W3(@L3.%Self: %L3.type) {
+// CHECK:STDOUT:   assoc_const W3:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %.loc9_7.2 as %.loc9_15 {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   witness = <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @W3(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @W3(constants.%L3.facet) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_two_different_both_bad.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %L4.type: type = facet_type <@L4> [template]
 // CHECK:STDOUT:   %Self: %L4.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %L4.type, type [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, @L4.%W4 [template]
+// CHECK:STDOUT:   %L4.assoc_type: type = assoc_entity_type %L4.type [template]
+// CHECK:STDOUT:   %assoc0: %L4.assoc_type = assoc_entity element0, @L4.%W4 [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %.Self: %L4.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %L4.facet: %L4.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -780,12 +937,16 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:     %L4.ref: type = name_ref L4, file.%L4.decl [template = constants.%L4.type]
 // CHECK:STDOUT:     %.Self: %L4.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:     %.Self.ref.loc13_21: %L4.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %W4.ref.loc13_21: %assoc_type = name_ref W4, @L4.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %W4.ref.loc13_21: %L4.assoc_type = name_ref W4, @W4.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %.Self.as_type.loc13_21: type = facet_access_type %.Self.ref.loc13_21 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc13_21: type = converted %.Self.ref.loc13_21, %.Self.as_type.loc13_21 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit.loc13_21: <witness> = facet_access_witness %.Self.ref.loc13_21 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0.loc13_21: type = impl_witness_access %.Self.as_wit.loc13_21, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %BAD7.ref: <error> = name_ref BAD7, <error> [template = <error>]
 // CHECK:STDOUT:     %.Self.ref.loc13_36: %L4.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %W4.ref.loc13_36: %assoc_type = name_ref W4, @L4.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %W4.ref.loc13_36: %L4.assoc_type = name_ref W4, @W4.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %.Self.as_type.loc13_36: type = facet_access_type %.Self.ref.loc13_36 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc13_36: type = converted %.Self.ref.loc13_36, %.Self.as_type.loc13_36 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit.loc13_36: <witness> = facet_access_witness %.Self.ref.loc13_36 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0.loc13_36: type = impl_witness_access %.Self.as_wit.loc13_36, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %BAD8.ref: <error> = name_ref BAD8, <error> [template = <error>]
@@ -798,30 +959,41 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @L4 {
 // CHECK:STDOUT:   %Self: %L4.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %W4: type = assoc_const_decl W4 [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %W4 [template = constants.%assoc0]
+// CHECK:STDOUT:   %W4: type = assoc_const_decl @W4 [template] {
+// CHECK:STDOUT:     %assoc0: %L4.assoc_type = assoc_entity element0, @L4.%W4 [template = constants.%assoc0]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .W4 = %assoc0
+// CHECK:STDOUT:   .W4 = @W4.%assoc0
 // CHECK:STDOUT:   witness = (%W4)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @W4(@L4.%Self: %L4.type) {
+// CHECK:STDOUT:   assoc_const W4:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %.loc13_7.2 as %.loc13_15 {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   witness = <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @W4(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @W4(constants.%L4.facet) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: --- repeated.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %M.type: type = facet_type <@M> [template]
 // CHECK:STDOUT:   %Self: %M.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %M.type, type [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, @M.%X [template]
+// CHECK:STDOUT:   %M.assoc_type: type = assoc_entity_type %M.type [template]
+// CHECK:STDOUT:   %assoc0: %M.assoc_type = assoc_entity element0, @M.%X [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %.Self: %M.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %M.facet: %M.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %M_where.type: type = facet_type <@M where %impl.elem0 = %empty_struct_type> [template]
@@ -839,13 +1011,17 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:     %M.ref: type = name_ref M, file.%M.decl [template = constants.%M.type]
 // CHECK:STDOUT:     %.Self: %M.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:     %.Self.ref.loc5_20: %M.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %X.ref.loc5_20: %assoc_type = name_ref X, @M.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %X.ref.loc5_20: %M.assoc_type = name_ref X, @X.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %.Self.as_type.loc5_20: type = facet_access_type %.Self.ref.loc5_20 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc5_20: type = converted %.Self.ref.loc5_20, %.Self.as_type.loc5_20 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit.loc5_20: <witness> = facet_access_witness %.Self.ref.loc5_20 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0.loc5_20: type = impl_witness_access %.Self.as_wit.loc5_20, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %.loc5_26.1: %empty_struct_type = struct_literal ()
 // CHECK:STDOUT:     %.loc5_26.2: type = converted %.loc5_26.1, constants.%empty_struct_type [template = constants.%empty_struct_type]
 // CHECK:STDOUT:     %.Self.ref.loc5_32: %M.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %X.ref.loc5_32: %assoc_type = name_ref X, @M.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %X.ref.loc5_32: %M.assoc_type = name_ref X, @X.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %.Self.as_type.loc5_32: type = facet_access_type %.Self.ref.loc5_32 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc5_32: type = converted %.Self.ref.loc5_32, %.Self.as_type.loc5_32 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit.loc5_32: <witness> = facet_access_witness %.Self.ref.loc5_32 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0.loc5_32: type = impl_witness_access %.Self.as_wit.loc5_32, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %.loc5_38.1: %empty_struct_type = struct_literal ()
@@ -860,20 +1036,29 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @M {
 // CHECK:STDOUT:   %Self: %M.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %X: type = assoc_const_decl X [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %X [template = constants.%assoc0]
+// CHECK:STDOUT:   %X: type = assoc_const_decl @X [template] {
+// CHECK:STDOUT:     %assoc0: %M.assoc_type = assoc_entity element0, @M.%X [template = constants.%assoc0]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .X = %assoc0
+// CHECK:STDOUT:   .X = @X.%assoc0
 // CHECK:STDOUT:   witness = (%X)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @X(@M.%Self: %M.type) {
+// CHECK:STDOUT:   assoc_const X:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %.loc5_7.2 as %.loc5_14 {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   witness = file.%impl_witness
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @X(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @X(constants.%M.facet) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: --- non-type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
@@ -882,10 +1067,12 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %struct_type.a.225: type = struct_type {.a: %empty_struct_type} [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %N.type, %struct_type.a.225 [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, @N.%Y [template]
+// CHECK:STDOUT:   %N.assoc_type: type = assoc_entity_type %N.type [template]
+// CHECK:STDOUT:   %assoc0: %N.assoc_type = assoc_entity element0, @N.%Y [template]
 // CHECK:STDOUT:   %.Self: %N.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %N.facet: %N.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: %struct_type.a.225 = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT:   %empty_struct: %empty_struct_type = struct_value () [template]
 // CHECK:STDOUT:   %struct: %struct_type.a.225 = struct_value (%empty_struct) [template]
@@ -904,7 +1091,9 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:     %N.ref: type = name_ref N, file.%N.decl [template = constants.%N.type]
 // CHECK:STDOUT:     %.Self: %N.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:     %.Self.ref: %N.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:     %Y.ref: %assoc_type = name_ref Y, @N.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %Y.ref: %N.assoc_type = name_ref Y, @Y.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:     %.loc7_20: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:     %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:     %impl.elem0: %struct_type.a.225 = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %.loc7_32: %empty_struct_type = struct_literal ()
@@ -922,17 +1111,26 @@ impl () as N where .Y = {.a = {}} { }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @N {
 // CHECK:STDOUT:   %Self: %N.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %Y: %struct_type.a.225 = assoc_const_decl Y [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %Y [template = constants.%assoc0]
+// CHECK:STDOUT:   %Y: %struct_type.a.225 = assoc_const_decl @Y [template] {
+// CHECK:STDOUT:     %assoc0: %N.assoc_type = assoc_entity element0, @N.%Y [template = constants.%assoc0]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .Y = %assoc0
+// CHECK:STDOUT:   .Y = @Y.%assoc0
 // CHECK:STDOUT:   witness = (%Y)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @Y(@N.%Self: %N.type) {
+// CHECK:STDOUT:   assoc_const Y:! %struct_type.a.225;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %.loc7_7.2 as %.loc7_14 {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   witness = file.%impl_witness
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @Y(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Y(constants.%N.facet) {}
+// CHECK:STDOUT:

+ 33 - 33
toolchain/check/testdata/impl/no_prelude/import_builtin_call.carbon

@@ -84,8 +84,8 @@ var n: Int(64) = MakeFromClass(FromLiteral(64) as OtherInt);
 // CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic]
 // CHECK:STDOUT:   %Op.type.31b: type = fn_type @Op.1 [template]
 // CHECK:STDOUT:   %Op.d59: %Op.type.31b = struct_value () [template]
-// CHECK:STDOUT:   %Op.assoc_type: type = assoc_entity_type %Add.type, %Op.type.31b [template]
-// CHECK:STDOUT:   %assoc0: %Op.assoc_type = assoc_entity element0, @Add.%Op.decl [template]
+// CHECK:STDOUT:   %Add.assoc_type: type = assoc_entity_type %Add.type [template]
+// CHECK:STDOUT:   %assoc0: %Add.assoc_type = assoc_entity element0, @Add.%Op.decl [template]
 // CHECK:STDOUT:   %IntLiteral.type: type = fn_type @IntLiteral [template]
 // CHECK:STDOUT:   %IntLiteral: %IntLiteral.type = struct_value () [template]
 // CHECK:STDOUT:   %Int.type: type = fn_type @Int [template]
@@ -232,7 +232,7 @@ var n: Int(64) = MakeFromClass(FromLiteral(64) as OtherInt);
 // CHECK:STDOUT:     %return.param: ref @Op.1.%Self.as_type.loc5_15.1 (%Self.as_type) = out_param runtime_param2
 // CHECK:STDOUT:     %return: ref @Op.1.%Self.as_type.loc5_15.1 (%Self.as_type) = return_slot %return.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc0: %Op.assoc_type = assoc_entity element0, %Op.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %Add.assoc_type = assoc_entity element0, %Op.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -335,7 +335,7 @@ var n: Int(64) = MakeFromClass(FromLiteral(64) as OtherInt);
 // CHECK:STDOUT:   !entry:
 // CHECK:STDOUT:     %x.ref.loc20_10: @Double.%MyInt.loc19_39.2 (%MyInt) = name_ref x, %x
 // CHECK:STDOUT:     %Add.ref: type = name_ref Add, file.%Add.decl [template = constants.%Add.type]
-// CHECK:STDOUT:     %Op.ref: %Op.assoc_type = name_ref Op, @Add.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %Op.ref: %Add.assoc_type = name_ref Op, @Add.%assoc0 [template = constants.%assoc0]
 // CHECK:STDOUT:     %impl.elem0: %Op.type.31b = impl_witness_access constants.%impl_witness, element0 [symbolic = %Op (constants.%Op.8bc)]
 // CHECK:STDOUT:     %Op.bound: <bound method> = bound_method %x.ref.loc20_10, %impl.elem0
 // CHECK:STDOUT:     %x.ref.loc20_21: @Double.%MyInt.loc19_39.2 (%MyInt) = name_ref x, %x
@@ -421,18 +421,18 @@ var n: Int(64) = MakeFromClass(FromLiteral(64) as OtherInt);
 // CHECK:STDOUT:   %complete_type.4a1: <witness> = complete_type_witness %i64.builtin [template]
 // CHECK:STDOUT:   %Add.type: type = facet_type <@Add> [template]
 // CHECK:STDOUT:   %Self: %Add.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %Op.type.31b: type = fn_type @Op.1 [template]
-// CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic]
-// CHECK:STDOUT:   %Op.assoc_type: type = assoc_entity_type %Add.type, %Op.type.31b [template]
-// CHECK:STDOUT:   %assoc0: %Op.assoc_type = assoc_entity element0, imports.%Main.import_ref.047 [template]
+// CHECK:STDOUT:   %Add.assoc_type: type = assoc_entity_type %Add.type [template]
+// CHECK:STDOUT:   %assoc0: %Add.assoc_type = assoc_entity element0, imports.%Main.import_ref.5a3 [template]
 // CHECK:STDOUT:   %impl_witness.3a3: <witness> = impl_witness (imports.%Main.import_ref.19b), @impl(%N) [symbolic]
-// CHECK:STDOUT:   %Op.type.883: type = fn_type @Op.2, @impl(%N) [symbolic]
+// CHECK:STDOUT:   %Op.type.883: type = fn_type @Op.1, @impl(%N) [symbolic]
 // CHECK:STDOUT:   %Op.8bc: %Op.type.883 = struct_value () [symbolic]
 // CHECK:STDOUT:   %require_complete.fc7: <witness> = require_complete_type %MyInt.09f [symbolic]
 // CHECK:STDOUT:   %impl_witness.8d6: <witness> = impl_witness (imports.%Main.import_ref.19b), @impl(%int_64) [template]
 // CHECK:STDOUT:   %impl_witness.7e5: <witness> = impl_witness (imports.%Main.import_ref.464), @impl(%N) [symbolic]
-// CHECK:STDOUT:   %Op.type.5a6: type = fn_type @Op.2, @impl(%int_64) [template]
+// CHECK:STDOUT:   %Op.type.5a6: type = fn_type @Op.1, @impl(%int_64) [template]
 // CHECK:STDOUT:   %Op.cf9: %Op.type.5a6 = struct_value () [template]
+// CHECK:STDOUT:   %Op.type.31b: type = fn_type @Op.2 [template]
+// CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic]
 // CHECK:STDOUT:   %CallImportedDouble.type: type = fn_type @CallImportedDouble [template]
 // CHECK:STDOUT:   %CallImportedDouble: %CallImportedDouble.type = struct_value () [template]
 // CHECK:STDOUT:   %Double.type: type = fn_type @Double [template]
@@ -449,7 +449,7 @@ var n: Int(64) = MakeFromClass(FromLiteral(64) as OtherInt);
 // CHECK:STDOUT:   %Main.import_ref.9e9: <witness> = import_ref Main//generic_impl, loc13_1, loaded [symbolic = @MyInt.%complete_type (constants.%complete_type.a87)]
 // CHECK:STDOUT:   %Main.import_ref.697 = import_ref Main//generic_impl, inst89 [no loc], unloaded
 // CHECK:STDOUT:   %Main.import_ref.07c = import_ref Main//generic_impl, inst15 [no loc], unloaded
-// CHECK:STDOUT:   %Main.import_ref.6d9: %Op.assoc_type = import_ref Main//generic_impl, loc5_41, loaded [template = constants.%assoc0]
+// CHECK:STDOUT:   %Main.import_ref.db7: %Add.assoc_type = import_ref Main//generic_impl, loc5_41, loaded [template = constants.%assoc0]
 // CHECK:STDOUT:   %Main.Op = import_ref Main//generic_impl, Op, unloaded
 // CHECK:STDOUT:   %Main.import_ref.33b: <witness> = import_ref Main//generic_impl, loc15_48, loaded [symbolic = @impl.%impl_witness (constants.%impl_witness.7e5)]
 // CHECK:STDOUT:   %Main.import_ref.719: type = import_ref Main//generic_impl, loc15_39, loaded [symbolic = @impl.%MyInt (constants.%MyInt.09f)]
@@ -511,7 +511,7 @@ var n: Int(64) = MakeFromClass(FromLiteral(64) as OtherInt);
 // CHECK:STDOUT: interface @Add [from "generic_impl.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = imports.%Main.import_ref.07c
-// CHECK:STDOUT:   .Op = imports.%Main.import_ref.6d9
+// CHECK:STDOUT:   .Op = imports.%Main.import_ref.db7
 // CHECK:STDOUT:   witness = (imports.%Main.Op)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -522,7 +522,7 @@ var n: Int(64) = MakeFromClass(FromLiteral(64) as OtherInt);
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (imports.%Main.import_ref.19b), @impl(%N) [symbolic = %impl_witness (constants.%impl_witness.3a3)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %Op.type: type = fn_type @Op.2, @impl(%N) [symbolic = %Op.type (constants.%Op.type.883)]
+// CHECK:STDOUT:   %Op.type: type = fn_type @Op.1, @impl(%N) [symbolic = %Op.type (constants.%Op.type.883)]
 // CHECK:STDOUT:   %Op: @impl.%Op.type (%Op.type.883) = struct_value () [symbolic = %Op (constants.%Op.8bc)]
 // CHECK:STDOUT:   %require_complete: <witness> = require_complete_type @impl.%MyInt (%MyInt.09f) [symbolic = %require_complete (constants.%require_complete.fc7)]
 // CHECK:STDOUT:
@@ -553,31 +553,31 @@ var n: Int(64) = MakeFromClass(FromLiteral(64) as OtherInt);
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %x.ref.loc9_10: %MyInt.f30 = name_ref x, %x
 // CHECK:STDOUT:   %Add.ref: type = name_ref Add, imports.%Main.Add [template = constants.%Add.type]
-// CHECK:STDOUT:   %Op.ref: %Op.assoc_type = name_ref Op, imports.%Main.import_ref.6d9 [template = constants.%assoc0]
+// CHECK:STDOUT:   %Op.ref: %Add.assoc_type = name_ref Op, imports.%Main.import_ref.db7 [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0: %Op.type.31b = impl_witness_access constants.%impl_witness.8d6, element0 [template = constants.%Op.cf9]
 // CHECK:STDOUT:   %Op.bound: <bound method> = bound_method %x.ref.loc9_10, %impl.elem0
 // CHECK:STDOUT:   %x.ref.loc9_21: %MyInt.f30 = name_ref x, %x
-// CHECK:STDOUT:   %Op.specific_fn: <specific function> = specific_function %Op.bound, @Op.2(constants.%int_64)
+// CHECK:STDOUT:   %Op.specific_fn: <specific function> = specific_function %Op.bound, @Op.1(constants.%int_64)
 // CHECK:STDOUT:   %int.sadd: init %MyInt.f30 = call %Op.specific_fn(%x.ref.loc9_10, %x.ref.loc9_21)
 // CHECK:STDOUT:   %.loc9_23.1: %MyInt.f30 = value_of_initializer %int.sadd
 // CHECK:STDOUT:   %.loc9_23.2: %MyInt.f30 = converted %int.sadd, %.loc9_23.1
 // CHECK:STDOUT:   return %.loc9_23.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: generic fn @Op.1(constants.%Self: %Add.type) [from "generic_impl.carbon"] {
-// CHECK:STDOUT:   %Self: %Add.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)]
-// CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic = %Self.as_type (constants.%Self.as_type)]
-// CHECK:STDOUT:
-// CHECK:STDOUT:   fn[%self.param_patt: @Op.1.%Self.as_type (%Self.as_type)](%other.param_patt: @Op.1.%Self.as_type (%Self.as_type)) -> @Op.1.%Self.as_type (%Self.as_type);
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
-// CHECK:STDOUT: generic fn @Op.2(constants.%N: Core.IntLiteral) [from "generic_impl.carbon"] {
+// CHECK:STDOUT: generic fn @Op.1(constants.%N: Core.IntLiteral) [from "generic_impl.carbon"] {
 // CHECK:STDOUT:   %N: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic = %N (constants.%N)]
 // CHECK:STDOUT:   %MyInt: type = class_type @MyInt, @MyInt(%N) [symbolic = %MyInt (constants.%MyInt.09f)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
-// CHECK:STDOUT:   fn[%self.param_patt: @Op.2.%MyInt (%MyInt.09f)](%other.param_patt: @Op.2.%MyInt (%MyInt.09f)) -> @Op.2.%MyInt (%MyInt.09f) = "int.sadd";
+// CHECK:STDOUT:   fn[%self.param_patt: @Op.1.%MyInt (%MyInt.09f)](%other.param_patt: @Op.1.%MyInt (%MyInt.09f)) -> @Op.1.%MyInt (%MyInt.09f) = "int.sadd";
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @Op.2(constants.%Self: %Add.type) [from "generic_impl.carbon"] {
+// CHECK:STDOUT:   %Self: %Add.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)]
+// CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic = %Self.as_type (constants.%Self.as_type)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn[%self.param_patt: @Op.2.%Self.as_type (%Self.as_type)](%other.param_patt: @Op.2.%Self.as_type (%Self.as_type)) -> @Op.2.%Self.as_type (%Self.as_type);
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @CallImportedDouble(%n.param_patt: %MyInt.f30) -> %MyInt.f30 {
@@ -598,7 +598,7 @@ var n: Int(64) = MakeFromClass(FromLiteral(64) as OtherInt);
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete: <witness> = require_complete_type @Double.%MyInt (%MyInt.09f) [symbolic = %require_complete (constants.%require_complete.fc7)]
-// CHECK:STDOUT:   %Op.type: type = fn_type @Op.2, @impl(%N) [symbolic = %Op.type (constants.%Op.type.883)]
+// CHECK:STDOUT:   %Op.type: type = fn_type @Op.1, @impl(%N) [symbolic = %Op.type (constants.%Op.type.883)]
 // CHECK:STDOUT:   %Op: @Double.%Op.type (%Op.type.883) = struct_value () [symbolic = %Op (constants.%Op.8bc)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn[%N.param_patt: Core.IntLiteral](%x.param_patt: @Double.%MyInt (%MyInt.09f)) -> @Double.%MyInt (%MyInt.09f);
@@ -624,11 +624,6 @@ var n: Int(64) = MakeFromClass(FromLiteral(64) as OtherInt);
 // CHECK:STDOUT:   %complete_type => constants.%complete_type.4a1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Op.1(constants.%Self) {
-// CHECK:STDOUT:   %Self => constants.%Self
-// CHECK:STDOUT:   %Self.as_type => constants.%Self.as_type
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl(constants.%N) {
 // CHECK:STDOUT:   %N => constants.%N
 // CHECK:STDOUT:   %N.patt => constants.%N
@@ -645,9 +640,9 @@ var n: Int(64) = MakeFromClass(FromLiteral(64) as OtherInt);
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl(%N) {}
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @MyInt(@Op.2.%N) {}
+// CHECK:STDOUT: specific @MyInt(@Op.1.%N) {}
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Op.2(constants.%N) {
+// CHECK:STDOUT: specific @Op.1(constants.%N) {
 // CHECK:STDOUT:   %N => constants.%N
 // CHECK:STDOUT:   %MyInt => constants.%MyInt.09f
 // CHECK:STDOUT:
@@ -666,7 +661,12 @@ var n: Int(64) = MakeFromClass(FromLiteral(64) as OtherInt);
 // CHECK:STDOUT:   %require_complete => constants.%complete_type.4a1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Op.2(constants.%int_64) {
+// CHECK:STDOUT: specific @Op.2(constants.%Self) {
+// CHECK:STDOUT:   %Self => constants.%Self
+// CHECK:STDOUT:   %Self.as_type => constants.%Self.as_type
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Op.1(constants.%int_64) {
 // CHECK:STDOUT:   %N => constants.%int_64
 // CHECK:STDOUT:   %MyInt => constants.%MyInt.f30
 // CHECK:STDOUT:

+ 10 - 12
toolchain/check/testdata/impl/no_prelude/import_extend_impl.carbon

@@ -40,8 +40,8 @@ fn G(c: C) {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %F.type.cf0: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.bc6: %F.type.cf0 = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %I.type, %F.type.cf0 [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @I.%F.decl [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @I.%F.decl [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (@impl.%F.decl) [template]
 // CHECK:STDOUT:   %F.type.f36: type = fn_type @F.2 [template]
@@ -63,7 +63,7 @@ fn G(c: C) {
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type.cf0 = fn_decl @F.1 [template = constants.%F.bc6] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -94,7 +94,6 @@ fn G(c: C) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(@I.%Self: %I.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -118,10 +117,10 @@ fn G(c: C) {
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
 // CHECK:STDOUT:   %I.type: type = facet_type <@I> [template]
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %F.type.cf0: type = fn_type @F.1 [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %I.type, %F.type.cf0 [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, imports.%Main.import_ref.777 [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, imports.%Main.import_ref.e03 [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (imports.%Main.import_ref.f6d) [template]
+// CHECK:STDOUT:   %F.type.cf0: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.type.f36: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.4c3: %F.type.f36 = struct_value () [template]
 // CHECK:STDOUT: }
@@ -133,7 +132,7 @@ fn G(c: C) {
 // CHECK:STDOUT:   %Main.import_ref.2c4 = import_ref Main//extend_impl_library, inst25 [no loc], unloaded
 // CHECK:STDOUT:   %Main.import_ref.3019d1.1: type = import_ref Main//extend_impl_library, loc9_18, loaded [template = constants.%I.type]
 // CHECK:STDOUT:   %Main.import_ref.e5d = import_ref Main//extend_impl_library, inst15 [no loc], unloaded
-// CHECK:STDOUT:   %Main.import_ref.b5b: %F.assoc_type = import_ref Main//extend_impl_library, loc5_9, loaded [template = constants.%assoc0]
+// CHECK:STDOUT:   %Main.import_ref.bcb: %I.assoc_type = import_ref Main//extend_impl_library, loc5_9, loaded [template = constants.%assoc0]
 // CHECK:STDOUT:   %Main.F = import_ref Main//extend_impl_library, F, unloaded
 // CHECK:STDOUT:   %Main.import_ref.b86: <witness> = import_ref Main//extend_impl_library, loc9_20, loaded [template = constants.%impl_witness]
 // CHECK:STDOUT:   %Main.import_ref.0ed: type = import_ref Main//extend_impl_library, loc9_15, loaded [template = constants.%C]
@@ -160,7 +159,7 @@ fn G(c: C) {
 // CHECK:STDOUT: interface @I [from "extend_impl_library.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = imports.%Main.import_ref.e5d
-// CHECK:STDOUT:   .F = imports.%Main.import_ref.b5b
+// CHECK:STDOUT:   .F = imports.%Main.import_ref.bcb
 // CHECK:STDOUT:   witness = (imports.%Main.F)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -180,18 +179,17 @@ fn G(c: C) {
 // CHECK:STDOUT: fn @G(%c.param_patt: %C) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %C.ref.loc7: type = name_ref C, imports.%Main.C [template = constants.%C]
-// CHECK:STDOUT:   %F.ref.loc7: %F.assoc_type = name_ref F, imports.%Main.import_ref.b5b [template = constants.%assoc0]
+// CHECK:STDOUT:   %F.ref.loc7: %I.assoc_type = name_ref F, imports.%Main.import_ref.bcb [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0.loc7: %F.type.cf0 = impl_witness_access constants.%impl_witness, element0 [template = constants.%F.4c3]
 // CHECK:STDOUT:   %F.call.loc7: init %empty_tuple.type = call %impl.elem0.loc7()
 // CHECK:STDOUT:   %c.ref: %C = name_ref c, %c
-// CHECK:STDOUT:   %F.ref.loc8: %F.assoc_type = name_ref F, imports.%Main.import_ref.b5b [template = constants.%assoc0]
+// CHECK:STDOUT:   %F.ref.loc8: %I.assoc_type = name_ref F, imports.%Main.import_ref.bcb [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0.loc8: %F.type.cf0 = impl_witness_access constants.%impl_witness, element0 [template = constants.%F.4c3]
 // CHECK:STDOUT:   %F.call.loc8: init %empty_tuple.type = call %impl.elem0.loc8()
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(constants.%Self: %I.type) [from "extend_impl_library.carbon"] {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

Разница между файлами не показана из-за своего большого размера
+ 326 - 103
toolchain/check/testdata/impl/no_prelude/import_interface_assoc_const.carbon


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

@@ -38,8 +38,8 @@ fn F(x: (), y: ()) -> () {
 // CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic]
 // CHECK:STDOUT:   %Op.type: type = fn_type @Op [template]
 // CHECK:STDOUT:   %Op: %Op.type = struct_value () [template]
-// CHECK:STDOUT:   %Op.assoc_type: type = assoc_entity_type %Add.type, %Op.type [template]
-// CHECK:STDOUT:   %assoc0: %Op.assoc_type = assoc_entity element0, @Add.%Op.decl [template]
+// CHECK:STDOUT:   %Add.assoc_type: type = assoc_entity_type %Add.type [template]
+// CHECK:STDOUT:   %assoc0: %Add.assoc_type = assoc_entity element0, @Add.%Op.decl [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -79,7 +79,7 @@ fn F(x: (), y: ()) -> () {
 // CHECK:STDOUT:     %return.param: ref @Op.%Self.as_type.loc5_15.1 (%Self.as_type) = out_param runtime_param2
 // CHECK:STDOUT:     %return: ref @Op.%Self.as_type.loc5_15.1 (%Self.as_type) = return_slot %return.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc0: %Op.assoc_type = assoc_entity element0, %Op.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %Add.assoc_type = assoc_entity element0, %Op.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -115,14 +115,14 @@ fn F(x: (), y: ()) -> () {
 // CHECK:STDOUT:   %empty_tuple: %empty_tuple.type = tuple_value () [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %Op.assoc_type: type = assoc_entity_type %Add.type, %Op.type.31b [template]
-// CHECK:STDOUT:   %assoc0: %Op.assoc_type = assoc_entity element0, imports.%Main.import_ref.047 [template]
+// CHECK:STDOUT:   %Add.assoc_type: type = assoc_entity_type %Add.type [template]
+// CHECK:STDOUT:   %assoc0: %Add.assoc_type = assoc_entity element0, imports.%Main.import_ref.5a3 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Main.Add: type = import_ref Main//a, Add, loaded [template = constants.%Add.type]
 // CHECK:STDOUT:   %Main.import_ref.07c = import_ref Main//a, inst15 [no loc], unloaded
-// CHECK:STDOUT:   %Main.import_ref.6d9: %Op.assoc_type = import_ref Main//a, loc5_41, loaded [template = constants.%assoc0]
+// CHECK:STDOUT:   %Main.import_ref.db7: %Add.assoc_type = import_ref Main//a, loc5_41, loaded [template = constants.%assoc0]
 // CHECK:STDOUT:   %Main.Op: %Op.type.31b = import_ref Main//a, Op, loaded [template = constants.%Op.d59]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -168,7 +168,7 @@ fn F(x: (), y: ()) -> () {
 // CHECK:STDOUT: interface @Add [from "a.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = imports.%Main.import_ref.07c
-// CHECK:STDOUT:   .Op = imports.%Main.import_ref.6d9
+// CHECK:STDOUT:   .Op = imports.%Main.import_ref.db7
 // CHECK:STDOUT:   witness = (imports.%Main.Op)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -216,7 +216,7 @@ fn F(x: (), y: ()) -> () {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %x.ref: %empty_tuple.type = name_ref x, %x
 // CHECK:STDOUT:   %Add.ref: type = name_ref Add, imports.%Main.Add [template = constants.%Add.type]
-// CHECK:STDOUT:   %Op.ref: %Op.assoc_type = name_ref Op, imports.%Main.import_ref.6d9 [template = constants.%assoc0]
+// CHECK:STDOUT:   %Op.ref: %Add.assoc_type = name_ref Op, imports.%Main.import_ref.db7 [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0: %Op.type.31b = impl_witness_access constants.%impl_witness, element0 [template = constants.%Op.489]
 // CHECK:STDOUT:   %Op.bound: <bound method> = bound_method %x.ref, %impl.elem0
 // CHECK:STDOUT:   %y.ref: %empty_tuple.type = name_ref y, %y

+ 21 - 23
toolchain/check/testdata/impl/no_prelude/import_use_generic.carbon

@@ -54,8 +54,8 @@ fn F() -> c.(I.F)() {}
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %F.type.cf0: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.bc6: %F.type.cf0 = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %I.type, %F.type.cf0 [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @I.%F.decl [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @I.%F.decl [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (@impl.%F.decl), @impl(%T) [symbolic]
 // CHECK:STDOUT:   %F.type.40c: type = fn_type @F.2, @impl(%T) [symbolic]
 // CHECK:STDOUT:   %F.071: %F.type.40c = struct_value () [symbolic]
@@ -92,7 +92,7 @@ fn F() -> c.(I.F)() {}
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type.cf0 = fn_decl @F.1 [template = constants.%F.bc6] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -135,7 +135,6 @@ fn F() -> c.(I.F)() {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(@I.%Self: %I.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -189,17 +188,17 @@ fn F() -> c.(I.F)() {}
 // CHECK:STDOUT:   %C.val: %C.7a7 = struct_value () [template]
 // CHECK:STDOUT:   %I.type: type = facet_type <@I> [template]
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %F.type.cf0: type = fn_type @F.1 [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %I.type, %F.type.cf0 [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, imports.%Main.import_ref.777 [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, imports.%Main.import_ref.e03 [template]
 // CHECK:STDOUT:   %impl_witness.681: <witness> = impl_witness (imports.%Main.import_ref.e2c), @impl(%T) [symbolic]
-// CHECK:STDOUT:   %F.type.40c: type = fn_type @F.2, @impl(%T) [symbolic]
+// CHECK:STDOUT:   %F.type.40c: type = fn_type @F.1, @impl(%T) [symbolic]
 // CHECK:STDOUT:   %F.071: %F.type.40c = struct_value () [symbolic]
 // CHECK:STDOUT:   %impl_witness.02b: <witness> = impl_witness (imports.%Main.import_ref.e2c), @impl(%empty_struct_type) [template]
 // CHECK:STDOUT:   %impl_witness.bbe: <witness> = impl_witness (imports.%Main.import_ref.c57), @impl(%T) [symbolic]
-// CHECK:STDOUT:   %F.type.4a4: type = fn_type @F.2, @impl(%empty_struct_type) [template]
+// CHECK:STDOUT:   %F.type.4a4: type = fn_type @F.1, @impl(%empty_struct_type) [template]
 // CHECK:STDOUT:   %F.9e6: %F.type.4a4 = struct_value () [template]
-// CHECK:STDOUT:   %F.specific_fn: <specific function> = specific_function %F.9e6, @F.2(%empty_struct_type) [template]
+// CHECK:STDOUT:   %F.type.cf0: type = fn_type @F.2 [template]
+// CHECK:STDOUT:   %F.specific_fn: <specific function> = specific_function %F.9e6, @F.1(%empty_struct_type) [template]
 // CHECK:STDOUT:   %F.type.b25: type = fn_type @F.3 [template]
 // CHECK:STDOUT:   %F.c41: %F.type.b25 = struct_value () [template]
 // CHECK:STDOUT: }
@@ -210,7 +209,7 @@ fn F() -> c.(I.F)() {}
 // CHECK:STDOUT:   %Main.import_ref.8f2: <witness> = import_ref Main//import_generic, loc4_20, loaded [template = constants.%complete_type]
 // CHECK:STDOUT:   %Main.import_ref.4c0 = import_ref Main//import_generic, inst25 [no loc], unloaded
 // CHECK:STDOUT:   %Main.import_ref.e5d = import_ref Main//import_generic, inst31 [no loc], unloaded
-// CHECK:STDOUT:   %Main.import_ref.b5b: %F.assoc_type = import_ref Main//import_generic, loc7_9, loaded [template = constants.%assoc0]
+// CHECK:STDOUT:   %Main.import_ref.bcb: %I.assoc_type = import_ref Main//import_generic, loc7_9, loaded [template = constants.%assoc0]
 // CHECK:STDOUT:   %Main.F = import_ref Main//import_generic, F, unloaded
 // CHECK:STDOUT:   %Main.import_ref.d91: <witness> = import_ref Main//import_generic, loc10_34, loaded [symbolic = @impl.%impl_witness (constants.%impl_witness.bbe)]
 // CHECK:STDOUT:   %Main.import_ref.499: type = import_ref Main//import_generic, loc10_27, loaded [symbolic = @impl.%C (constants.%C.f2e)]
@@ -244,9 +243,9 @@ fn F() -> c.(I.F)() {}
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %c.ref: ref %C.7a7 = name_ref c, file.%c
 // CHECK:STDOUT:     %I.ref: type = name_ref I, imports.%Main.I [template = constants.%I.type]
-// CHECK:STDOUT:     %F.ref: %F.assoc_type = name_ref F, imports.%Main.import_ref.b5b [template = constants.%assoc0]
+// CHECK:STDOUT:     %F.ref: %I.assoc_type = name_ref F, imports.%Main.import_ref.bcb [template = constants.%assoc0]
 // CHECK:STDOUT:     %impl.elem0: %F.type.cf0 = impl_witness_access constants.%impl_witness.02b, element0 [template = constants.%F.9e6]
-// CHECK:STDOUT:     %F.specific_fn: <specific function> = specific_function %impl.elem0, @F.2(constants.%empty_struct_type) [template = constants.%F.specific_fn]
+// CHECK:STDOUT:     %F.specific_fn: <specific function> = specific_function %impl.elem0, @F.1(constants.%empty_struct_type) [template = constants.%F.specific_fn]
 // CHECK:STDOUT:     %F.call: init %empty_tuple.type = call %F.specific_fn()
 // CHECK:STDOUT:     %.loc16_19.1: ref %empty_tuple.type = temporary_storage
 // CHECK:STDOUT:     %.loc16_19.2: ref %empty_tuple.type = temporary %.loc16_19.1, %F.call
@@ -259,7 +258,7 @@ fn F() -> c.(I.F)() {}
 // CHECK:STDOUT: interface @I [from "import_generic.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = imports.%Main.import_ref.e5d
-// CHECK:STDOUT:   .F = imports.%Main.import_ref.b5b
+// CHECK:STDOUT:   .F = imports.%Main.import_ref.bcb
 // CHECK:STDOUT:   witness = (imports.%Main.F)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -270,7 +269,7 @@ fn F() -> c.(I.F)() {}
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (imports.%Main.import_ref.e2c), @impl(%T) [symbolic = %impl_witness (constants.%impl_witness.681)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %F.type: type = fn_type @F.2, @impl(%T) [symbolic = %F.type (constants.%F.type.40c)]
+// CHECK:STDOUT:   %F.type: type = fn_type @F.1, @impl(%T) [symbolic = %F.type (constants.%F.type.40c)]
 // CHECK:STDOUT:   %F: @impl.%F.type (%F.type.40c) = struct_value () [symbolic = %F (constants.%F.071)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   impl: imports.%Main.import_ref.499 as imports.%Main.import_ref.301 {
@@ -293,14 +292,13 @@ fn F() -> c.(I.F)() {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: generic fn @F.1(constants.%Self: %I.type) [from "import_generic.carbon"] {
+// CHECK:STDOUT: generic fn @F.1(constants.%T: type) [from "import_generic.carbon"] {
+// CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: generic fn @F.2(constants.%T: type) [from "import_generic.carbon"] {
-// CHECK:STDOUT: !definition:
-// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @F.2(constants.%Self: %I.type) [from "import_generic.carbon"] {
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -329,8 +327,6 @@ fn F() -> c.(I.F)() {}
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @F.1(constants.%Self) {}
-// CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl(constants.%T) {
 // CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT:   %T.patt => constants.%T
@@ -346,7 +342,7 @@ fn F() -> c.(I.F)() {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl(%T) {}
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @F.2(constants.%T) {}
+// CHECK:STDOUT: specific @F.1(constants.%T) {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl(constants.%empty_struct_type) {
 // CHECK:STDOUT:   %T => constants.%empty_struct_type
@@ -359,7 +355,9 @@ fn F() -> c.(I.F)() {}
 // CHECK:STDOUT:   %F => constants.%F.9e6
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @F.2(constants.%empty_struct_type) {
+// CHECK:STDOUT: specific @F.2(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F.1(constants.%empty_struct_type) {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 80 - 83
toolchain/check/testdata/impl/no_prelude/interface_args.carbon

@@ -91,8 +91,8 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Self: %Action.type.cca = bind_symbolic_name Self, 1 [symbolic]
 // CHECK:STDOUT:   %Op.type.036: type = fn_type @Op.1, @Action(%T) [symbolic]
 // CHECK:STDOUT:   %Op.6ed: %Op.type.036 = struct_value () [symbolic]
-// CHECK:STDOUT:   %Op.assoc_type.2ba: type = assoc_entity_type %Action.type.cca, %Op.type.036 [symbolic]
-// CHECK:STDOUT:   %assoc0.0aa: %Op.assoc_type.2ba = assoc_entity element0, @Action.%Op.decl [symbolic]
+// CHECK:STDOUT:   %Action.assoc_type.8f9: type = assoc_entity_type %Action.type.cca [symbolic]
+// CHECK:STDOUT:   %assoc0.69b: %Action.assoc_type.8f9 = assoc_entity element0, @Action.%Op.decl [symbolic]
 // CHECK:STDOUT:   %A: type = class_type @A [template]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [template]
@@ -101,8 +101,8 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Action.type.cb0: type = facet_type <@Action, @Action(%B)> [template]
 // CHECK:STDOUT:   %Op.type.54d: type = fn_type @Op.1, @Action(%B) [template]
 // CHECK:STDOUT:   %Op.dba: %Op.type.54d = struct_value () [template]
-// CHECK:STDOUT:   %Op.assoc_type.e7a: type = assoc_entity_type %Action.type.cb0, %Op.type.54d [template]
-// CHECK:STDOUT:   %assoc0.64a: %Op.assoc_type.e7a = assoc_entity element0, @Action.%Op.decl [template]
+// CHECK:STDOUT:   %Action.assoc_type.827: type = assoc_entity_type %Action.type.cb0 [template]
+// CHECK:STDOUT:   %assoc0.035: %Action.assoc_type.827 = assoc_entity element0, @Action.%Op.decl [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (@impl.%Op.decl) [template]
 // CHECK:STDOUT:   %Op.type.4b4: type = fn_type @Op.2 [template]
 // CHECK:STDOUT:   %Op.40d: %Op.type.4b4 = struct_value () [template]
@@ -155,13 +155,13 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Self.2: %Action.type.cca = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
 // CHECK:STDOUT:   %Op.type: type = fn_type @Op.1, @Action(%T.loc4_18.2) [symbolic = %Op.type (constants.%Op.type.036)]
 // CHECK:STDOUT:   %Op: @Action.%Op.type (%Op.type.036) = struct_value () [symbolic = %Op (constants.%Op.6ed)]
-// CHECK:STDOUT:   %Op.assoc_type: type = assoc_entity_type @Action.%Action.type (%Action.type.cca), @Action.%Op.type (%Op.type.036) [symbolic = %Op.assoc_type (constants.%Op.assoc_type.2ba)]
-// CHECK:STDOUT:   %assoc0.loc5_10.2: @Action.%Op.assoc_type (%Op.assoc_type.2ba) = assoc_entity element0, %Op.decl [symbolic = %assoc0.loc5_10.2 (constants.%assoc0.0aa)]
+// CHECK:STDOUT:   %Action.assoc_type: type = assoc_entity_type @Action.%Action.type (%Action.type.cca) [symbolic = %Action.assoc_type (constants.%Action.assoc_type.8f9)]
+// CHECK:STDOUT:   %assoc0.loc5_10.2: @Action.%Action.assoc_type (%Action.assoc_type.8f9) = assoc_entity element0, %Op.decl [symbolic = %assoc0.loc5_10.2 (constants.%assoc0.69b)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:     %Self.1: @Action.%Action.type (%Action.type.cca) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
 // CHECK:STDOUT:     %Op.decl: @Action.%Op.type (%Op.type.036) = fn_decl @Op.1 [symbolic = @Action.%Op (constants.%Op.6ed)] {} {}
-// CHECK:STDOUT:     %assoc0.loc5_10.1: @Action.%Op.assoc_type (%Op.assoc_type.2ba) = assoc_entity element0, %Op.decl [symbolic = %assoc0.loc5_10.2 (constants.%assoc0.0aa)]
+// CHECK:STDOUT:     %assoc0.loc5_10.1: @Action.%Action.assoc_type (%Action.assoc_type.8f9) = assoc_entity element0, %Op.decl [symbolic = %assoc0.loc5_10.2 (constants.%assoc0.69b)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = %Self.1
@@ -203,7 +203,6 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @Op.1(@Action.%T.loc4_18.1: type, @Action.%Self.1: @Action.%Action.type (%Action.type.cca)) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -218,8 +217,8 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Action.ref: %Action.type.29c = name_ref Action, file.%Action.decl [template = constants.%Action.generic]
 // CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B.decl [template = constants.%B]
 // CHECK:STDOUT:   %Action.type: type = facet_type <@Action, @Action(constants.%B)> [template = constants.%Action.type.cb0]
-// CHECK:STDOUT:   %.loc16: %Op.assoc_type.e7a = specific_constant @Action.%assoc0.loc5_10.1, @Action(constants.%B) [template = constants.%assoc0.64a]
-// CHECK:STDOUT:   %Op.ref: %Op.assoc_type.e7a = name_ref Op, %.loc16 [template = constants.%assoc0.64a]
+// CHECK:STDOUT:   %.loc16: %Action.assoc_type.827 = specific_constant @Action.%assoc0.loc5_10.1, @Action(constants.%B) [template = constants.%assoc0.035]
+// CHECK:STDOUT:   %Op.ref: %Action.assoc_type.827 = name_ref Op, %.loc16 [template = constants.%assoc0.035]
 // CHECK:STDOUT:   %impl.elem0: %Op.type.54d = impl_witness_access constants.%impl_witness, element0 [template = constants.%Op.40d]
 // CHECK:STDOUT:   %Op.call: init %empty_tuple.type = call %impl.elem0()
 // CHECK:STDOUT:   return
@@ -243,8 +242,8 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Self.2 => constants.%Self
 // CHECK:STDOUT:   %Op.type => constants.%Op.type.54d
 // CHECK:STDOUT:   %Op => constants.%Op.dba
-// CHECK:STDOUT:   %Op.assoc_type => constants.%Op.assoc_type.e7a
-// CHECK:STDOUT:   %assoc0.loc5_10.2 => constants.%assoc0.64a
+// CHECK:STDOUT:   %Action.assoc_type => constants.%Action.assoc_type.827
+// CHECK:STDOUT:   %assoc0.loc5_10.2 => constants.%assoc0.035
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @Op.1(constants.%B, constants.%Action.facet) {}
@@ -266,15 +265,15 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %A: type = class_type @A [template]
 // CHECK:STDOUT:   %Op.type.036: type = fn_type @Op.1, @Action(%T) [symbolic]
 // CHECK:STDOUT:   %Op.6ed: %Op.type.036 = struct_value () [symbolic]
-// CHECK:STDOUT:   %Op.assoc_type.2ba: type = assoc_entity_type %Action.type.cca, %Op.type.036 [symbolic]
-// CHECK:STDOUT:   %assoc0.9b9b19.1: %Op.assoc_type.2ba = assoc_entity element0, imports.%Main.import_ref.0e3753.1 [symbolic]
+// CHECK:STDOUT:   %Action.assoc_type.8f9: type = assoc_entity_type %Action.type.cca [symbolic]
+// CHECK:STDOUT:   %assoc0.905ab9.1: %Action.assoc_type.8f9 = assoc_entity element0, imports.%Main.import_ref.0e3753.1 [symbolic]
 // CHECK:STDOUT:   %Op.type.54d: type = fn_type @Op.1, @Action(%B) [template]
 // CHECK:STDOUT:   %Op.dba: %Op.type.54d = struct_value () [template]
-// CHECK:STDOUT:   %Op.assoc_type.e7a: type = assoc_entity_type %Action.type.cb0, %Op.type.54d [template]
-// CHECK:STDOUT:   %assoc0.b39: %Op.assoc_type.e7a = assoc_entity element0, imports.%Main.import_ref.0e3753.2 [template]
+// CHECK:STDOUT:   %Action.assoc_type.827: type = assoc_entity_type %Action.type.cb0 [template]
+// CHECK:STDOUT:   %assoc0.4cc: %Action.assoc_type.827 = assoc_entity element0, imports.%Main.import_ref.1f6 [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
-// CHECK:STDOUT:   %assoc0.9b9b19.2: %Op.assoc_type.2ba = assoc_entity element0, imports.%Main.import_ref.0e3753.3 [symbolic]
+// CHECK:STDOUT:   %assoc0.905ab9.2: %Action.assoc_type.8f9 = assoc_entity element0, imports.%Main.import_ref.0e3753.2 [symbolic]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (imports.%Main.import_ref.d0b) [template]
 // CHECK:STDOUT:   %Op.type.4b4: type = fn_type @Op.2 [template]
 // CHECK:STDOUT:   %Op.40d: %Op.type.4b4 = struct_value () [template]
@@ -290,7 +289,7 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Main.import_ref.8f24d3.1: <witness> = import_ref Main//action, loc9_10, loaded [template = constants.%complete_type]
 // CHECK:STDOUT:   %Main.import_ref.54a = import_ref Main//action, inst46 [no loc], unloaded
 // CHECK:STDOUT:   %Main.import_ref.ddc = import_ref Main//action, inst26 [no loc], unloaded
-// CHECK:STDOUT:   %Main.import_ref.f86: @Action.%Op.assoc_type (%Op.assoc_type.2ba) = import_ref Main//action, loc5_10, loaded [symbolic = @Action.%assoc0 (constants.%assoc0.9b9b19.2)]
+// CHECK:STDOUT:   %Main.import_ref.318: @Action.%Action.assoc_type (%Action.assoc_type.8f9) = import_ref Main//action, loc5_10, loaded [symbolic = @Action.%assoc0 (constants.%assoc0.905ab9.2)]
 // CHECK:STDOUT:   %Main.Op = import_ref Main//action, Op, unloaded
 // CHECK:STDOUT:   %Main.import_ref.8f24d3.2: <witness> = import_ref Main//action, loc8_10, loaded [template = constants.%complete_type]
 // CHECK:STDOUT:   %Main.import_ref.da3 = import_ref Main//action, inst41 [no loc], unloaded
@@ -330,13 +329,13 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Self: %Action.type.cca = 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.036)]
 // CHECK:STDOUT:   %Op: @Action.%Op.type (%Op.type.036) = struct_value () [symbolic = %Op (constants.%Op.6ed)]
-// CHECK:STDOUT:   %Op.assoc_type: type = assoc_entity_type @Action.%Action.type (%Action.type.cca), @Action.%Op.type (%Op.type.036) [symbolic = %Op.assoc_type (constants.%Op.assoc_type.2ba)]
-// CHECK:STDOUT:   %assoc0: @Action.%Op.assoc_type (%Op.assoc_type.2ba) = assoc_entity element0, imports.%Main.import_ref.0e3753.1 [symbolic = %assoc0 (constants.%assoc0.9b9b19.1)]
+// CHECK:STDOUT:   %Action.assoc_type: type = assoc_entity_type @Action.%Action.type (%Action.type.cca) [symbolic = %Action.assoc_type (constants.%Action.assoc_type.8f9)]
+// CHECK:STDOUT:   %assoc0: @Action.%Action.assoc_type (%Action.assoc_type.8f9) = assoc_entity element0, imports.%Main.import_ref.0e3753.1 [symbolic = %assoc0 (constants.%assoc0.905ab9.1)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = imports.%Main.import_ref.ddc
-// CHECK:STDOUT:     .Op = imports.%Main.import_ref.f86
+// CHECK:STDOUT:     .Op = imports.%Main.import_ref.318
 // CHECK:STDOUT:     witness = (imports.%Main.Op)
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -362,7 +361,6 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @Op.1(constants.%T: type, constants.%Self: %Action.type.cca) [from "action.carbon"] {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -372,8 +370,8 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Action.ref: %Action.type.29c = name_ref Action, imports.%Main.Action [template = constants.%Action.generic]
 // CHECK:STDOUT:   %B.ref: type = name_ref B, imports.%Main.B [template = constants.%B]
 // CHECK:STDOUT:   %Action.type: type = facet_type <@Action, @Action(constants.%B)> [template = constants.%Action.type.cb0]
-// CHECK:STDOUT:   %.loc4: %Op.assoc_type.e7a = specific_constant imports.%Main.import_ref.f86, @Action(constants.%B) [template = constants.%assoc0.b39]
-// CHECK:STDOUT:   %Op.ref: %Op.assoc_type.e7a = name_ref Op, %.loc4 [template = constants.%assoc0.b39]
+// CHECK:STDOUT:   %.loc4: %Action.assoc_type.827 = specific_constant imports.%Main.import_ref.318, @Action(constants.%B) [template = constants.%assoc0.4cc]
+// CHECK:STDOUT:   %Op.ref: %Action.assoc_type.827 = name_ref Op, %.loc4 [template = constants.%assoc0.4cc]
 // CHECK:STDOUT:   %impl.elem0: %Op.type.54d = impl_witness_access constants.%impl_witness, element0 [template = constants.%Op.40d]
 // CHECK:STDOUT:   %Op.call: init %empty_tuple.type = call %impl.elem0()
 // CHECK:STDOUT:   return
@@ -395,8 +393,8 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT:   %Op.type => constants.%Op.type.54d
 // CHECK:STDOUT:   %Op => constants.%Op.dba
-// CHECK:STDOUT:   %Op.assoc_type => constants.%Op.assoc_type.e7a
-// CHECK:STDOUT:   %assoc0 => constants.%assoc0.b39
+// CHECK:STDOUT:   %Action.assoc_type => constants.%Action.assoc_type.827
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.4cc
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @Action(%T) {}
@@ -419,21 +417,21 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %A: type = class_type @A [template]
 // CHECK:STDOUT:   %Op.type.036: type = fn_type @Op, @Action(%T) [symbolic]
 // CHECK:STDOUT:   %Op.6ed: %Op.type.036 = struct_value () [symbolic]
-// CHECK:STDOUT:   %Op.assoc_type.2ba: type = assoc_entity_type %Action.type.cca, %Op.type.036 [symbolic]
-// CHECK:STDOUT:   %assoc0.9b9b19.1: %Op.assoc_type.2ba = assoc_entity element0, imports.%Main.import_ref.0e3753.1 [symbolic]
+// CHECK:STDOUT:   %Action.assoc_type.8f9: type = assoc_entity_type %Action.type.cca [symbolic]
+// CHECK:STDOUT:   %assoc0.905ab9.1: %Action.assoc_type.8f9 = assoc_entity element0, imports.%Main.import_ref.0e3753.1 [symbolic]
 // CHECK:STDOUT:   %Op.type.54d: type = fn_type @Op, @Action(%B) [template]
 // CHECK:STDOUT:   %Op.dba: %Op.type.54d = struct_value () [template]
-// CHECK:STDOUT:   %Op.assoc_type.e7a: type = assoc_entity_type %Action.type.cb0, %Op.type.54d [template]
-// CHECK:STDOUT:   %assoc0.b39: %Op.assoc_type.e7a = assoc_entity element0, imports.%Main.import_ref.0e3753.2 [template]
+// CHECK:STDOUT:   %Action.assoc_type.827: type = assoc_entity_type %Action.type.cb0 [template]
+// CHECK:STDOUT:   %assoc0.8f8: %Action.assoc_type.827 = assoc_entity element0, imports.%Main.import_ref.0e3753.2 [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %Action.type.e2b: type = facet_type <@Action, @Action(%C)> [template]
 // CHECK:STDOUT:   %Op.type.5ad: type = fn_type @Op, @Action(%C) [template]
 // CHECK:STDOUT:   %Op.b10: %Op.type.5ad = struct_value () [template]
-// CHECK:STDOUT:   %Op.assoc_type.17b: type = assoc_entity_type %Action.type.e2b, %Op.type.5ad [template]
-// CHECK:STDOUT:   %assoc0.ccd: %Op.assoc_type.17b = assoc_entity element0, imports.%Main.import_ref.0e3753.1 [template]
-// CHECK:STDOUT:   %assoc0.9b9b19.2: %Op.assoc_type.2ba = assoc_entity element0, imports.%Main.import_ref.0e3753.3 [symbolic]
+// CHECK:STDOUT:   %Action.assoc_type.0a7: type = assoc_entity_type %Action.type.e2b [template]
+// CHECK:STDOUT:   %assoc0.85d: %Action.assoc_type.0a7 = assoc_entity element0, imports.%Main.import_ref.0e3753.1 [template]
+// CHECK:STDOUT:   %assoc0.905ab9.2: %Action.assoc_type.8f9 = assoc_entity element0, imports.%Main.import_ref.0e3753.3 [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -446,7 +444,7 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Main.import_ref.8f24d3.1: <witness> = import_ref Main//action, loc9_10, loaded [template = constants.%complete_type]
 // CHECK:STDOUT:   %Main.import_ref.54a = import_ref Main//action, inst46 [no loc], unloaded
 // CHECK:STDOUT:   %Main.import_ref.ddc = import_ref Main//action, inst26 [no loc], unloaded
-// CHECK:STDOUT:   %Main.import_ref.f86: @Action.%Op.assoc_type (%Op.assoc_type.2ba) = import_ref Main//action, loc5_10, loaded [symbolic = @Action.%assoc0 (constants.%assoc0.9b9b19.2)]
+// CHECK:STDOUT:   %Main.import_ref.318: @Action.%Action.assoc_type (%Action.assoc_type.8f9) = import_ref Main//action, loc5_10, loaded [symbolic = @Action.%assoc0 (constants.%assoc0.905ab9.2)]
 // CHECK:STDOUT:   %Main.Op = import_ref Main//action, Op, unloaded
 // CHECK:STDOUT:   %Main.import_ref.8f24d3.2: <witness> = import_ref Main//action, loc8_10, loaded [template = constants.%complete_type]
 // CHECK:STDOUT:   %Main.import_ref.da3 = import_ref Main//action, inst41 [no loc], unloaded
@@ -488,13 +486,13 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Self: %Action.type.cca = 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.036)]
 // CHECK:STDOUT:   %Op: @Action.%Op.type (%Op.type.036) = struct_value () [symbolic = %Op (constants.%Op.6ed)]
-// CHECK:STDOUT:   %Op.assoc_type: type = assoc_entity_type @Action.%Action.type (%Action.type.cca), @Action.%Op.type (%Op.type.036) [symbolic = %Op.assoc_type (constants.%Op.assoc_type.2ba)]
-// CHECK:STDOUT:   %assoc0: @Action.%Op.assoc_type (%Op.assoc_type.2ba) = assoc_entity element0, imports.%Main.import_ref.0e3753.1 [symbolic = %assoc0 (constants.%assoc0.9b9b19.1)]
+// CHECK:STDOUT:   %Action.assoc_type: type = assoc_entity_type @Action.%Action.type (%Action.type.cca) [symbolic = %Action.assoc_type (constants.%Action.assoc_type.8f9)]
+// CHECK:STDOUT:   %assoc0: @Action.%Action.assoc_type (%Action.assoc_type.8f9) = assoc_entity element0, imports.%Main.import_ref.0e3753.1 [symbolic = %assoc0 (constants.%assoc0.905ab9.1)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = imports.%Main.import_ref.ddc
-// CHECK:STDOUT:     .Op = imports.%Main.import_ref.f86
+// CHECK:STDOUT:     .Op = imports.%Main.import_ref.318
 // CHECK:STDOUT:     witness = (imports.%Main.Op)
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -527,7 +525,6 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @Op(constants.%T: type, constants.%Self: %Action.type.cca) [from "action.carbon"] {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -537,8 +534,8 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Action.ref: %Action.type.29c = name_ref Action, imports.%Main.Action [template = constants.%Action.generic]
 // CHECK:STDOUT:   %C.ref: type = name_ref C, imports.%Main.C [template = constants.%C]
 // CHECK:STDOUT:   %Action.type: type = facet_type <@Action, @Action(constants.%C)> [template = constants.%Action.type.e2b]
-// CHECK:STDOUT:   %.loc8: %Op.assoc_type.17b = specific_constant imports.%Main.import_ref.f86, @Action(constants.%C) [template = constants.%assoc0.ccd]
-// CHECK:STDOUT:   %Op.ref: %Op.assoc_type.17b = name_ref Op, %.loc8 [template = constants.%assoc0.ccd]
+// CHECK:STDOUT:   %.loc8: %Action.assoc_type.0a7 = specific_constant imports.%Main.import_ref.318, @Action(constants.%C) [template = constants.%assoc0.85d]
+// CHECK:STDOUT:   %Op.ref: %Action.assoc_type.0a7 = name_ref Op, %.loc8 [template = constants.%assoc0.85d]
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -556,8 +553,8 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT:   %Op.type => constants.%Op.type.54d
 // CHECK:STDOUT:   %Op => constants.%Op.dba
-// CHECK:STDOUT:   %Op.assoc_type => constants.%Op.assoc_type.e7a
-// CHECK:STDOUT:   %assoc0 => constants.%assoc0.b39
+// CHECK:STDOUT:   %Action.assoc_type => constants.%Action.assoc_type.827
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.8f8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @Action(%T) {}
@@ -573,8 +570,8 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT:   %Op.type => constants.%Op.type.5ad
 // CHECK:STDOUT:   %Op => constants.%Op.b10
-// CHECK:STDOUT:   %Op.assoc_type => constants.%Op.assoc_type.17b
-// CHECK:STDOUT:   %assoc0 => constants.%assoc0.ccd
+// CHECK:STDOUT:   %Action.assoc_type => constants.%Action.assoc_type.0a7
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.85d
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- factory.carbon
@@ -588,8 +585,8 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Self: %Factory.type.c96 = bind_symbolic_name Self, 1 [symbolic]
 // CHECK:STDOUT:   %Make.type.598: type = fn_type @Make.1, @Factory(%T) [symbolic]
 // CHECK:STDOUT:   %Make.737: %Make.type.598 = struct_value () [symbolic]
-// CHECK:STDOUT:   %Make.assoc_type.4d9: type = assoc_entity_type %Factory.type.c96, %Make.type.598 [symbolic]
-// CHECK:STDOUT:   %assoc0.a4a: %Make.assoc_type.4d9 = assoc_entity element0, @Factory.%Make.decl [symbolic]
+// CHECK:STDOUT:   %Factory.assoc_type.ca7: type = assoc_entity_type %Factory.type.c96 [symbolic]
+// CHECK:STDOUT:   %assoc0.d7a: %Factory.assoc_type.ca7 = assoc_entity element0, @Factory.%Make.decl [symbolic]
 // CHECK:STDOUT:   %A: type = class_type @A [template]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [template]
@@ -597,8 +594,8 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Factory.type.a5d: type = facet_type <@Factory, @Factory(%B)> [template]
 // CHECK:STDOUT:   %Make.type.c59: type = fn_type @Make.1, @Factory(%B) [template]
 // CHECK:STDOUT:   %Make.efe: %Make.type.c59 = struct_value () [template]
-// CHECK:STDOUT:   %Make.assoc_type.6c6: type = assoc_entity_type %Factory.type.a5d, %Make.type.c59 [template]
-// CHECK:STDOUT:   %assoc0.925: %Make.assoc_type.6c6 = assoc_entity element0, @Factory.%Make.decl [template]
+// CHECK:STDOUT:   %Factory.assoc_type.668: type = assoc_entity_type %Factory.type.a5d [template]
+// CHECK:STDOUT:   %assoc0.40c: %Factory.assoc_type.668 = assoc_entity element0, @Factory.%Make.decl [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (@impl.%Make.decl) [template]
 // CHECK:STDOUT:   %Make.type.ec4: type = fn_type @Make.2 [template]
 // CHECK:STDOUT:   %Make.377: %Make.type.ec4 = struct_value () [template]
@@ -638,8 +635,8 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Self.2: %Factory.type.c96 = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
 // CHECK:STDOUT:   %Make.type: type = fn_type @Make.1, @Factory(%T.loc4_19.2) [symbolic = %Make.type (constants.%Make.type.598)]
 // CHECK:STDOUT:   %Make: @Factory.%Make.type (%Make.type.598) = struct_value () [symbolic = %Make (constants.%Make.737)]
-// CHECK:STDOUT:   %Make.assoc_type: type = assoc_entity_type @Factory.%Factory.type (%Factory.type.c96), @Factory.%Make.type (%Make.type.598) [symbolic = %Make.assoc_type (constants.%Make.assoc_type.4d9)]
-// CHECK:STDOUT:   %assoc0.loc5_17.2: @Factory.%Make.assoc_type (%Make.assoc_type.4d9) = assoc_entity element0, %Make.decl [symbolic = %assoc0.loc5_17.2 (constants.%assoc0.a4a)]
+// CHECK:STDOUT:   %Factory.assoc_type: type = assoc_entity_type @Factory.%Factory.type (%Factory.type.c96) [symbolic = %Factory.assoc_type (constants.%Factory.assoc_type.ca7)]
+// CHECK:STDOUT:   %assoc0.loc5_17.2: @Factory.%Factory.assoc_type (%Factory.assoc_type.ca7) = assoc_entity element0, %Make.decl [symbolic = %assoc0.loc5_17.2 (constants.%assoc0.d7a)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:     %Self.1: @Factory.%Factory.type (%Factory.type.c96) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
@@ -651,7 +648,7 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:       %return.param: ref @Make.1.%T (%T) = out_param runtime_param0
 // CHECK:STDOUT:       %return: ref @Make.1.%T (%T) = return_slot %return.param
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %assoc0.loc5_17.1: @Factory.%Make.assoc_type (%Make.assoc_type.4d9) = assoc_entity element0, %Make.decl [symbolic = %assoc0.loc5_17.2 (constants.%assoc0.a4a)]
+// CHECK:STDOUT:     %assoc0.loc5_17.1: @Factory.%Factory.assoc_type (%Factory.assoc_type.ca7) = assoc_entity element0, %Make.decl [symbolic = %assoc0.loc5_17.2 (constants.%assoc0.d7a)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = %Self.1
@@ -719,8 +716,8 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Self.2 => constants.%Self
 // CHECK:STDOUT:   %Make.type => constants.%Make.type.c59
 // CHECK:STDOUT:   %Make => constants.%Make.efe
-// CHECK:STDOUT:   %Make.assoc_type => constants.%Make.assoc_type.6c6
-// CHECK:STDOUT:   %assoc0.loc5_17.2 => constants.%assoc0.925
+// CHECK:STDOUT:   %Factory.assoc_type => constants.%Factory.assoc_type.668
+// CHECK:STDOUT:   %assoc0.loc5_17.2 => constants.%assoc0.40c
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @Make.1(constants.%B, constants.%Factory.facet) {
@@ -743,15 +740,15 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %A: type = class_type @A [template]
 // CHECK:STDOUT:   %Make.type.598: type = fn_type @Make.1, @Factory(%T) [symbolic]
 // CHECK:STDOUT:   %Make.737: %Make.type.598 = struct_value () [symbolic]
-// CHECK:STDOUT:   %Make.assoc_type.4d9: type = assoc_entity_type %Factory.type.c96, %Make.type.598 [symbolic]
-// CHECK:STDOUT:   %assoc0.9270f3.1: %Make.assoc_type.4d9 = assoc_entity element0, imports.%Main.import_ref.21018a.1 [symbolic]
+// CHECK:STDOUT:   %Factory.assoc_type.ca7: type = assoc_entity_type %Factory.type.c96 [symbolic]
+// CHECK:STDOUT:   %assoc0.35472f.1: %Factory.assoc_type.ca7 = assoc_entity element0, imports.%Main.import_ref.21018a.1 [symbolic]
 // CHECK:STDOUT:   %Make.type.c59: type = fn_type @Make.1, @Factory(%B) [template]
 // CHECK:STDOUT:   %Make.efe: %Make.type.c59 = struct_value () [template]
-// CHECK:STDOUT:   %Make.assoc_type.6c6: type = assoc_entity_type %Factory.type.a5d, %Make.type.c59 [template]
-// CHECK:STDOUT:   %assoc0.c38: %Make.assoc_type.6c6 = assoc_entity element0, imports.%Main.import_ref.21018a.2 [template]
+// CHECK:STDOUT:   %Factory.assoc_type.668: type = assoc_entity_type %Factory.type.a5d [template]
+// CHECK:STDOUT:   %assoc0.503: %Factory.assoc_type.668 = assoc_entity element0, imports.%Main.import_ref.1aa [template]
 // CHECK:STDOUT:   %MakeB.type: type = fn_type @MakeB [template]
 // CHECK:STDOUT:   %MakeB: %MakeB.type = struct_value () [template]
-// CHECK:STDOUT:   %assoc0.9270f3.2: %Make.assoc_type.4d9 = assoc_entity element0, imports.%Main.import_ref.21018a.3 [symbolic]
+// CHECK:STDOUT:   %assoc0.35472f.2: %Factory.assoc_type.ca7 = assoc_entity element0, imports.%Main.import_ref.21018a.2 [symbolic]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (imports.%Main.import_ref.9ec) [template]
 // CHECK:STDOUT:   %Make.type.ec4: type = fn_type @Make.2 [template]
 // CHECK:STDOUT:   %Make.377: %Make.type.ec4 = struct_value () [template]
@@ -765,7 +762,7 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Main.import_ref.8f24d3.1: <witness> = import_ref Main//factory, loc9_10, loaded [template = constants.%complete_type]
 // CHECK:STDOUT:   %Main.import_ref.54a = import_ref Main//factory, inst52 [no loc], unloaded
 // CHECK:STDOUT:   %Main.import_ref.fbb = import_ref Main//factory, inst26 [no loc], unloaded
-// CHECK:STDOUT:   %Main.import_ref.b0a: @Factory.%Make.assoc_type (%Make.assoc_type.4d9) = import_ref Main//factory, loc5_17, loaded [symbolic = @Factory.%assoc0 (constants.%assoc0.9270f3.2)]
+// CHECK:STDOUT:   %Main.import_ref.8d5: @Factory.%Factory.assoc_type (%Factory.assoc_type.ca7) = import_ref Main//factory, loc5_17, loaded [symbolic = @Factory.%assoc0 (constants.%assoc0.35472f.2)]
 // CHECK:STDOUT:   %Main.Make = import_ref Main//factory, Make, unloaded
 // CHECK:STDOUT:   %Main.import_ref.8f24d3.2: <witness> = import_ref Main//factory, loc8_10, loaded [template = constants.%complete_type]
 // CHECK:STDOUT:   %Main.import_ref.da3 = import_ref Main//factory, inst47 [no loc], unloaded
@@ -808,13 +805,13 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Self: %Factory.type.c96 = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self)]
 // CHECK:STDOUT:   %Make.type: type = fn_type @Make.1, @Factory(%T) [symbolic = %Make.type (constants.%Make.type.598)]
 // CHECK:STDOUT:   %Make: @Factory.%Make.type (%Make.type.598) = struct_value () [symbolic = %Make (constants.%Make.737)]
-// CHECK:STDOUT:   %Make.assoc_type: type = assoc_entity_type @Factory.%Factory.type (%Factory.type.c96), @Factory.%Make.type (%Make.type.598) [symbolic = %Make.assoc_type (constants.%Make.assoc_type.4d9)]
-// CHECK:STDOUT:   %assoc0: @Factory.%Make.assoc_type (%Make.assoc_type.4d9) = assoc_entity element0, imports.%Main.import_ref.21018a.1 [symbolic = %assoc0 (constants.%assoc0.9270f3.1)]
+// CHECK:STDOUT:   %Factory.assoc_type: type = assoc_entity_type @Factory.%Factory.type (%Factory.type.c96) [symbolic = %Factory.assoc_type (constants.%Factory.assoc_type.ca7)]
+// CHECK:STDOUT:   %assoc0: @Factory.%Factory.assoc_type (%Factory.assoc_type.ca7) = assoc_entity element0, imports.%Main.import_ref.21018a.1 [symbolic = %assoc0 (constants.%assoc0.35472f.1)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = imports.%Main.import_ref.fbb
-// CHECK:STDOUT:     .Make = imports.%Main.import_ref.b0a
+// CHECK:STDOUT:     .Make = imports.%Main.import_ref.8d5
 // CHECK:STDOUT:     witness = (imports.%Main.Make)
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -851,8 +848,8 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Factory.ref: %Factory.type.1a8 = name_ref Factory, imports.%Main.Factory [template = constants.%Factory.generic]
 // CHECK:STDOUT:   %B.ref.loc5: type = name_ref B, imports.%Main.B [template = constants.%B]
 // CHECK:STDOUT:   %Factory.type: type = facet_type <@Factory, @Factory(constants.%B)> [template = constants.%Factory.type.a5d]
-// CHECK:STDOUT:   %.loc5: %Make.assoc_type.6c6 = specific_constant imports.%Main.import_ref.b0a, @Factory(constants.%B) [template = constants.%assoc0.c38]
-// CHECK:STDOUT:   %Make.ref: %Make.assoc_type.6c6 = name_ref Make, %.loc5 [template = constants.%assoc0.c38]
+// CHECK:STDOUT:   %.loc5: %Factory.assoc_type.668 = specific_constant imports.%Main.import_ref.8d5, @Factory(constants.%B) [template = constants.%assoc0.503]
+// CHECK:STDOUT:   %Make.ref: %Factory.assoc_type.668 = name_ref Make, %.loc5 [template = constants.%assoc0.503]
 // CHECK:STDOUT:   %impl.elem0: %Make.type.c59 = impl_witness_access constants.%impl_witness, element0 [template = constants.%Make.377]
 // CHECK:STDOUT:   %.loc4: ref %B = splice_block %return {}
 // CHECK:STDOUT:   %Make.call: init %B = call %impl.elem0() to %.loc4
@@ -875,8 +872,8 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT:   %Make.type => constants.%Make.type.c59
 // CHECK:STDOUT:   %Make => constants.%Make.efe
-// CHECK:STDOUT:   %Make.assoc_type => constants.%Make.assoc_type.6c6
-// CHECK:STDOUT:   %assoc0 => constants.%assoc0.c38
+// CHECK:STDOUT:   %Factory.assoc_type => constants.%Factory.assoc_type.668
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.503
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @Factory(%T) {}
@@ -901,21 +898,21 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %A: type = class_type @A [template]
 // CHECK:STDOUT:   %Make.type.598: type = fn_type @Make, @Factory(%T) [symbolic]
 // CHECK:STDOUT:   %Make.737: %Make.type.598 = struct_value () [symbolic]
-// CHECK:STDOUT:   %Make.assoc_type.4d9: type = assoc_entity_type %Factory.type.c96, %Make.type.598 [symbolic]
-// CHECK:STDOUT:   %assoc0.9270f3.1: %Make.assoc_type.4d9 = assoc_entity element0, imports.%Main.import_ref.21018a.1 [symbolic]
+// CHECK:STDOUT:   %Factory.assoc_type.ca7: type = assoc_entity_type %Factory.type.c96 [symbolic]
+// CHECK:STDOUT:   %assoc0.35472f.1: %Factory.assoc_type.ca7 = assoc_entity element0, imports.%Main.import_ref.21018a.1 [symbolic]
 // CHECK:STDOUT:   %Make.type.c59: type = fn_type @Make, @Factory(%B) [template]
 // CHECK:STDOUT:   %Make.efe: %Make.type.c59 = struct_value () [template]
-// CHECK:STDOUT:   %Make.assoc_type.6c6: type = assoc_entity_type %Factory.type.a5d, %Make.type.c59 [template]
-// CHECK:STDOUT:   %assoc0.c38: %Make.assoc_type.6c6 = assoc_entity element0, imports.%Main.import_ref.21018a.2 [template]
+// CHECK:STDOUT:   %Factory.assoc_type.668: type = assoc_entity_type %Factory.type.a5d [template]
+// CHECK:STDOUT:   %assoc0.228: %Factory.assoc_type.668 = assoc_entity element0, imports.%Main.import_ref.21018a.2 [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %MakeC.type: type = fn_type @MakeC [template]
 // CHECK:STDOUT:   %MakeC: %MakeC.type = struct_value () [template]
 // CHECK:STDOUT:   %Factory.type.5c5: type = facet_type <@Factory, @Factory(%C)> [template]
 // CHECK:STDOUT:   %Make.type.0de: type = fn_type @Make, @Factory(%C) [template]
 // CHECK:STDOUT:   %Make.8ba: %Make.type.0de = struct_value () [template]
-// CHECK:STDOUT:   %Make.assoc_type.2ea: type = assoc_entity_type %Factory.type.5c5, %Make.type.0de [template]
-// CHECK:STDOUT:   %assoc0.9a3: %Make.assoc_type.2ea = assoc_entity element0, imports.%Main.import_ref.21018a.1 [template]
-// CHECK:STDOUT:   %assoc0.9270f3.2: %Make.assoc_type.4d9 = assoc_entity element0, imports.%Main.import_ref.21018a.3 [symbolic]
+// CHECK:STDOUT:   %Factory.assoc_type.709: type = assoc_entity_type %Factory.type.5c5 [template]
+// CHECK:STDOUT:   %assoc0.ef9: %Factory.assoc_type.709 = assoc_entity element0, imports.%Main.import_ref.21018a.1 [template]
+// CHECK:STDOUT:   %assoc0.35472f.2: %Factory.assoc_type.ca7 = assoc_entity element0, imports.%Main.import_ref.21018a.3 [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -926,7 +923,7 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Main.import_ref.8f24d3.1: <witness> = import_ref Main//factory, loc9_10, loaded [template = constants.%complete_type]
 // CHECK:STDOUT:   %Main.import_ref.54a = import_ref Main//factory, inst52 [no loc], unloaded
 // CHECK:STDOUT:   %Main.import_ref.fbb = import_ref Main//factory, inst26 [no loc], unloaded
-// CHECK:STDOUT:   %Main.import_ref.b0a: @Factory.%Make.assoc_type (%Make.assoc_type.4d9) = import_ref Main//factory, loc5_17, loaded [symbolic = @Factory.%assoc0 (constants.%assoc0.9270f3.2)]
+// CHECK:STDOUT:   %Main.import_ref.8d5: @Factory.%Factory.assoc_type (%Factory.assoc_type.ca7) = import_ref Main//factory, loc5_17, loaded [symbolic = @Factory.%assoc0 (constants.%assoc0.35472f.2)]
 // CHECK:STDOUT:   %Main.Make = import_ref Main//factory, Make, unloaded
 // CHECK:STDOUT:   %Main.import_ref.8f24d3.2: <witness> = import_ref Main//factory, loc8_10, loaded [template = constants.%complete_type]
 // CHECK:STDOUT:   %Main.import_ref.da3 = import_ref Main//factory, inst47 [no loc], unloaded
@@ -971,13 +968,13 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Self: %Factory.type.c96 = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self)]
 // CHECK:STDOUT:   %Make.type: type = fn_type @Make, @Factory(%T) [symbolic = %Make.type (constants.%Make.type.598)]
 // CHECK:STDOUT:   %Make: @Factory.%Make.type (%Make.type.598) = struct_value () [symbolic = %Make (constants.%Make.737)]
-// CHECK:STDOUT:   %Make.assoc_type: type = assoc_entity_type @Factory.%Factory.type (%Factory.type.c96), @Factory.%Make.type (%Make.type.598) [symbolic = %Make.assoc_type (constants.%Make.assoc_type.4d9)]
-// CHECK:STDOUT:   %assoc0: @Factory.%Make.assoc_type (%Make.assoc_type.4d9) = assoc_entity element0, imports.%Main.import_ref.21018a.1 [symbolic = %assoc0 (constants.%assoc0.9270f3.1)]
+// CHECK:STDOUT:   %Factory.assoc_type: type = assoc_entity_type @Factory.%Factory.type (%Factory.type.c96) [symbolic = %Factory.assoc_type (constants.%Factory.assoc_type.ca7)]
+// CHECK:STDOUT:   %assoc0: @Factory.%Factory.assoc_type (%Factory.assoc_type.ca7) = assoc_entity element0, imports.%Main.import_ref.21018a.1 [symbolic = %assoc0 (constants.%assoc0.35472f.1)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = imports.%Main.import_ref.fbb
-// CHECK:STDOUT:     .Make = imports.%Main.import_ref.b0a
+// CHECK:STDOUT:     .Make = imports.%Main.import_ref.8d5
 // CHECK:STDOUT:     witness = (imports.%Main.Make)
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -1022,8 +1019,8 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Factory.ref: %Factory.type.1a8 = name_ref Factory, imports.%Main.Factory [template = constants.%Factory.generic]
 // CHECK:STDOUT:   %C.ref.loc11: type = name_ref C, file.%C.decl [template = constants.%C]
 // CHECK:STDOUT:   %Factory.type: type = facet_type <@Factory, @Factory(constants.%C)> [template = constants.%Factory.type.5c5]
-// CHECK:STDOUT:   %.loc11: %Make.assoc_type.2ea = specific_constant imports.%Main.import_ref.b0a, @Factory(constants.%C) [template = constants.%assoc0.9a3]
-// CHECK:STDOUT:   %Make.ref: %Make.assoc_type.2ea = name_ref Make, %.loc11 [template = constants.%assoc0.9a3]
+// CHECK:STDOUT:   %.loc11: %Factory.assoc_type.709 = specific_constant imports.%Main.import_ref.8d5, @Factory(constants.%C) [template = constants.%assoc0.ef9]
+// CHECK:STDOUT:   %Make.ref: %Factory.assoc_type.709 = name_ref Make, %.loc11 [template = constants.%assoc0.ef9]
 // CHECK:STDOUT:   return <error> to %return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -1041,8 +1038,8 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT:   %Make.type => constants.%Make.type.c59
 // CHECK:STDOUT:   %Make => constants.%Make.efe
-// CHECK:STDOUT:   %Make.assoc_type => constants.%Make.assoc_type.6c6
-// CHECK:STDOUT:   %assoc0 => constants.%assoc0.c38
+// CHECK:STDOUT:   %Factory.assoc_type => constants.%Factory.assoc_type.668
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.228
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @Factory(%T) {}
@@ -1060,7 +1057,7 @@ fn MakeC(a: A) -> C {
 // CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT:   %Make.type => constants.%Make.type.0de
 // CHECK:STDOUT:   %Make => constants.%Make.8ba
-// CHECK:STDOUT:   %Make.assoc_type => constants.%Make.assoc_type.2ea
-// CHECK:STDOUT:   %assoc0 => constants.%assoc0.9a3
+// CHECK:STDOUT:   %Factory.assoc_type => constants.%Factory.assoc_type.709
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.ef9
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

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

@@ -30,8 +30,8 @@ class A {
 // CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic]
 // CHECK:STDOUT:   %Make.type.068: type = fn_type @Make.1 [template]
 // CHECK:STDOUT:   %Make.606: %Make.type.068 = struct_value () [template]
-// CHECK:STDOUT:   %Make.assoc_type: type = assoc_entity_type %DefaultConstructible.type, %Make.type.068 [template]
-// CHECK:STDOUT:   %assoc0: %Make.assoc_type = assoc_entity element0, @DefaultConstructible.%Make.decl [template]
+// CHECK:STDOUT:   %DefaultConstructible.assoc_type: type = assoc_entity_type %DefaultConstructible.type [template]
+// CHECK:STDOUT:   %assoc0: %DefaultConstructible.assoc_type = assoc_entity element0, @DefaultConstructible.%Make.decl [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [template]
@@ -66,7 +66,7 @@ class A {
 // CHECK:STDOUT:     %return.param: ref @Make.1.%Self.as_type.loc12_16.1 (%Self.as_type) = out_param runtime_param0
 // CHECK:STDOUT:     %return: ref @Make.1.%Self.as_type.loc12_16.1 (%Self.as_type) = return_slot %return.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc0: %Make.assoc_type = assoc_entity element0, %Make.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %DefaultConstructible.assoc_type = assoc_entity element0, %Make.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self

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

@@ -45,8 +45,8 @@ impl D as SelfNested {
 // CHECK:STDOUT:   %F.type.86a: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.408: %F.type.86a = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type.59c: type = assoc_entity_type %UseSelf.type, %F.type.86a [template]
-// CHECK:STDOUT:   %assoc0.86d: %F.assoc_type.59c = assoc_entity element0, @UseSelf.%F.decl [template]
+// CHECK:STDOUT:   %UseSelf.assoc_type: type = assoc_entity_type %UseSelf.type [template]
+// CHECK:STDOUT:   %assoc0.774: %UseSelf.assoc_type = assoc_entity element0, @UseSelf.%F.decl [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [template]
@@ -70,8 +70,8 @@ impl D as SelfNested {
 // CHECK:STDOUT:   %tuple.type.46b: type = tuple_type (%ptr.e87, %struct_type.x.y.270) [symbolic]
 // CHECK:STDOUT:   %F.type.6ed: type = fn_type @F.4 [template]
 // CHECK:STDOUT:   %F.998: %F.type.6ed = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type.4b1: type = assoc_entity_type %SelfNested.type, %F.type.6ed [template]
-// CHECK:STDOUT:   %assoc0.7e7: %F.assoc_type.4b1 = assoc_entity element0, @SelfNested.%F.decl [template]
+// CHECK:STDOUT:   %SelfNested.assoc_type: type = assoc_entity_type %SelfNested.type [template]
+// CHECK:STDOUT:   %assoc0.a58: %SelfNested.assoc_type = assoc_entity element0, @SelfNested.%F.decl [template]
 // CHECK:STDOUT:   %impl_witness.f4e: <witness> = impl_witness (@impl.3.%F.decl) [template]
 // CHECK:STDOUT:   %ptr.019: type = ptr_type %C [template]
 // CHECK:STDOUT:   %struct_type.x.y.2f0: type = struct_type {.x: %C, .y: %empty_tuple.type} [template]
@@ -151,7 +151,7 @@ impl D as SelfNested {
 // CHECK:STDOUT:     %return.param: ref @F.1.%Self.as_type.loc12_14.1 (%Self.as_type.599) = out_param runtime_param2
 // CHECK:STDOUT:     %return: ref @F.1.%Self.as_type.loc12_14.1 (%Self.as_type.599) = return_slot %return.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc0: %F.assoc_type.59c = assoc_entity element0, %F.decl [template = constants.%assoc0.86d]
+// CHECK:STDOUT:   %assoc0: %UseSelf.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0.774]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -182,7 +182,7 @@ impl D as SelfNested {
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %x: @F.4.%tuple.type (%tuple.type.46b) = bind_name x, %x.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc0: %F.assoc_type.4b1 = assoc_entity element0, %F.decl [template = constants.%assoc0.7e7]
+// CHECK:STDOUT:   %assoc0: %SelfNested.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0.a58]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self

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

@@ -36,8 +36,8 @@ var d: i32 = c[-10];
 // CHECK:STDOUT:   %int_1: Core.IntLiteral = int_value 1 [template]
 // CHECK:STDOUT:   %array: %array_type = tuple_value (%int_42.c68, %int_42.c68) [template]
 // CHECK:STDOUT:   %int_10: Core.IntLiteral = int_value 10 [template]
-// CHECK:STDOUT:   %Op.type.e42: type = fn_type @Op.13 [template]
 // CHECK:STDOUT:   %impl_witness.0f6: <witness> = impl_witness (imports.%Core.import_ref.c15) [template]
+// CHECK:STDOUT:   %Op.type.e42: type = fn_type @Op.13 [template]
 // CHECK:STDOUT:   %Op.type.1be: type = fn_type @Op.14 [template]
 // CHECK:STDOUT:   %Op.bba: %Op.type.1be = struct_value () [template]
 // CHECK:STDOUT:   %Op.bound: <bound method> = bound_method %int_10, %Op.bba [template]

+ 23 - 10
toolchain/check/testdata/interface/assoc_const.carbon

@@ -18,12 +18,11 @@ interface I {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %I.type: type = facet_type <@I> [template]
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type.579: type = assoc_entity_type %I.type, type [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type.579 = assoc_entity element0, @I.%T [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [template]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [template]
-// CHECK:STDOUT:   %assoc_type.4fb: type = assoc_entity_type %I.type, %i32 [template]
-// CHECK:STDOUT:   %assoc1: %assoc_type.4fb = assoc_entity element1, @I.%N [template]
+// CHECK:STDOUT:   %assoc1: %I.assoc_type = assoc_entity element1, @I.%N [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -45,15 +44,29 @@ interface I {
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %T: type = assoc_const_decl T [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type.579 = assoc_entity element0, %T [template = constants.%assoc0]
-// CHECK:STDOUT:   %N: %i32 = assoc_const_decl N [template]
-// CHECK:STDOUT:   %assoc1: %assoc_type.4fb = assoc_entity element1, %N [template = constants.%assoc1]
+// CHECK:STDOUT:   %T: type = assoc_const_decl @T [template] {
+// CHECK:STDOUT:     %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [template = constants.%assoc0]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %N: %i32 = assoc_const_decl @N [template] {
+// CHECK:STDOUT:     %assoc1: %I.assoc_type = assoc_entity element1, @I.%N [template = constants.%assoc1]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .T = %assoc0
-// CHECK:STDOUT:   .N = %assoc1
+// CHECK:STDOUT:   .T = @T.%assoc0
+// CHECK:STDOUT:   .N = @N.%assoc1
 // CHECK:STDOUT:   witness = (%T, %N)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @T(@I.%Self: %I.type) {
+// CHECK:STDOUT:   assoc_const T:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @N(@I.%Self: %I.type) {
+// CHECK:STDOUT:   assoc_const N:! %i32;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @T(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @N(constants.%Self) {}
+// CHECK:STDOUT:

+ 16 - 7
toolchain/check/testdata/interface/fail_assoc_const_bad_default.carbon

@@ -24,8 +24,8 @@ interface I {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %I.type: type = facet_type <@I> [template]
 // CHECK:STDOUT:   %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %I.type, type [template]
-// CHECK:STDOUT:   %assoc0.790: %assoc_type = assoc_entity element0, @I.%T [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0.c7e: %I.assoc_type = assoc_entity element0, @I.%T [template]
 // CHECK:STDOUT:   %int_42: Core.IntLiteral = int_value 42 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -48,14 +48,23 @@ interface I {
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826]
-// CHECK:STDOUT:   %T: type = assoc_const_decl T [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %T [template = constants.%assoc0.790]
-// CHECK:STDOUT:   %int_42: Core.IntLiteral = int_value 42 [template = constants.%int_42]
-// CHECK:STDOUT:   %.loc19: type = converted %int_42, <error> [template = <error>]
+// CHECK:STDOUT:   %T: type = assoc_const_decl @T [template] {
+// CHECK:STDOUT:     %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [template = constants.%assoc0.c7e]
+// CHECK:STDOUT:     %int_42: Core.IntLiteral = int_value 42 [template = constants.%int_42]
+// CHECK:STDOUT:     %.loc19: type = converted %int_42, <error> [template = <error>]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .T = %assoc0
+// CHECK:STDOUT:   .T = @T.%assoc0
 // CHECK:STDOUT:   witness = (%T)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @T(@I.%Self: %I.type) {
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   assoc_const T:! type = <error>;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @T(constants.%Self.826) {}
+// CHECK:STDOUT:

+ 40 - 23
toolchain/check/testdata/interface/fail_todo_assoc_const_default.carbon

@@ -26,14 +26,13 @@ interface I {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %I.type: type = facet_type <@I> [template]
 // CHECK:STDOUT:   %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type.579: type = assoc_entity_type %I.type, type [template]
-// CHECK:STDOUT:   %assoc0.790: %assoc_type.579 = assoc_entity element0, @I.%T [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0.c7e: %I.assoc_type = assoc_entity element0, @I.%T [template]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [template]
 // CHECK:STDOUT:   %tuple.type.24b: type = tuple_type (type, type) [template]
 // CHECK:STDOUT:   %tuple.type.d07: type = tuple_type (%i32, %i32) [template]
-// CHECK:STDOUT:   %assoc_type.4fb: type = assoc_entity_type %I.type, %i32 [template]
-// CHECK:STDOUT:   %assoc1: %assoc_type.4fb = assoc_entity element1, @I.%N [template]
+// CHECK:STDOUT:   %assoc1: %I.assoc_type = assoc_entity element1, @I.%N [template]
 // CHECK:STDOUT:   %int_42.20e: Core.IntLiteral = int_value 42 [template]
 // CHECK:STDOUT:   %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [template]
 // CHECK:STDOUT:   %impl_witness.d39: <witness> = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [template]
@@ -64,28 +63,46 @@ interface I {
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826]
-// CHECK:STDOUT:   %T: type = assoc_const_decl T [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type.579 = assoc_entity element0, %T [template = constants.%assoc0.790]
-// CHECK:STDOUT:   %int_32.loc16_27: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:   %i32.loc16_27: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
-// CHECK:STDOUT:   %int_32.loc16_32: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:   %i32.loc16_32: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
-// CHECK:STDOUT:   %.loc16_35: %tuple.type.24b = tuple_literal (%i32.loc16_27, %i32.loc16_32)
-// CHECK:STDOUT:   %.loc16_36: type = converted %.loc16_35, constants.%tuple.type.d07 [template = constants.%tuple.type.d07]
-// CHECK:STDOUT:   %N: %i32 = assoc_const_decl N [template]
-// CHECK:STDOUT:   %assoc1: %assoc_type.4fb = assoc_entity element1, %N [template = constants.%assoc1]
-// CHECK:STDOUT:   %int_42: Core.IntLiteral = int_value 42 [template = constants.%int_42.20e]
-// CHECK:STDOUT:   %impl.elem0: %Convert.type.1b6 = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
-// CHECK:STDOUT:   %Convert.bound: <bound method> = bound_method %int_42, %impl.elem0 [template = constants.%Convert.bound]
-// CHECK:STDOUT:   %Convert.specific_fn: <specific function> = specific_function %Convert.bound, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn]
-// CHECK:STDOUT:   %int.convert_checked: init %i32 = call %Convert.specific_fn(%int_42) [template = constants.%int_42.c68]
-// CHECK:STDOUT:   %.loc21_27.1: %i32 = value_of_initializer %int.convert_checked [template = constants.%int_42.c68]
-// CHECK:STDOUT:   %.loc21_27.2: %i32 = converted %int_42, %.loc21_27.1 [template = constants.%int_42.c68]
+// CHECK:STDOUT:   %T: type = assoc_const_decl @T [template] {
+// CHECK:STDOUT:     %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [template = constants.%assoc0.c7e]
+// CHECK:STDOUT:     %int_32.loc16_27: Core.IntLiteral = int_value 32 [template = constants.%int_32]
+// CHECK:STDOUT:     %i32.loc16_27: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
+// CHECK:STDOUT:     %int_32.loc16_32: Core.IntLiteral = int_value 32 [template = constants.%int_32]
+// CHECK:STDOUT:     %i32.loc16_32: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
+// CHECK:STDOUT:     %.loc16_35: %tuple.type.24b = tuple_literal (%i32.loc16_27, %i32.loc16_32)
+// CHECK:STDOUT:     %.loc16_36: type = converted %.loc16_35, constants.%tuple.type.d07 [template = constants.%tuple.type.d07]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %N: %i32 = assoc_const_decl @N [template] {
+// CHECK:STDOUT:     %assoc1: %I.assoc_type = assoc_entity element1, @I.%N [template = constants.%assoc1]
+// CHECK:STDOUT:     %int_42: Core.IntLiteral = int_value 42 [template = constants.%int_42.20e]
+// CHECK:STDOUT:     %impl.elem0: %Convert.type.1b6 = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
+// CHECK:STDOUT:     %Convert.bound: <bound method> = bound_method %int_42, %impl.elem0 [template = constants.%Convert.bound]
+// CHECK:STDOUT:     %Convert.specific_fn: <specific function> = specific_function %Convert.bound, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn]
+// CHECK:STDOUT:     %int.convert_checked: init %i32 = call %Convert.specific_fn(%int_42) [template = constants.%int_42.c68]
+// CHECK:STDOUT:     %.loc21_27.1: %i32 = value_of_initializer %int.convert_checked [template = constants.%int_42.c68]
+// CHECK:STDOUT:     %.loc21_27.2: %i32 = converted %int_42, %.loc21_27.1 [template = constants.%int_42.c68]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .T = %assoc0
-// CHECK:STDOUT:   .N = %assoc1
+// CHECK:STDOUT:   .T = @T.%assoc0
+// CHECK:STDOUT:   .N = @N.%assoc1
 // CHECK:STDOUT:   witness = (%T, %N)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @T(@I.%Self: %I.type) {
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   assoc_const T:! type = %.loc16_36;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @N(@I.%Self: %I.type) {
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   assoc_const N:! %i32 = %.loc21_27.2;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @T(constants.%Self.826) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @N(constants.%Self.826) {}
+// CHECK:STDOUT:

+ 5 - 6
toolchain/check/testdata/interface/fail_todo_define_default_fn_inline.carbon

@@ -29,14 +29,13 @@ interface Interface {
 // CHECK:STDOUT:   %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %Interface.type, %F.type [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @Interface.%F.decl [template]
+// CHECK:STDOUT:   %Interface.assoc_type: type = assoc_entity_type %Interface.type [template]
+// CHECK:STDOUT:   %assoc0: %Interface.assoc_type = assoc_entity element0, @Interface.%F.decl [template]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
-// CHECK:STDOUT:   %G.assoc_type: type = assoc_entity_type %Interface.type, %G.type [template]
-// CHECK:STDOUT:   %assoc1: %G.assoc_type = assoc_entity element1, @Interface.%G.decl [template]
+// CHECK:STDOUT:   %assoc1: %Interface.assoc_type = assoc_entity element1, @Interface.%G.decl [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -59,7 +58,7 @@ interface Interface {
 // CHECK:STDOUT: interface @Interface {
 // CHECK:STDOUT:   %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %Interface.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [template = constants.%G] {
 // CHECK:STDOUT:     %a.patt: %i32 = binding_pattern a
 // CHECK:STDOUT:     %a.param_patt: %i32 = value_param_pattern %a.patt, runtime_param0
@@ -85,7 +84,7 @@ interface Interface {
 // CHECK:STDOUT:     %return.param: ref %i32 = out_param runtime_param2
 // CHECK:STDOUT:     %return: ref %i32 = return_slot %return.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc1: %G.assoc_type = assoc_entity element1, %G.decl [template = constants.%assoc1]
+// CHECK:STDOUT:   %assoc1: %Interface.assoc_type = assoc_entity element1, %G.decl [template = constants.%assoc1]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self

+ 5 - 8
toolchain/check/testdata/interface/fail_todo_define_default_fn_out_of_line.carbon

@@ -71,14 +71,13 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; }
 // CHECK:STDOUT:   %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %Interface.type, %F.type [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @Interface.%F.decl [template]
+// CHECK:STDOUT:   %Interface.assoc_type: type = assoc_entity_type %Interface.type [template]
+// CHECK:STDOUT:   %assoc0: %Interface.assoc_type = assoc_entity element0, @Interface.%F.decl [template]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
-// CHECK:STDOUT:   %G.assoc_type: type = assoc_entity_type %Interface.type, %G.type [template]
-// CHECK:STDOUT:   %assoc1: %G.assoc_type = assoc_entity element1, @Interface.%G.decl [template]
+// CHECK:STDOUT:   %assoc1: %Interface.assoc_type = assoc_entity element1, @Interface.%G.decl [template]
 // CHECK:STDOUT:   %.type.136624.1: type = fn_type @.1 [template]
 // CHECK:STDOUT:   %.563abc.1: %.type.136624.1 = struct_value () [template]
 // CHECK:STDOUT:   %.type.136624.2: type = fn_type @.2 [template]
@@ -131,7 +130,7 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; }
 // CHECK:STDOUT: interface @Interface {
 // CHECK:STDOUT:   %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %Interface.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [template = constants.%G] {
 // CHECK:STDOUT:     %a.patt: %i32 = binding_pattern a
 // CHECK:STDOUT:     %a.param_patt: %i32 = value_param_pattern %a.patt, runtime_param0
@@ -157,7 +156,7 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; }
 // CHECK:STDOUT:     %return.param: ref %i32 = out_param runtime_param2
 // CHECK:STDOUT:     %return: ref %i32 = return_slot %return.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc1: %G.assoc_type = assoc_entity element1, %G.decl [template = constants.%assoc1]
+// CHECK:STDOUT:   %assoc1: %Interface.assoc_type = assoc_entity element1, %G.decl [template = constants.%assoc1]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -167,12 +166,10 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(@Interface.%Self: %Interface.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @G(@Interface.%Self: %Interface.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%a.param_patt: %i32, %b.param_patt: %i32) -> %i32;
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 76 - 38
toolchain/check/testdata/interface/member_lookup.carbon

@@ -58,14 +58,16 @@ fn AccessMissingConcrete(I:! Interface(i32)) -> i32 {
 // CHECK:STDOUT:   %Interface.type.d32: type = facet_type <@Interface, @Interface(%T)> [symbolic]
 // CHECK:STDOUT:   %Self: %Interface.type.d32 = bind_symbolic_name Self, 1 [symbolic]
 // CHECK:STDOUT:   %require_complete.4ae: <witness> = require_complete_type %T [symbolic]
-// CHECK:STDOUT:   %assoc_type.376: type = assoc_entity_type %Interface.type.d32, %T [symbolic]
-// CHECK:STDOUT:   %assoc0.fa3: %assoc_type.376 = assoc_entity element0, @Interface.%X [symbolic]
+// CHECK:STDOUT:   %Interface.assoc_type.3bd: type = assoc_entity_type %Interface.type.d32 [symbolic]
+// CHECK:STDOUT:   %assoc0.ed7: %Interface.assoc_type.3bd = assoc_entity element0, @Interface.%X [symbolic]
 // CHECK:STDOUT:   %I.a5f: %Interface.type.d32 = bind_symbolic_name I, 1 [symbolic]
 // CHECK:STDOUT:   %I.patt.47c: %Interface.type.d32 = symbolic_binding_pattern I, 1 [symbolic]
 // CHECK:STDOUT:   %AccessGeneric.type: type = fn_type @AccessGeneric [template]
 // CHECK:STDOUT:   %AccessGeneric: %AccessGeneric.type = struct_value () [template]
 // CHECK:STDOUT:   %require_complete.6f3: <witness> = require_complete_type %Interface.type.d32 [symbolic]
+// CHECK:STDOUT:   %I.as_type.59e: type = facet_access_type %I.a5f [symbolic]
 // CHECK:STDOUT:   %I.as_wit.9f4: <witness> = facet_access_witness %I.a5f [symbolic]
+// CHECK:STDOUT:   %Interface.facet.856: %Interface.type.d32 = facet_value %I.as_type.59e, %I.as_wit.9f4 [symbolic]
 // CHECK:STDOUT:   %impl.elem0.68a: %T = impl_witness_access %I.as_wit.9f4, element0 [symbolic]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [template]
@@ -76,9 +78,11 @@ fn AccessMissingConcrete(I:! Interface(i32)) -> i32 {
 // CHECK:STDOUT:   %AccessConcrete: %AccessConcrete.type = struct_value () [template]
 // CHECK:STDOUT:   %i32.builtin: type = int_type signed, %int_32 [template]
 // CHECK:STDOUT:   %complete_type.f8a: <witness> = complete_type_witness %i32.builtin [template]
-// CHECK:STDOUT:   %assoc_type.5f0: type = assoc_entity_type %Interface.type.981, %i32 [template]
-// CHECK:STDOUT:   %assoc0.ed2: %assoc_type.5f0 = assoc_entity element0, @Interface.%X [template]
+// CHECK:STDOUT:   %Interface.assoc_type.44d: type = assoc_entity_type %Interface.type.981 [template]
+// CHECK:STDOUT:   %assoc0.4ff: %Interface.assoc_type.44d = assoc_entity element0, @Interface.%X [template]
+// CHECK:STDOUT:   %I.as_type.ee6: type = facet_access_type %I.d08 [symbolic]
 // CHECK:STDOUT:   %I.as_wit.156: <witness> = facet_access_witness %I.d08 [symbolic]
+// CHECK:STDOUT:   %Interface.facet.a3f: %Interface.type.d32 = facet_value %I.as_type.ee6, %I.as_wit.156 [symbolic]
 // CHECK:STDOUT:   %impl.elem0.b00: %i32 = impl_witness_access %I.as_wit.156, element0 [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -154,22 +158,29 @@ fn AccessMissingConcrete(I:! Interface(i32)) -> i32 {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %Interface.type: type = facet_type <@Interface, @Interface(%T.loc4_21.2)> [symbolic = %Interface.type (constants.%Interface.type.d32)]
 // CHECK:STDOUT:   %Self.2: %Interface.type.d32 = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
-// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type @Interface.%T.loc4_21.2 (%T) [symbolic = %require_complete (constants.%require_complete.4ae)]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type @Interface.%Interface.type (%Interface.type.d32), @Interface.%T.loc4_21.2 (%T) [symbolic = %assoc_type (constants.%assoc_type.376)]
-// CHECK:STDOUT:   %assoc0.loc5_8.2: @Interface.%assoc_type (%assoc_type.376) = assoc_entity element0, %X [symbolic = %assoc0.loc5_8.2 (constants.%assoc0.fa3)]
+// CHECK:STDOUT:   %Interface.assoc_type: type = assoc_entity_type @Interface.%Interface.type (%Interface.type.d32) [symbolic = %Interface.assoc_type (constants.%Interface.assoc_type.3bd)]
+// CHECK:STDOUT:   %assoc0: @Interface.%Interface.assoc_type (%Interface.assoc_type.3bd) = assoc_entity element0, %X [symbolic = %assoc0 (constants.%assoc0.ed7)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:     %Self.1: @Interface.%Interface.type (%Interface.type.d32) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
-// CHECK:STDOUT:     %X: @Interface.%T.loc4_21.2 (%T) = assoc_const_decl X [template]
-// CHECK:STDOUT:     %assoc0.loc5_8.1: @Interface.%assoc_type (%assoc_type.376) = assoc_entity element0, %X [symbolic = %assoc0.loc5_8.2 (constants.%assoc0.fa3)]
+// CHECK:STDOUT:     %X: @X.%T (%T) = assoc_const_decl @X [template] {
+// CHECK:STDOUT:       %assoc0: @Interface.%Interface.assoc_type (%Interface.assoc_type.3bd) = assoc_entity element0, @Interface.%X [symbolic = @Interface.%assoc0 (constants.%assoc0.ed7)]
+// CHECK:STDOUT:     }
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = %Self.1
-// CHECK:STDOUT:     .X = %assoc0.loc5_8.1
+// CHECK:STDOUT:     .X = @X.%assoc0
 // CHECK:STDOUT:     witness = (%X)
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @X(@Interface.%T.loc4_21.1: type, @Interface.%Self.1: @Interface.%Interface.type (%Interface.type.d32)) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type @X.%T (%T) [symbolic = %require_complete (constants.%require_complete.4ae)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   assoc_const X:! @X.%T (%T);
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @AccessGeneric(%T.loc8_18.1: type, %I.loc8_28.1: @AccessGeneric.%Interface.type.loc8_43.2 (%Interface.type.d32)) {
 // CHECK:STDOUT:   %T.loc8_18.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc8_18.2 (constants.%T)]
 // CHECK:STDOUT:   %T.patt.loc8_18.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_18.2 (constants.%T.patt)]
@@ -179,8 +190,9 @@ fn AccessMissingConcrete(I:! Interface(i32)) -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc9_10: <witness> = require_complete_type @AccessGeneric.%Interface.type.loc8_43.2 (%Interface.type.d32) [symbolic = %require_complete.loc9_10 (constants.%require_complete.6f3)]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type @AccessGeneric.%Interface.type.loc8_43.2 (%Interface.type.d32), @AccessGeneric.%T.loc8_18.2 (%T) [symbolic = %assoc_type (constants.%assoc_type.376)]
-// CHECK:STDOUT:   %assoc0: @AccessGeneric.%assoc_type (%assoc_type.376) = assoc_entity element0, @Interface.%X [symbolic = %assoc0 (constants.%assoc0.fa3)]
+// CHECK:STDOUT:   %Interface.assoc_type: type = assoc_entity_type @AccessGeneric.%Interface.type.loc8_43.2 (%Interface.type.d32) [symbolic = %Interface.assoc_type (constants.%Interface.assoc_type.3bd)]
+// CHECK:STDOUT:   %assoc0: @AccessGeneric.%Interface.assoc_type (%Interface.assoc_type.3bd) = assoc_entity element0, @Interface.%X [symbolic = %assoc0 (constants.%assoc0.ed7)]
+// CHECK:STDOUT:   %I.as_type.loc9_11.2: type = facet_access_type %I.loc8_28.2 [symbolic = %I.as_type.loc9_11.2 (constants.%I.as_type.59e)]
 // CHECK:STDOUT:   %I.as_wit.loc9_11.2: <witness> = facet_access_witness %I.loc8_28.2 [symbolic = %I.as_wit.loc9_11.2 (constants.%I.as_wit.9f4)]
 // CHECK:STDOUT:   %impl.elem0.loc9_11.2: @AccessGeneric.%T.loc8_18.2 (%T) = impl_witness_access %I.as_wit.loc9_11.2, element0 [symbolic = %impl.elem0.loc9_11.2 (constants.%impl.elem0.68a)]
 // CHECK:STDOUT:   %require_complete.loc9_13: <witness> = require_complete_type @AccessGeneric.%T.loc8_18.2 (%T) [symbolic = %require_complete.loc9_13 (constants.%require_complete.4ae)]
@@ -188,8 +200,10 @@ fn AccessMissingConcrete(I:! Interface(i32)) -> i32 {
 // CHECK:STDOUT:   fn[%T.param_patt: type](%I.param_patt: @AccessGeneric.%Interface.type.loc8_43.2 (%Interface.type.d32)) -> @AccessGeneric.%T.loc8_18.2 (%T) {
 // CHECK:STDOUT:   !entry:
 // CHECK:STDOUT:     %I.ref: @AccessGeneric.%Interface.type.loc8_43.2 (%Interface.type.d32) = name_ref I, %I.loc8_28.1 [symbolic = %I.loc8_28.2 (constants.%I.a5f)]
-// CHECK:STDOUT:     %.loc9: @AccessGeneric.%assoc_type (%assoc_type.376) = specific_constant @Interface.%assoc0.loc5_8.1, @Interface(constants.%T) [symbolic = %assoc0 (constants.%assoc0.fa3)]
-// CHECK:STDOUT:     %X.ref: @AccessGeneric.%assoc_type (%assoc_type.376) = name_ref X, %.loc9 [symbolic = %assoc0 (constants.%assoc0.fa3)]
+// CHECK:STDOUT:     %.loc9_11.1: @AccessGeneric.%Interface.assoc_type (%Interface.assoc_type.3bd) = specific_constant @X.%assoc0, @Interface(constants.%T) [symbolic = %assoc0 (constants.%assoc0.ed7)]
+// CHECK:STDOUT:     %X.ref: @AccessGeneric.%Interface.assoc_type (%Interface.assoc_type.3bd) = name_ref X, %.loc9_11.1 [symbolic = %assoc0 (constants.%assoc0.ed7)]
+// CHECK:STDOUT:     %I.as_type.loc9_11.1: type = facet_access_type %I.ref [symbolic = %I.as_type.loc9_11.2 (constants.%I.as_type.59e)]
+// CHECK:STDOUT:     %.loc9_11.2: type = converted %I.ref, %I.as_type.loc9_11.1 [symbolic = %I.as_type.loc9_11.2 (constants.%I.as_type.59e)]
 // CHECK:STDOUT:     %I.as_wit.loc9_11.1: <witness> = facet_access_witness %I.ref [symbolic = %I.as_wit.loc9_11.2 (constants.%I.as_wit.9f4)]
 // CHECK:STDOUT:     %impl.elem0.loc9_11.1: @AccessGeneric.%T.loc8_18.2 (%T) = impl_witness_access %I.as_wit.loc9_11.1, element0 [symbolic = %impl.elem0.loc9_11.2 (constants.%impl.elem0.68a)]
 // CHECK:STDOUT:     return %impl.elem0.loc9_11.1
@@ -201,14 +215,17 @@ fn AccessMissingConcrete(I:! Interface(i32)) -> i32 {
 // CHECK:STDOUT:   %I.patt.loc12_19.2: %Interface.type.981 = symbolic_binding_pattern I, 0 [symbolic = %I.patt.loc12_19.2 (constants.%I.patt.1f8)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %I.as_type.loc13_11.2: type = facet_access_type %I.loc12_19.2 [symbolic = %I.as_type.loc13_11.2 (constants.%I.as_type.ee6)]
 // CHECK:STDOUT:   %I.as_wit.loc13_11.2: <witness> = facet_access_witness %I.loc12_19.2 [symbolic = %I.as_wit.loc13_11.2 (constants.%I.as_wit.156)]
 // CHECK:STDOUT:   %impl.elem0.loc13_11.2: %i32 = impl_witness_access %I.as_wit.loc13_11.2, element0 [symbolic = %impl.elem0.loc13_11.2 (constants.%impl.elem0.b00)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%I.param_patt: %Interface.type.981) -> %i32 {
 // CHECK:STDOUT:   !entry:
 // CHECK:STDOUT:     %I.ref: %Interface.type.981 = name_ref I, %I.loc12_19.1 [symbolic = %I.loc12_19.2 (constants.%I.d08)]
-// CHECK:STDOUT:     %.loc13: %assoc_type.5f0 = specific_constant @Interface.%assoc0.loc5_8.1, @Interface(constants.%i32) [template = constants.%assoc0.ed2]
-// CHECK:STDOUT:     %X.ref: %assoc_type.5f0 = name_ref X, %.loc13 [template = constants.%assoc0.ed2]
+// CHECK:STDOUT:     %.loc13_11.1: %Interface.assoc_type.44d = specific_constant @X.%assoc0, @Interface(constants.%i32) [template = constants.%assoc0.4ff]
+// CHECK:STDOUT:     %X.ref: %Interface.assoc_type.44d = name_ref X, %.loc13_11.1 [template = constants.%assoc0.4ff]
+// CHECK:STDOUT:     %I.as_type.loc13_11.1: type = facet_access_type %I.ref [symbolic = %I.as_type.loc13_11.2 (constants.%I.as_type.ee6)]
+// CHECK:STDOUT:     %.loc13_11.2: type = converted %I.ref, %I.as_type.loc13_11.1 [symbolic = %I.as_type.loc13_11.2 (constants.%I.as_type.ee6)]
 // CHECK:STDOUT:     %I.as_wit.loc13_11.1: <witness> = facet_access_witness %I.ref [symbolic = %I.as_wit.loc13_11.2 (constants.%I.as_wit.156)]
 // CHECK:STDOUT:     %impl.elem0.loc13_11.1: %i32 = impl_witness_access %I.as_wit.loc13_11.1, element0 [symbolic = %impl.elem0.loc13_11.2 (constants.%impl.elem0.b00)]
 // CHECK:STDOUT:     return %impl.elem0.loc13_11.1
@@ -222,9 +239,13 @@ fn AccessMissingConcrete(I:! Interface(i32)) -> i32 {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %Interface.type => constants.%Interface.type.d32
 // CHECK:STDOUT:   %Self.2 => constants.%Self
+// CHECK:STDOUT:   %Interface.assoc_type => constants.%Interface.assoc_type.3bd
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.ed7
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @X(constants.%T, constants.%Self) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT:   %require_complete => constants.%require_complete.4ae
-// CHECK:STDOUT:   %assoc_type => constants.%assoc_type.376
-// CHECK:STDOUT:   %assoc0.loc5_8.2 => constants.%assoc0.fa3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @Interface(%T.loc4_21.2) {}
@@ -239,6 +260,11 @@ fn AccessMissingConcrete(I:! Interface(i32)) -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @Interface(@AccessGeneric.%T.loc8_18.2) {}
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @X(constants.%T, constants.%Interface.facet.856) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %require_complete => constants.%require_complete.4ae
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @Interface(constants.%i32) {
 // CHECK:STDOUT:   %T.loc4_21.2 => constants.%i32
 // CHECK:STDOUT:   %T.patt.loc4_21.2 => constants.%i32
@@ -246,9 +272,8 @@ fn AccessMissingConcrete(I:! Interface(i32)) -> i32 {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %Interface.type => constants.%Interface.type.981
 // CHECK:STDOUT:   %Self.2 => constants.%Self
-// CHECK:STDOUT:   %require_complete => constants.%complete_type.f8a
-// CHECK:STDOUT:   %assoc_type => constants.%assoc_type.5f0
-// CHECK:STDOUT:   %assoc0.loc5_8.2 => constants.%assoc0.ed2
+// CHECK:STDOUT:   %Interface.assoc_type => constants.%Interface.assoc_type.44d
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.4ff
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @AccessConcrete(constants.%I.d08) {
@@ -256,6 +281,11 @@ fn AccessMissingConcrete(I:! Interface(i32)) -> i32 {
 // CHECK:STDOUT:   %I.patt.loc12_19.2 => constants.%I.d08
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @X(constants.%i32, constants.%Interface.facet.a3f) {
+// CHECK:STDOUT:   %T => constants.%i32
+// CHECK:STDOUT:   %require_complete => constants.%complete_type.f8a
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_no_member.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
@@ -266,8 +296,8 @@ fn AccessMissingConcrete(I:! Interface(i32)) -> i32 {
 // CHECK:STDOUT:   %Interface.type.d32: type = facet_type <@Interface, @Interface(%T)> [symbolic]
 // CHECK:STDOUT:   %Self: %Interface.type.d32 = bind_symbolic_name Self, 1 [symbolic]
 // CHECK:STDOUT:   %require_complete.4ae: <witness> = require_complete_type %T [symbolic]
-// CHECK:STDOUT:   %assoc_type.376: type = assoc_entity_type %Interface.type.d32, %T [symbolic]
-// CHECK:STDOUT:   %assoc0.fa3: %assoc_type.376 = assoc_entity element0, @Interface.%X [symbolic]
+// CHECK:STDOUT:   %Interface.assoc_type.3bd: type = assoc_entity_type %Interface.type.d32 [symbolic]
+// CHECK:STDOUT:   %assoc0.ed7: %Interface.assoc_type.3bd = assoc_entity element0, @Interface.%X [symbolic]
 // CHECK:STDOUT:   %I.a5f: %Interface.type.d32 = bind_symbolic_name I, 1 [symbolic]
 // CHECK:STDOUT:   %I.patt.47c: %Interface.type.d32 = symbolic_binding_pattern I, 1 [symbolic]
 // CHECK:STDOUT:   %AccessMissingGeneric.type: type = fn_type @AccessMissingGeneric [template]
@@ -280,10 +310,8 @@ fn AccessMissingConcrete(I:! Interface(i32)) -> i32 {
 // CHECK:STDOUT:   %I.patt.1f8: %Interface.type.981 = symbolic_binding_pattern I, 0 [symbolic]
 // CHECK:STDOUT:   %AccessMissingConcrete.type: type = fn_type @AccessMissingConcrete [template]
 // CHECK:STDOUT:   %AccessMissingConcrete: %AccessMissingConcrete.type = struct_value () [template]
-// CHECK:STDOUT:   %i32.builtin: type = int_type signed, %int_32 [template]
-// CHECK:STDOUT:   %complete_type.f8a: <witness> = complete_type_witness %i32.builtin [template]
-// CHECK:STDOUT:   %assoc_type.5f0: type = assoc_entity_type %Interface.type.981, %i32 [template]
-// CHECK:STDOUT:   %assoc0.ed2: %assoc_type.5f0 = assoc_entity element0, @Interface.%X [template]
+// CHECK:STDOUT:   %Interface.assoc_type.44d: type = assoc_entity_type %Interface.type.981 [template]
+// CHECK:STDOUT:   %assoc0.4ff: %Interface.assoc_type.44d = assoc_entity element0, @Interface.%X [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -358,22 +386,29 @@ fn AccessMissingConcrete(I:! Interface(i32)) -> i32 {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %Interface.type: type = facet_type <@Interface, @Interface(%T.loc4_21.2)> [symbolic = %Interface.type (constants.%Interface.type.d32)]
 // CHECK:STDOUT:   %Self.2: %Interface.type.d32 = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
-// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type @Interface.%T.loc4_21.2 (%T) [symbolic = %require_complete (constants.%require_complete.4ae)]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type @Interface.%Interface.type (%Interface.type.d32), @Interface.%T.loc4_21.2 (%T) [symbolic = %assoc_type (constants.%assoc_type.376)]
-// CHECK:STDOUT:   %assoc0.loc5_8.2: @Interface.%assoc_type (%assoc_type.376) = assoc_entity element0, %X [symbolic = %assoc0.loc5_8.2 (constants.%assoc0.fa3)]
+// CHECK:STDOUT:   %Interface.assoc_type: type = assoc_entity_type @Interface.%Interface.type (%Interface.type.d32) [symbolic = %Interface.assoc_type (constants.%Interface.assoc_type.3bd)]
+// CHECK:STDOUT:   %assoc0: @Interface.%Interface.assoc_type (%Interface.assoc_type.3bd) = assoc_entity element0, %X [symbolic = %assoc0 (constants.%assoc0.ed7)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:     %Self.1: @Interface.%Interface.type (%Interface.type.d32) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
-// CHECK:STDOUT:     %X: @Interface.%T.loc4_21.2 (%T) = assoc_const_decl X [template]
-// CHECK:STDOUT:     %assoc0.loc5_8.1: @Interface.%assoc_type (%assoc_type.376) = assoc_entity element0, %X [symbolic = %assoc0.loc5_8.2 (constants.%assoc0.fa3)]
+// CHECK:STDOUT:     %X: @X.%T (%T) = assoc_const_decl @X [template] {
+// CHECK:STDOUT:       %assoc0: @Interface.%Interface.assoc_type (%Interface.assoc_type.3bd) = assoc_entity element0, @Interface.%X [symbolic = @Interface.%assoc0 (constants.%assoc0.ed7)]
+// CHECK:STDOUT:     }
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = %Self.1
-// CHECK:STDOUT:     .X = %assoc0.loc5_8.1
+// CHECK:STDOUT:     .X = @X.%assoc0
 // CHECK:STDOUT:     witness = (%X)
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @X(@Interface.%T.loc4_21.1: type, @Interface.%Self.1: @Interface.%Interface.type (%Interface.type.d32)) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type @X.%T (%T) [symbolic = %require_complete (constants.%require_complete.4ae)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   assoc_const X:! @X.%T (%T);
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @AccessMissingGeneric(%T.loc8_25.1: type, %I.loc8_35.1: @AccessMissingGeneric.%Interface.type.loc8_50.2 (%Interface.type.d32)) {
 // CHECK:STDOUT:   %T.loc8_25.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc8_25.2 (constants.%T)]
 // CHECK:STDOUT:   %T.patt.loc8_25.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_25.2 (constants.%T.patt)]
@@ -413,9 +448,13 @@ fn AccessMissingConcrete(I:! Interface(i32)) -> i32 {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %Interface.type => constants.%Interface.type.d32
 // CHECK:STDOUT:   %Self.2 => constants.%Self
+// CHECK:STDOUT:   %Interface.assoc_type => constants.%Interface.assoc_type.3bd
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.ed7
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @X(constants.%T, constants.%Self) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT:   %require_complete => constants.%require_complete.4ae
-// CHECK:STDOUT:   %assoc_type => constants.%assoc_type.376
-// CHECK:STDOUT:   %assoc0.loc5_8.2 => constants.%assoc0.fa3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @Interface(%T.loc4_21.2) {}
@@ -437,9 +476,8 @@ fn AccessMissingConcrete(I:! Interface(i32)) -> i32 {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %Interface.type => constants.%Interface.type.981
 // CHECK:STDOUT:   %Self.2 => constants.%Self
-// CHECK:STDOUT:   %require_complete => constants.%complete_type.f8a
-// CHECK:STDOUT:   %assoc_type => constants.%assoc_type.5f0
-// CHECK:STDOUT:   %assoc0.loc5_8.2 => constants.%assoc0.ed2
+// CHECK:STDOUT:   %Interface.assoc_type => constants.%Interface.assoc_type.44d
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.4ff
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @AccessMissingConcrete(constants.%I.d08) {

+ 25 - 28
toolchain/check/testdata/interface/no_prelude/assoc_const_in_generic.carbon

@@ -35,24 +35,23 @@ fn H() {
 // CHECK:STDOUT:   %Self: %I.type.325 = bind_symbolic_name Self, 1 [symbolic]
 // CHECK:STDOUT:   %U: type = bind_symbolic_name U, 2 [symbolic]
 // CHECK:STDOUT:   %U.patt: type = symbolic_binding_pattern U, 2 [symbolic]
-// CHECK:STDOUT:   %F.type.2ae: type = fn_type @F, @I(%T) [symbolic]
-// CHECK:STDOUT:   %F: %F.type.2ae = struct_value () [symbolic]
-// CHECK:STDOUT:   %F.assoc_type.003: type = assoc_entity_type %I.type.325, %F.type.2ae [symbolic]
-// CHECK:STDOUT:   %assoc0.819: %F.assoc_type.003 = assoc_entity element0, @I.%F.decl [symbolic]
+// CHECK:STDOUT:   %F.type: type = fn_type @F, @I(%T) [symbolic]
+// CHECK:STDOUT:   %F: %F.type = struct_value () [symbolic]
+// CHECK:STDOUT:   %I.assoc_type.955: type = assoc_entity_type %I.type.325 [symbolic]
+// CHECK:STDOUT:   %assoc0.fef: %I.assoc_type.955 = assoc_entity element0, @I.%F.decl [symbolic]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
 // CHECK:STDOUT:   %require_complete.cfe: <witness> = require_complete_type %I.type.325 [symbolic]
-// CHECK:STDOUT:   %require_complete.ba5: <witness> = require_complete_type %F.assoc_type.003 [symbolic]
+// CHECK:STDOUT:   %require_complete.66f: <witness> = require_complete_type %I.assoc_type.955 [symbolic]
 // CHECK:STDOUT:   %H.type: type = fn_type @H [template]
 // CHECK:STDOUT:   %H: %H.type = struct_value () [template]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %G.specific_fn: <specific function> = specific_function %G, @G(%empty_struct_type) [template]
 // CHECK:STDOUT:   %I.type.885: type = facet_type <@I, @I(%empty_struct_type)> [template]
 // CHECK:STDOUT:   %complete_type.788: <witness> = complete_type_witness %I.type.885 [template]
-// CHECK:STDOUT:   %F.type.684: type = fn_type @F, @I(%empty_struct_type) [template]
-// CHECK:STDOUT:   %F.assoc_type.6a8: type = assoc_entity_type %I.type.885, %F.type.684 [template]
-// CHECK:STDOUT:   %assoc0.d32: %F.assoc_type.6a8 = assoc_entity element0, @I.%F.decl [template]
-// CHECK:STDOUT:   %complete_type.678: <witness> = complete_type_witness %F.assoc_type.6a8 [template]
+// CHECK:STDOUT:   %I.assoc_type.67f: type = assoc_entity_type %I.type.885 [template]
+// CHECK:STDOUT:   %assoc0.639: %I.assoc_type.67f = assoc_entity element0, @I.%F.decl [template]
+// CHECK:STDOUT:   %complete_type.973: <witness> = complete_type_witness %I.assoc_type.67f [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -85,14 +84,14 @@ fn H() {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %I.type: type = facet_type <@I, @I(%T.loc11_13.2)> [symbolic = %I.type (constants.%I.type.325)]
 // CHECK:STDOUT:   %Self.2: %I.type.325 = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
-// CHECK:STDOUT:   %F.type: type = fn_type @F, @I(%T.loc11_13.2) [symbolic = %F.type (constants.%F.type.2ae)]
-// CHECK:STDOUT:   %F: @I.%F.type (%F.type.2ae) = struct_value () [symbolic = %F (constants.%F)]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type @I.%I.type (%I.type.325), @I.%F.type (%F.type.2ae) [symbolic = %F.assoc_type (constants.%F.assoc_type.003)]
-// CHECK:STDOUT:   %assoc0.loc12_22.2: @I.%F.assoc_type (%F.assoc_type.003) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc12_22.2 (constants.%assoc0.819)]
+// CHECK:STDOUT:   %F.type: type = fn_type @F, @I(%T.loc11_13.2) [symbolic = %F.type (constants.%F.type)]
+// CHECK:STDOUT:   %F: @I.%F.type (%F.type) = struct_value () [symbolic = %F (constants.%F)]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type @I.%I.type (%I.type.325) [symbolic = %I.assoc_type (constants.%I.assoc_type.955)]
+// CHECK:STDOUT:   %assoc0.loc12_22.2: @I.%I.assoc_type (%I.assoc_type.955) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc12_22.2 (constants.%assoc0.fef)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:     %Self.1: @I.%I.type (%I.type.325) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
-// CHECK:STDOUT:     %F.decl: @I.%F.type (%F.type.2ae) = fn_decl @F [symbolic = @I.%F (constants.%F)] {
+// CHECK:STDOUT:     %F.decl: @I.%F.type (%F.type) = fn_decl @F [symbolic = @I.%F (constants.%F)] {
 // CHECK:STDOUT:       %U.patt.loc12_8.2: type = symbolic_binding_pattern U, 2 [symbolic = %U.patt.loc12_8.1 (constants.%U.patt)]
 // CHECK:STDOUT:       %U.param_patt: type = value_param_pattern %U.patt.loc12_8.2, runtime_param<none> [symbolic = %U.patt.loc12_8.1 (constants.%U.patt)]
 // CHECK:STDOUT:       %return.patt: @F.%U.loc12_8.1 (%U) = return_slot_pattern
@@ -104,7 +103,7 @@ fn H() {
 // CHECK:STDOUT:       %return.param: ref @F.%U.loc12_8.1 (%U) = out_param runtime_param0
 // CHECK:STDOUT:       %return: ref @F.%U.loc12_8.1 (%U) = return_slot %return.param
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %assoc0.loc12_22.1: @I.%F.assoc_type (%F.assoc_type.003) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc12_22.2 (constants.%assoc0.819)]
+// CHECK:STDOUT:     %assoc0.loc12_22.1: @I.%I.assoc_type (%I.assoc_type.955) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc12_22.2 (constants.%assoc0.fef)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = %Self.1
@@ -127,18 +126,17 @@ fn H() {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %I.type.loc19_6.2: type = facet_type <@I, @I(%T.loc15_6.2)> [symbolic = %I.type.loc19_6.2 (constants.%I.type.325)]
 // CHECK:STDOUT:   %require_complete.loc19_7.1: <witness> = require_complete_type @G.%I.type.loc19_6.2 (%I.type.325) [symbolic = %require_complete.loc19_7.1 (constants.%require_complete.cfe)]
-// CHECK:STDOUT:   %F.type: type = fn_type @F, @I(%T.loc15_6.2) [symbolic = %F.type (constants.%F.type.2ae)]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type @G.%I.type.loc19_6.2 (%I.type.325), @G.%F.type (%F.type.2ae) [symbolic = %F.assoc_type (constants.%F.assoc_type.003)]
-// CHECK:STDOUT:   %assoc0: @G.%F.assoc_type (%F.assoc_type.003) = assoc_entity element0, @I.%F.decl [symbolic = %assoc0 (constants.%assoc0.819)]
-// CHECK:STDOUT:   %require_complete.loc19_7.2: <witness> = require_complete_type @G.%F.assoc_type (%F.assoc_type.003) [symbolic = %require_complete.loc19_7.2 (constants.%require_complete.ba5)]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type @G.%I.type.loc19_6.2 (%I.type.325) [symbolic = %I.assoc_type (constants.%I.assoc_type.955)]
+// CHECK:STDOUT:   %assoc0: @G.%I.assoc_type (%I.assoc_type.955) = assoc_entity element0, @I.%F.decl [symbolic = %assoc0 (constants.%assoc0.fef)]
+// CHECK:STDOUT:   %require_complete.loc19_7.2: <witness> = require_complete_type @G.%I.assoc_type (%I.assoc_type.955) [symbolic = %require_complete.loc19_7.2 (constants.%require_complete.66f)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%T.param_patt: type) {
 // CHECK:STDOUT:   !entry:
 // CHECK:STDOUT:     %I.ref: %I.type.dac = name_ref I, file.%I.decl [template = constants.%I.generic]
 // CHECK:STDOUT:     %T.ref: type = name_ref T, %T.loc15_6.1 [symbolic = %T.loc15_6.2 (constants.%T)]
 // CHECK:STDOUT:     %I.type.loc19_6.1: type = facet_type <@I, @I(constants.%T)> [symbolic = %I.type.loc19_6.2 (constants.%I.type.325)]
-// CHECK:STDOUT:     %.loc19: @G.%F.assoc_type (%F.assoc_type.003) = specific_constant @I.%assoc0.loc12_22.1, @I(constants.%T) [symbolic = %assoc0 (constants.%assoc0.819)]
-// CHECK:STDOUT:     %F.ref: @G.%F.assoc_type (%F.assoc_type.003) = name_ref F, %.loc19 [symbolic = %assoc0 (constants.%assoc0.819)]
+// CHECK:STDOUT:     %.loc19: @G.%I.assoc_type (%I.assoc_type.955) = specific_constant @I.%assoc0.loc12_22.1, @I(constants.%T) [symbolic = %assoc0 (constants.%assoc0.fef)]
+// CHECK:STDOUT:     %F.ref: @G.%I.assoc_type (%I.assoc_type.955) = name_ref F, %.loc19 [symbolic = %assoc0 (constants.%assoc0.fef)]
 // CHECK:STDOUT:     return
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -160,10 +158,10 @@ fn H() {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %I.type => constants.%I.type.325
 // CHECK:STDOUT:   %Self.2 => constants.%Self
-// CHECK:STDOUT:   %F.type => constants.%F.type.2ae
+// CHECK:STDOUT:   %F.type => constants.%F.type
 // CHECK:STDOUT:   %F => constants.%F
-// CHECK:STDOUT:   %F.assoc_type => constants.%F.assoc_type.003
-// CHECK:STDOUT:   %assoc0.loc12_22.2 => constants.%assoc0.819
+// CHECK:STDOUT:   %I.assoc_type => constants.%I.assoc_type.955
+// CHECK:STDOUT:   %assoc0.loc12_22.2 => constants.%assoc0.fef
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%T, constants.%Self, constants.%U) {
@@ -187,10 +185,9 @@ fn H() {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %I.type.loc19_6.2 => constants.%I.type.885
 // CHECK:STDOUT:   %require_complete.loc19_7.1 => constants.%complete_type.788
-// CHECK:STDOUT:   %F.type => constants.%F.type.684
-// CHECK:STDOUT:   %F.assoc_type => constants.%F.assoc_type.6a8
-// CHECK:STDOUT:   %assoc0 => constants.%assoc0.d32
-// CHECK:STDOUT:   %require_complete.loc19_7.2 => constants.%complete_type.678
+// CHECK:STDOUT:   %I.assoc_type => constants.%I.assoc_type.67f
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.639
+// CHECK:STDOUT:   %require_complete.loc19_7.2 => constants.%complete_type.973
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @I(constants.%empty_struct_type) {

+ 3 - 4
toolchain/check/testdata/interface/no_prelude/basic.carbon

@@ -26,8 +26,8 @@ interface ForwardDeclared {
 // CHECK:STDOUT:   %Self.efa: %ForwardDeclared.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %ForwardDeclared.type, %F.type [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @ForwardDeclared.%F.decl [template]
+// CHECK:STDOUT:   %ForwardDeclared.assoc_type: type = assoc_entity_type %ForwardDeclared.type [template]
+// CHECK:STDOUT:   %assoc0: %ForwardDeclared.assoc_type = assoc_entity element0, @ForwardDeclared.%F.decl [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -51,7 +51,7 @@ interface ForwardDeclared {
 // CHECK:STDOUT: interface @ForwardDeclared {
 // CHECK:STDOUT:   %Self: %ForwardDeclared.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.efa]
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %ForwardDeclared.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -60,7 +60,6 @@ interface ForwardDeclared {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(@ForwardDeclared.%Self: %ForwardDeclared.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

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

@@ -32,8 +32,8 @@ class C {
 // CHECK:STDOUT:   %F.type.0b5: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %F.20c: %F.type.0b5 = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %I.type, %F.type.0b5 [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @I.%F.decl [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @I.%F.decl [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (@impl.%F.decl) [template]
 // CHECK:STDOUT:   %F.type.4a2: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.eb2: %F.type.4a2 = struct_value () [template]
@@ -53,7 +53,7 @@ class C {
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type.0b5 = fn_decl @F.1 [template = constants.%F.20c] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -102,7 +102,7 @@ class C {
 // CHECK:STDOUT:     %c: ref %C = bind_name c, %c.var
 // CHECK:STDOUT:     %c.ref: ref %C = name_ref c, %c
 // CHECK:STDOUT:     %I.ref: type = name_ref I, @C.%I.decl [template = constants.%I.type]
-// CHECK:STDOUT:     %F.ref: %F.assoc_type = name_ref F, @I.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %F.ref: %I.assoc_type = name_ref F, @I.%assoc0 [template = constants.%assoc0]
 // CHECK:STDOUT:     %impl.elem0: %F.type.0b5 = impl_witness_access constants.%impl_witness, element0 [template = constants.%F.eb2]
 // CHECK:STDOUT:     %F.call: init %empty_tuple.type = call %impl.elem0()
 // CHECK:STDOUT:     return

+ 0 - 2
toolchain/check/testdata/interface/no_prelude/fail_add_member_outside_definition.carbon

@@ -109,12 +109,10 @@ interface Outer {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @.1(@Outer.%Self: %Outer.type, @Inner.%Self.1: @Inner.%Inner.type (%Inner.type.3d8)) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.2(@Outer.%Self: %Outer.type, @Inner.%Self.1: @Inner.%Inner.type (%Inner.type.3d8)) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 19 - 7
toolchain/check/testdata/interface/no_prelude/fail_assoc_const_not_binding.carbon

@@ -9,9 +9,9 @@
 // TIP:   bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interface/no_prelude/fail_assoc_const_not_binding.carbon
 
 interface I {
-  // CHECK:STDERR: fail_assoc_const_not_binding.carbon:[[@LINE+4]]:3: error: semantics TODO: `tuple pattern in let/var` [SemanticsTodo]
+  // CHECK:STDERR: fail_assoc_const_not_binding.carbon:[[@LINE+4]]:7: error: semantics TODO: `tuple pattern in let/var` [SemanticsTodo]
   // CHECK:STDERR:   let (T:! type, U:! type);
-  // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR:       ^~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
   let (T:! type, U:! type);
 }
@@ -19,15 +19,27 @@ interface I {
 // CHECK:STDOUT: --- fail_assoc_const_not_binding.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %I.type: type = facet_type <@I> [template]
+// CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: file {}
+// CHECK:STDOUT: file {
+// CHECK:STDOUT:   package: <namespace> = namespace [template] {
+// CHECK:STDOUT:     .I = %I.decl
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %I.decl: type = interface_decl @I [template = constants.%I.type] {} {}
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @I {
+// CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
+// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = <unexpected>.inst15
-// CHECK:STDOUT:   .T = <unexpected>.inst19.loc16_9
-// CHECK:STDOUT:   .U = <unexpected>.inst22.loc16_19
-// CHECK:STDOUT:   witness = invalid
+// CHECK:STDOUT:   .Self = %Self
+// CHECK:STDOUT:   has_error
+// CHECK:STDOUT:   witness = ()
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: assoc_const @T T:! type;
+// CHECK:STDOUT:
+// CHECK:STDOUT: assoc_const @U U:! type;
+// CHECK:STDOUT:

+ 2 - 1
toolchain/check/testdata/interface/no_prelude/fail_assoc_const_template.carbon

@@ -26,7 +26,8 @@ interface I {
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = <unexpected>.inst15
-// CHECK:STDOUT:   .T = <unexpected>.inst19.loc16_17
 // CHECK:STDOUT:   witness = invalid
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: assoc_const @T T:! type;
+// CHECK:STDOUT:

+ 6 - 7
toolchain/check/testdata/interface/no_prelude/fail_duplicate.carbon

@@ -79,8 +79,8 @@ interface Class { }
 // CHECK:STDOUT:   %Self.86e: %.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %.type, %F.type [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @.1.%F.decl [template]
+// CHECK:STDOUT:   %.assoc_type: type = assoc_entity_type %.type [template]
+// CHECK:STDOUT:   %assoc0: %.assoc_type = assoc_entity element0, @.1.%F.decl [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -102,7 +102,7 @@ interface Class { }
 // CHECK:STDOUT: interface @.1 {
 // CHECK:STDOUT:   %Self: %.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.86e]
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -111,7 +111,6 @@ interface Class { }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(@.1.%Self: %.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -127,8 +126,8 @@ interface Class { }
 // CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self.86e [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %.type, %F.type [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @.1.%F.decl [template]
+// CHECK:STDOUT:   %.assoc_type: type = assoc_entity_type %.type [template]
+// CHECK:STDOUT:   %assoc0: %.assoc_type = assoc_entity element0, @.1.%F.decl [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -161,7 +160,7 @@ interface Class { }
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %self: @F.%Self.as_type.loc14_14.1 (%Self.as_type) = bind_name self, %self.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self

+ 12 - 3
toolchain/check/testdata/interface/no_prelude/fail_incomplete_type.carbon

@@ -27,6 +27,8 @@ interface I {
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %I.type: type = facet_type <@I> [template]
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -40,14 +42,21 @@ interface I {
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %T: <error> = assoc_const_decl T [template]
-// CHECK:STDOUT:   %assoc0: <error> = assoc_entity element0, %T [template = <error>]
+// CHECK:STDOUT:   %T: <error> = assoc_const_decl @T [template] {
+// CHECK:STDOUT:     %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [template = constants.%assoc0]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .T = %assoc0
+// CHECK:STDOUT:   .T = @T.%assoc0
 // CHECK:STDOUT:   witness = (%T)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @T(@I.%Self: %I.type) {
+// CHECK:STDOUT:   assoc_const T:! <error>;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: class @C;
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @T(constants.%Self) {}
+// CHECK:STDOUT:

+ 3 - 5
toolchain/check/testdata/interface/no_prelude/fail_lookup_undefined.carbon

@@ -62,8 +62,8 @@ interface BeingDefined {
 // CHECK:STDOUT:   %Self: %BeingDefined.type = 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:   %H.assoc_type: type = assoc_entity_type %BeingDefined.type, %H.type [template]
-// CHECK:STDOUT:   %assoc0: %H.assoc_type = assoc_entity element0, @BeingDefined.%H.decl [template]
+// CHECK:STDOUT:   %BeingDefined.assoc_type: type = assoc_entity_type %BeingDefined.type [template]
+// CHECK:STDOUT:   %assoc0: %BeingDefined.assoc_type = assoc_entity element0, @BeingDefined.%H.decl [template]
 // CHECK:STDOUT:   %.type.5fb: type = fn_type @.2 [template]
 // CHECK:STDOUT:   %.b15: %.type.5fb = struct_value () [template]
 // CHECK:STDOUT: }
@@ -93,7 +93,7 @@ interface BeingDefined {
 // CHECK:STDOUT:     %return.param: ref <error> = out_param runtime_param0
 // CHECK:STDOUT:     %return: ref <error> = return_slot %return.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc0: %H.assoc_type = assoc_entity element0, %H.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %BeingDefined.assoc_type = assoc_entity element0, %H.decl [template = constants.%assoc0]
 // CHECK:STDOUT:   %.decl: %.type.5fb = fn_decl @.2 [template = constants.%.b15] {} {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
@@ -112,12 +112,10 @@ interface BeingDefined {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @H(@BeingDefined.%Self: %BeingDefined.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn() -> <error>;
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @.2(@BeingDefined.%Self: %BeingDefined.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 18 - 13
toolchain/check/testdata/interface/no_prelude/fail_member_lookup.carbon

@@ -15,7 +15,7 @@ interface Interface {
 }
 
 fn F() {
-  // CHECK:STDERR: fail_member_lookup.carbon:[[@LINE+4]]:3: error: value of type `<associated <type of F> in Interface>` is not callable [CallToNonCallable]
+  // CHECK:STDERR: fail_member_lookup.carbon:[[@LINE+4]]:3: error: value of type `<associated entity in Interface>` is not callable [CallToNonCallable]
   // CHECK:STDERR:   Interface.F();
   // CHECK:STDERR:   ^~~~~~~~~~~~~
   // CHECK:STDERR:
@@ -43,10 +43,9 @@ fn G(U:! Different) -> U.(Interface.T);
 // CHECK:STDOUT:   %Self.719: %Interface.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %F.type.1ad: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.5d3: %F.type.1ad = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %Interface.type, %F.type.1ad [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @Interface.%F.decl [template]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %Interface.type, type [template]
-// CHECK:STDOUT:   %assoc1: %assoc_type = assoc_entity element1, @Interface.%T [template]
+// CHECK:STDOUT:   %Interface.assoc_type: type = assoc_entity_type %Interface.type [template]
+// CHECK:STDOUT:   %assoc0: %Interface.assoc_type = assoc_entity element0, @Interface.%F.decl [template]
+// CHECK:STDOUT:   %assoc1: %Interface.assoc_type = assoc_entity element1, @Interface.%T [template]
 // CHECK:STDOUT:   %F.type.b25: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.c41: %F.type.b25 = struct_value () [template]
 // CHECK:STDOUT:   %Different.type: type = facet_type <@Different> [template]
@@ -75,7 +74,7 @@ fn G(U:! Different) -> U.(Interface.T);
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %U.ref: %Different.type = name_ref U, %U.loc37_6.1 [symbolic = %U.loc37_6.2 (constants.%U)]
 // CHECK:STDOUT:     %Interface.ref: type = name_ref Interface, file.%Interface.decl [template = constants.%Interface.type]
-// CHECK:STDOUT:     %T.ref: %assoc_type = name_ref T, @Interface.%assoc1 [template = constants.%assoc1]
+// CHECK:STDOUT:     %T.ref: %Interface.assoc_type = name_ref T, @T.%assoc1 [template = constants.%assoc1]
 // CHECK:STDOUT:     %U.param: %Different.type = value_param runtime_param<none>
 // CHECK:STDOUT:     %Different.ref: type = name_ref Different, file.%Different.decl [template = constants.%Different.type]
 // CHECK:STDOUT:     %U.loc37_6.1: %Different.type = bind_symbolic_name U, 0, %U.param [symbolic = %U.loc37_6.2 (constants.%U)]
@@ -87,14 +86,15 @@ fn G(U:! Different) -> U.(Interface.T);
 // CHECK:STDOUT: interface @Interface {
 // CHECK:STDOUT:   %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.719]
 // CHECK:STDOUT:   %F.decl: %F.type.1ad = fn_decl @F.1 [template = constants.%F.5d3] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
-// CHECK:STDOUT:   %T: type = assoc_const_decl T [template]
-// CHECK:STDOUT:   %assoc1: %assoc_type = assoc_entity element1, %T [template = constants.%assoc1]
+// CHECK:STDOUT:   %assoc0: %Interface.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %T: type = assoc_const_decl @T [template] {
+// CHECK:STDOUT:     %assoc1: %Interface.assoc_type = assoc_entity element1, @Interface.%T [template = constants.%assoc1]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
 // CHECK:STDOUT:   .F = %assoc0
-// CHECK:STDOUT:   .T = %assoc1
+// CHECK:STDOUT:   .T = @T.%assoc1
 // CHECK:STDOUT:   witness = (%F.decl, %T)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -106,15 +106,18 @@ fn G(U:! Different) -> U.(Interface.T);
 // CHECK:STDOUT:   witness = ()
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: generic fn @F.1(@Interface.%Self: %Interface.type) {
+// CHECK:STDOUT: generic assoc_const @T(@Interface.%Self: %Interface.type) {
+// CHECK:STDOUT:   assoc_const T:! type;
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @F.1(@Interface.%Self: %Interface.type) {
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.2() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Interface.ref.loc22: type = name_ref Interface, file.%Interface.decl [template = constants.%Interface.type]
-// CHECK:STDOUT:   %F.ref: %F.assoc_type = name_ref F, @Interface.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:   %F.ref: %Interface.assoc_type = name_ref F, @Interface.%assoc0 [template = constants.%assoc0]
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %v.patt: <error> = binding_pattern v
 // CHECK:STDOUT:     %.loc28_3: <error> = var_pattern %v.patt
@@ -122,7 +125,7 @@ fn G(U:! Different) -> U.(Interface.T);
 // CHECK:STDOUT:   %v.var: ref <error> = var v
 // CHECK:STDOUT:   %.1: <error> = splice_block <error> [template = <error>] {
 // CHECK:STDOUT:     %Interface.ref.loc28: type = name_ref Interface, file.%Interface.decl [template = constants.%Interface.type]
-// CHECK:STDOUT:     %T.ref: %assoc_type = name_ref T, @Interface.%assoc1 [template = constants.%assoc1]
+// CHECK:STDOUT:     %T.ref: %Interface.assoc_type = name_ref T, @T.%assoc1 [template = constants.%assoc1]
 // CHECK:STDOUT:     %.loc28_19: type = converted %T.ref, <error> [template = <error>]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %v: <error> = bind_name v, <error>
@@ -138,6 +141,8 @@ fn G(U:! Different) -> U.(Interface.T);
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F.1(constants.%Self.719) {}
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @T(constants.%Self.719) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @G(constants.%U) {
 // CHECK:STDOUT:   %U.loc37_6.2 => constants.%U
 // CHECK:STDOUT:   %U.patt.loc37_6.2 => constants.%U

+ 6 - 6
toolchain/check/testdata/interface/no_prelude/fail_modifiers.carbon

@@ -156,8 +156,8 @@ interface I {
 // CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %I.type, %F.type [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @I.%F.decl [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @I.%F.decl [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -181,7 +181,7 @@ interface I {
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %self: @F.%Self.as_type.loc9_22.1 (%Self.as_type) = bind_name self, %self.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -209,8 +209,8 @@ interface I {
 // CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %I.type, %F.type [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @I.%F.decl [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @I.%F.decl [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -234,7 +234,7 @@ interface I {
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %self: @F.%Self.as_type.loc9_24.1 (%Self.as_type) = bind_name self, %self.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self

+ 3 - 5
toolchain/check/testdata/interface/no_prelude/fail_redeclare_member.carbon

@@ -27,8 +27,8 @@ interface Interface {
 // CHECK:STDOUT:   %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %Interface.type, %F.type [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @Interface.%F.decl [template]
+// CHECK:STDOUT:   %Interface.assoc_type: type = assoc_entity_type %Interface.type [template]
+// CHECK:STDOUT:   %assoc0: %Interface.assoc_type = assoc_entity element0, @Interface.%F.decl [template]
 // CHECK:STDOUT:   %.type: type = fn_type @.1 [template]
 // CHECK:STDOUT:   %.563: %.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -43,7 +43,7 @@ interface Interface {
 // CHECK:STDOUT: interface @Interface {
 // CHECK:STDOUT:   %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %Interface.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:   %.decl: %.type = fn_decl @.1 [template = constants.%.563] {} {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
@@ -53,12 +53,10 @@ interface Interface {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(@Interface.%Self: %Interface.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @.1(@Interface.%Self: %Interface.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 8 - 6
toolchain/check/testdata/interface/no_prelude/fail_todo_facet_lookup.carbon

@@ -33,15 +33,15 @@ fn CallFacet(T:! Interface, x: T) {
 // CHECK:STDOUT:   %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %Interface.type, %F.type [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @Interface.%F.decl [template]
+// CHECK:STDOUT:   %Interface.assoc_type: type = assoc_entity_type %Interface.type [template]
+// CHECK:STDOUT:   %assoc0: %Interface.assoc_type = assoc_entity element0, @Interface.%F.decl [template]
 // CHECK:STDOUT:   %T: %Interface.type = bind_symbolic_name T, 0 [symbolic]
 // CHECK:STDOUT:   %T.patt: %Interface.type = symbolic_binding_pattern T, 0 [symbolic]
 // CHECK:STDOUT:   %CallStatic.type: type = fn_type @CallStatic [template]
 // CHECK:STDOUT:   %CallStatic: %CallStatic.type = struct_value () [template]
+// CHECK:STDOUT:   %T.as_type: type = facet_access_type %T [symbolic]
 // CHECK:STDOUT:   %T.as_wit: <witness> = facet_access_witness %T [symbolic]
 // CHECK:STDOUT:   %impl.elem0: %F.type = impl_witness_access %T.as_wit, element0 [symbolic]
-// CHECK:STDOUT:   %T.as_type: type = facet_access_type %T [symbolic]
 // CHECK:STDOUT:   %CallFacet.type: type = fn_type @CallFacet [template]
 // CHECK:STDOUT:   %CallFacet: %CallFacet.type = struct_value () [template]
 // CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %T.as_type [symbolic]
@@ -84,7 +84,7 @@ fn CallFacet(T:! Interface, x: T) {
 // CHECK:STDOUT: interface @Interface {
 // CHECK:STDOUT:   %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %Interface.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -93,7 +93,6 @@ fn CallFacet(T:! Interface, x: T) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(@Interface.%Self: %Interface.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -102,13 +101,16 @@ fn CallFacet(T:! Interface, x: T) {
 // CHECK:STDOUT:   %T.patt.loc13_15.2: %Interface.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc13_15.2 (constants.%T.patt)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %T.as_type.loc18_4.2: type = facet_access_type %T.loc13_15.2 [symbolic = %T.as_type.loc18_4.2 (constants.%T.as_type)]
 // CHECK:STDOUT:   %T.as_wit.loc18_4.2: <witness> = facet_access_witness %T.loc13_15.2 [symbolic = %T.as_wit.loc18_4.2 (constants.%T.as_wit)]
 // CHECK:STDOUT:   %impl.elem0.loc18_4.2: %F.type = impl_witness_access %T.as_wit.loc18_4.2, element0 [symbolic = %impl.elem0.loc18_4.2 (constants.%impl.elem0)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%T.param_patt: %Interface.type) {
 // CHECK:STDOUT:   !entry:
 // CHECK:STDOUT:     %T.ref: %Interface.type = name_ref T, %T.loc13_15.1 [symbolic = %T.loc13_15.2 (constants.%T)]
-// CHECK:STDOUT:     %F.ref: %F.assoc_type = name_ref F, @Interface.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %F.ref: %Interface.assoc_type = name_ref F, @Interface.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:     %T.as_type.loc18_4.1: type = facet_access_type %T.ref [symbolic = %T.as_type.loc18_4.2 (constants.%T.as_type)]
+// CHECK:STDOUT:     %.loc18: type = converted %T.ref, %T.as_type.loc18_4.1 [symbolic = %T.as_type.loc18_4.2 (constants.%T.as_type)]
 // CHECK:STDOUT:     %T.as_wit.loc18_4.1: <witness> = facet_access_witness %T.ref [symbolic = %T.as_wit.loc18_4.2 (constants.%T.as_wit)]
 // CHECK:STDOUT:     %impl.elem0.loc18_4.1: %F.type = impl_witness_access %T.as_wit.loc18_4.1, element0 [symbolic = %impl.elem0.loc18_4.2 (constants.%impl.elem0)]
 // CHECK:STDOUT:     return

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

@@ -34,8 +34,8 @@ fn I(T:! type).F[self: Self]() -> Self { return self; }
 // CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F, @I(%T) [symbolic]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [symbolic]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %I.type.325, %F.type [symbolic]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @I.%F.decl [symbolic]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type.325 [symbolic]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @I.%F.decl [symbolic]
 // CHECK:STDOUT:   %.type: type = fn_type @.1, @I(%T) [symbolic]
 // CHECK:STDOUT:   %.075: %.type = struct_value () [symbolic]
 // CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %Self.as_type [symbolic]
@@ -86,8 +86,8 @@ fn I(T:! type).F[self: Self]() -> Self { return self; }
 // CHECK:STDOUT:   %Self.2: %I.type.325 = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
 // CHECK:STDOUT:   %F.type: type = fn_type @F, @I(%T.loc11_13.2) [symbolic = %F.type (constants.%F.type)]
 // CHECK:STDOUT:   %F: @I.%F.type (%F.type) = struct_value () [symbolic = %F (constants.%F)]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type @I.%I.type (%I.type.325), @I.%F.type (%F.type) [symbolic = %F.assoc_type (constants.%F.assoc_type)]
-// CHECK:STDOUT:   %assoc0.loc13_29.2: @I.%F.assoc_type (%F.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc13_29.2 (constants.%assoc0)]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type @I.%I.type (%I.type.325) [symbolic = %I.assoc_type (constants.%I.assoc_type)]
+// CHECK:STDOUT:   %assoc0.loc13_29.2: @I.%I.assoc_type (%I.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc13_29.2 (constants.%assoc0)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:     %Self.1: @I.%I.type (%I.type.325) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
@@ -112,7 +112,7 @@ fn I(T:! type).F[self: Self]() -> Self { return self; }
 // CHECK:STDOUT:       %return.param: ref @F.%Self.as_type.loc13_14.1 (%Self.as_type) = out_param runtime_param1
 // CHECK:STDOUT:       %return: ref @F.%Self.as_type.loc13_14.1 (%Self.as_type) = return_slot %return.param
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %assoc0.loc13_29.1: @I.%F.assoc_type (%F.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc13_29.2 (constants.%assoc0)]
+// CHECK:STDOUT:     %assoc0.loc13_29.1: @I.%I.assoc_type (%I.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc13_29.2 (constants.%assoc0)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = %Self.1
@@ -156,7 +156,7 @@ fn I(T:! type).F[self: Self]() -> Self { return self; }
 // CHECK:STDOUT:   %Self.2 => constants.%Self
 // CHECK:STDOUT:   %F.type => constants.%F.type
 // CHECK:STDOUT:   %F => constants.%F
-// CHECK:STDOUT:   %F.assoc_type => constants.%F.assoc_type
+// CHECK:STDOUT:   %I.assoc_type => constants.%I.assoc_type
 // CHECK:STDOUT:   %assoc0.loc13_29.2 => constants.%assoc0
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 5 - 6
toolchain/check/testdata/interface/no_prelude/fail_todo_modifiers.carbon

@@ -28,12 +28,11 @@ interface Modifiers {
 // CHECK:STDOUT:   %Self: %Modifiers.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %Final.type: type = fn_type @Final [template]
 // CHECK:STDOUT:   %Final: %Final.type = struct_value () [template]
-// CHECK:STDOUT:   %Final.assoc_type: type = assoc_entity_type %Modifiers.type, %Final.type [template]
-// CHECK:STDOUT:   %assoc0: %Final.assoc_type = assoc_entity element0, @Modifiers.%Final.decl [template]
+// CHECK:STDOUT:   %Modifiers.assoc_type: type = assoc_entity_type %Modifiers.type [template]
+// CHECK:STDOUT:   %assoc0: %Modifiers.assoc_type = 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:   %Default.assoc_type: type = assoc_entity_type %Modifiers.type, %Default.type [template]
-// CHECK:STDOUT:   %assoc1: %Default.assoc_type = assoc_entity element1, @Modifiers.%Default.decl [template]
+// CHECK:STDOUT:   %assoc1: %Modifiers.assoc_type = assoc_entity element1, @Modifiers.%Default.decl [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -46,9 +45,9 @@ interface Modifiers {
 // CHECK:STDOUT: interface @Modifiers {
 // CHECK:STDOUT:   %Self: %Modifiers.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %Final.decl: %Final.type = fn_decl @Final [template = constants.%Final] {} {}
-// CHECK:STDOUT:   %assoc0: %Final.assoc_type = assoc_entity element0, %Final.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %Modifiers.assoc_type = assoc_entity element0, %Final.decl [template = constants.%assoc0]
 // CHECK:STDOUT:   %Default.decl: %Default.type = fn_decl @Default [template = constants.%Default] {} {}
-// CHECK:STDOUT:   %assoc1: %Default.assoc_type = assoc_entity element1, %Default.decl [template = constants.%assoc1]
+// CHECK:STDOUT:   %assoc1: %Modifiers.assoc_type = assoc_entity element1, %Default.decl [template = constants.%assoc1]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self

+ 9 - 10
toolchain/check/testdata/interface/no_prelude/generic.carbon

@@ -78,16 +78,16 @@ fn G(T:! Generic(B)) {
 // CHECK:STDOUT:   %Self.088: %WithAssocFn.type.ce6 = bind_symbolic_name Self, 1 [symbolic]
 // CHECK:STDOUT:   %F.type.1af: type = fn_type @F.1, @WithAssocFn(%T.8b3) [symbolic]
 // CHECK:STDOUT:   %F.b7d: %F.type.1af = struct_value () [symbolic]
-// CHECK:STDOUT:   %F.assoc_type.cd3: type = assoc_entity_type %WithAssocFn.type.ce6, %F.type.1af [symbolic]
-// CHECK:STDOUT:   %assoc0.8a0: %F.assoc_type.cd3 = assoc_entity element0, @WithAssocFn.%F.decl [symbolic]
+// CHECK:STDOUT:   %WithAssocFn.assoc_type.02b: type = assoc_entity_type %WithAssocFn.type.ce6 [symbolic]
+// CHECK:STDOUT:   %assoc0.470: %WithAssocFn.assoc_type.02b = assoc_entity element0, @WithAssocFn.%F.decl [symbolic]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %Simple.type.51f: type = facet_type <@Simple, @Simple(%C)> [template]
 // CHECK:STDOUT:   %impl_witness.1bc: <witness> = impl_witness () [template]
 // CHECK:STDOUT:   %WithAssocFn.type.683: type = facet_type <@WithAssocFn, @WithAssocFn(%C)> [template]
 // CHECK:STDOUT:   %F.type.18c: type = fn_type @F.1, @WithAssocFn(%C) [template]
 // CHECK:STDOUT:   %F.e46: %F.type.18c = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type.4f8: type = assoc_entity_type %WithAssocFn.type.683, %F.type.18c [template]
-// CHECK:STDOUT:   %assoc0.86f: %F.assoc_type.4f8 = assoc_entity element0, @WithAssocFn.%F.decl [template]
+// CHECK:STDOUT:   %WithAssocFn.assoc_type.480: type = assoc_entity_type %WithAssocFn.type.683 [template]
+// CHECK:STDOUT:   %assoc0.136: %WithAssocFn.assoc_type.480 = assoc_entity element0, @WithAssocFn.%F.decl [template]
 // CHECK:STDOUT:   %impl_witness.49b: <witness> = impl_witness (@impl.2.%F.decl) [template]
 // CHECK:STDOUT:   %F.type.005: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.317: %F.type.005 = struct_value () [template]
@@ -196,8 +196,8 @@ fn G(T:! Generic(B)) {
 // CHECK:STDOUT:   %Self.2: %WithAssocFn.type.ce6 = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self.088)]
 // CHECK:STDOUT:   %F.type: type = fn_type @F.1, @WithAssocFn(%T.loc8_23.2) [symbolic = %F.type (constants.%F.type.1af)]
 // CHECK:STDOUT:   %F: @WithAssocFn.%F.type (%F.type.1af) = struct_value () [symbolic = %F (constants.%F.b7d)]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type @WithAssocFn.%WithAssocFn.type (%WithAssocFn.type.ce6), @WithAssocFn.%F.type (%F.type.1af) [symbolic = %F.assoc_type (constants.%F.assoc_type.cd3)]
-// CHECK:STDOUT:   %assoc0.loc10_14.2: @WithAssocFn.%F.assoc_type (%F.assoc_type.cd3) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc10_14.2 (constants.%assoc0.8a0)]
+// CHECK:STDOUT:   %WithAssocFn.assoc_type: type = assoc_entity_type @WithAssocFn.%WithAssocFn.type (%WithAssocFn.type.ce6) [symbolic = %WithAssocFn.assoc_type (constants.%WithAssocFn.assoc_type.02b)]
+// CHECK:STDOUT:   %assoc0.loc10_14.2: @WithAssocFn.%WithAssocFn.assoc_type (%WithAssocFn.assoc_type.02b) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc10_14.2 (constants.%assoc0.470)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:     %Self.1: @WithAssocFn.%WithAssocFn.type (%WithAssocFn.type.ce6) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self.088)]
@@ -209,7 +209,7 @@ fn G(T:! Generic(B)) {
 // CHECK:STDOUT:       %return.param: ref %X = out_param runtime_param0
 // CHECK:STDOUT:       %return: ref %X = return_slot %return.param
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %assoc0.loc10_14.1: @WithAssocFn.%F.assoc_type (%F.assoc_type.cd3) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc10_14.2 (constants.%assoc0.8a0)]
+// CHECK:STDOUT:     %assoc0.loc10_14.1: @WithAssocFn.%WithAssocFn.assoc_type (%WithAssocFn.assoc_type.02b) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc10_14.2 (constants.%assoc0.470)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = %Self.1
@@ -278,7 +278,6 @@ fn G(T:! Generic(B)) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(@WithAssocFn.%T.loc8_23.1: type, @WithAssocFn.%Self.1: @WithAssocFn.%WithAssocFn.type (%WithAssocFn.type.ce6)) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn() -> %X;
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -353,8 +352,8 @@ fn G(T:! Generic(B)) {
 // CHECK:STDOUT:   %Self.2 => constants.%Self.088
 // CHECK:STDOUT:   %F.type => constants.%F.type.18c
 // CHECK:STDOUT:   %F => constants.%F.e46
-// CHECK:STDOUT:   %F.assoc_type => constants.%F.assoc_type.4f8
-// CHECK:STDOUT:   %assoc0.loc10_14.2 => constants.%assoc0.86f
+// CHECK:STDOUT:   %WithAssocFn.assoc_type => constants.%WithAssocFn.assoc_type.480
+// CHECK:STDOUT:   %assoc0.loc10_14.2 => constants.%assoc0.136
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F.1(constants.%C, constants.%WithAssocFn.facet) {}

+ 16 - 11
toolchain/check/testdata/interface/no_prelude/generic_binding_after_assoc_const.carbon

@@ -25,14 +25,12 @@ interface I {
 // CHECK:STDOUT:   %T.patt: type = symbolic_binding_pattern T, 1 [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %I.type, %F.type [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @I.%F.decl [template]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %I.type, type [template]
-// CHECK:STDOUT:   %assoc1: %assoc_type = assoc_entity element1, @I.%U [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @I.%F.decl [template]
+// CHECK:STDOUT:   %assoc1: %I.assoc_type = 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:   %G.assoc_type: type = assoc_entity_type %I.type, %G.type [template]
-// CHECK:STDOUT:   %assoc2: %G.assoc_type = assoc_entity element2, @I.%G.decl [template]
+// CHECK:STDOUT:   %assoc2: %I.assoc_type = assoc_entity element2, @I.%G.decl [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -51,9 +49,10 @@ interface I {
 // CHECK:STDOUT:     %T.param: type = value_param runtime_param<none>
 // CHECK:STDOUT:     %T.loc12_8.2: type = bind_symbolic_name T, 1, %T.param [symbolic = %T.loc12_8.1 (constants.%T)]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
-// CHECK:STDOUT:   %U: type = assoc_const_decl U [template]
-// CHECK:STDOUT:   %assoc1: %assoc_type = assoc_entity element1, %U [template = constants.%assoc1]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %U: type = assoc_const_decl @U [template] {
+// CHECK:STDOUT:     %assoc1: %I.assoc_type = assoc_entity element1, @I.%U [template = constants.%assoc1]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [template = constants.%G] {
 // CHECK:STDOUT:     %T.patt.loc16_8.2: type = symbolic_binding_pattern T, 1 [symbolic = %T.patt.loc16_8.1 (constants.%T.patt)]
 // CHECK:STDOUT:     %T.param_patt: type = value_param_pattern %T.patt.loc16_8.2, runtime_param<none> [symbolic = %T.patt.loc16_8.1 (constants.%T.patt)]
@@ -61,16 +60,20 @@ interface I {
 // CHECK:STDOUT:     %T.param: type = value_param runtime_param<none>
 // CHECK:STDOUT:     %T.loc16_8.2: type = bind_symbolic_name T, 1, %T.param [symbolic = %T.loc16_8.1 (constants.%T)]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc2: %G.assoc_type = assoc_entity element2, %G.decl [template = constants.%assoc2]
+// CHECK:STDOUT:   %assoc2: %I.assoc_type = assoc_entity element2, %G.decl [template = constants.%assoc2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
 // CHECK:STDOUT:   .F = %assoc0
-// CHECK:STDOUT:   .U = %assoc1
+// CHECK:STDOUT:   .U = @U.%assoc1
 // CHECK:STDOUT:   .G = %assoc2
 // CHECK:STDOUT:   witness = (%F.decl, %U, %G.decl)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @U(@I.%Self: %I.type) {
+// CHECK:STDOUT:   assoc_const U:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(@I.%Self: %I.type, %T.loc12_8.2: type) {
 // CHECK:STDOUT:   %T.loc12_8.1: type = bind_symbolic_name T, 1 [symbolic = %T.loc12_8.1 (constants.%T)]
 // CHECK:STDOUT:   %T.patt.loc12_8.1: type = symbolic_binding_pattern T, 1 [symbolic = %T.patt.loc12_8.1 (constants.%T.patt)]
@@ -90,6 +93,8 @@ interface I {
 // CHECK:STDOUT:   %T.patt.loc12_8.1 => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @U(constants.%Self) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @G(constants.%Self, constants.%T) {
 // CHECK:STDOUT:   %T.loc16_8.1 => constants.%T
 // CHECK:STDOUT:   %T.patt.loc16_8.1 => constants.%T

+ 15 - 17
toolchain/check/testdata/interface/no_prelude/generic_import.carbon

@@ -38,8 +38,8 @@ impl C as AddWith(C) {
 // CHECK:STDOUT:   %Self: %AddWith.type.bc7 = 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:   %F.assoc_type: type = assoc_entity_type %AddWith.type.bc7, %F.type [symbolic]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @AddWith.%F.decl [symbolic]
+// CHECK:STDOUT:   %AddWith.assoc_type: type = assoc_entity_type %AddWith.type.bc7 [symbolic]
+// CHECK:STDOUT:   %assoc0: %AddWith.assoc_type = assoc_entity element0, @AddWith.%F.decl [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -64,13 +64,13 @@ impl C as AddWith(C) {
 // CHECK:STDOUT:   %Self.2: %AddWith.type.bc7 = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
 // CHECK:STDOUT:   %F.type: type = fn_type @F, @AddWith(%T.loc4_19.2) [symbolic = %F.type (constants.%F.type)]
 // CHECK:STDOUT:   %F: @AddWith.%F.type (%F.type) = struct_value () [symbolic = %F (constants.%F)]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type @AddWith.%AddWith.type (%AddWith.type.bc7), @AddWith.%F.type (%F.type) [symbolic = %F.assoc_type (constants.%F.assoc_type)]
-// CHECK:STDOUT:   %assoc0.loc5_9.2: @AddWith.%F.assoc_type (%F.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc5_9.2 (constants.%assoc0)]
+// CHECK:STDOUT:   %AddWith.assoc_type: type = assoc_entity_type @AddWith.%AddWith.type (%AddWith.type.bc7) [symbolic = %AddWith.assoc_type (constants.%AddWith.assoc_type)]
+// CHECK:STDOUT:   %assoc0.loc5_9.2: @AddWith.%AddWith.assoc_type (%AddWith.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc5_9.2 (constants.%assoc0)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:     %Self.1: @AddWith.%AddWith.type (%AddWith.type.bc7) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
 // CHECK:STDOUT:     %F.decl: @AddWith.%F.type (%F.type) = fn_decl @F [symbolic = @AddWith.%F (constants.%F)] {} {}
-// CHECK:STDOUT:     %assoc0.loc5_9.1: @AddWith.%F.assoc_type (%F.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc5_9.2 (constants.%assoc0)]
+// CHECK:STDOUT:     %assoc0.loc5_9.1: @AddWith.%AddWith.assoc_type (%AddWith.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc5_9.2 (constants.%assoc0)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = %Self.1
@@ -80,7 +80,6 @@ impl C as AddWith(C) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(@AddWith.%T.loc4_19.1: type, @AddWith.%Self.1: @AddWith.%AddWith.type (%AddWith.type.bc7)) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -107,13 +106,13 @@ impl C as AddWith(C) {
 // CHECK:STDOUT:   %T.patt: type = symbolic_binding_pattern T, 0 [symbolic]
 // CHECK:STDOUT:   %F.type.fbc: type = fn_type @F.1, @AddWith(%T) [symbolic]
 // CHECK:STDOUT:   %F.be3: %F.type.fbc = struct_value () [symbolic]
-// CHECK:STDOUT:   %F.assoc_type.f26: type = assoc_entity_type %AddWith.type.bc7, %F.type.fbc [symbolic]
-// CHECK:STDOUT:   %assoc0.1ff: %F.assoc_type.f26 = assoc_entity element0, imports.%Main.import_ref.0c5 [symbolic]
+// CHECK:STDOUT:   %AddWith.assoc_type.73f: type = assoc_entity_type %AddWith.type.bc7 [symbolic]
+// CHECK:STDOUT:   %assoc0.80d: %AddWith.assoc_type.73f = assoc_entity element0, imports.%Main.import_ref.0c5 [symbolic]
 // CHECK:STDOUT:   %AddWith.type.e8e: type = facet_type <@AddWith, @AddWith(%C)> [template]
 // CHECK:STDOUT:   %F.type.cd2: type = fn_type @F.1, @AddWith(%C) [template]
 // CHECK:STDOUT:   %F.b58: %F.type.cd2 = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type.c97: type = assoc_entity_type %AddWith.type.e8e, %F.type.cd2 [template]
-// CHECK:STDOUT:   %assoc0.dc2: %F.assoc_type.c97 = assoc_entity element0, imports.%Main.import_ref.0c5 [template]
+// CHECK:STDOUT:   %AddWith.assoc_type.ace: type = assoc_entity_type %AddWith.type.e8e [template]
+// CHECK:STDOUT:   %assoc0.a9f: %AddWith.assoc_type.ace = assoc_entity element0, imports.%Main.import_ref.0c5 [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (@impl.%F.decl) [template]
 // CHECK:STDOUT:   %F.type.c09: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.e62: %F.type.c09 = struct_value () [template]
@@ -123,7 +122,7 @@ impl C as AddWith(C) {
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Main.AddWith: %AddWith.type.b35 = import_ref Main//a, AddWith, loaded [template = constants.%AddWith.generic]
 // CHECK:STDOUT:   %Main.import_ref.476 = import_ref Main//a, inst26 [no loc], unloaded
-// CHECK:STDOUT:   %Main.import_ref.ce5 = import_ref Main//a, loc5_9, unloaded
+// CHECK:STDOUT:   %Main.import_ref.550 = import_ref Main//a, loc5_9, unloaded
 // CHECK:STDOUT:   %Main.F: @AddWith.%F.type (%F.type.fbc) = import_ref Main//a, F, loaded [symbolic = @AddWith.%F (constants.%F.be3)]
 // CHECK:STDOUT:   %Main.import_ref.0c5 = import_ref Main//a, loc5_9, unloaded
 // CHECK:STDOUT: }
@@ -153,13 +152,13 @@ impl C as AddWith(C) {
 // CHECK:STDOUT:   %Self: %AddWith.type.bc7 = 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.fbc)]
 // CHECK:STDOUT:   %F: @AddWith.%F.type (%F.type.fbc) = struct_value () [symbolic = %F (constants.%F.be3)]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type @AddWith.%AddWith.type (%AddWith.type.bc7), @AddWith.%F.type (%F.type.fbc) [symbolic = %F.assoc_type (constants.%F.assoc_type.f26)]
-// CHECK:STDOUT:   %assoc0: @AddWith.%F.assoc_type (%F.assoc_type.f26) = assoc_entity element0, imports.%Main.import_ref.0c5 [symbolic = %assoc0 (constants.%assoc0.1ff)]
+// CHECK:STDOUT:   %AddWith.assoc_type: type = assoc_entity_type @AddWith.%AddWith.type (%AddWith.type.bc7) [symbolic = %AddWith.assoc_type (constants.%AddWith.assoc_type.73f)]
+// CHECK:STDOUT:   %assoc0: @AddWith.%AddWith.assoc_type (%AddWith.assoc_type.73f) = assoc_entity element0, imports.%Main.import_ref.0c5 [symbolic = %assoc0 (constants.%assoc0.80d)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = imports.%Main.import_ref.476
-// CHECK:STDOUT:     .F = imports.%Main.import_ref.ce5
+// CHECK:STDOUT:     .F = imports.%Main.import_ref.550
 // CHECK:STDOUT:     witness = (imports.%Main.F)
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -181,7 +180,6 @@ impl C as AddWith(C) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.1(constants.%T: type, constants.%Self: %AddWith.type.bc7) [from "a.carbon"] {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -208,8 +206,8 @@ impl C as AddWith(C) {
 // CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT:   %F.type => constants.%F.type.cd2
 // CHECK:STDOUT:   %F => constants.%F.b58
-// CHECK:STDOUT:   %F.assoc_type => constants.%F.assoc_type.c97
-// CHECK:STDOUT:   %assoc0 => constants.%assoc0.dc2
+// CHECK:STDOUT:   %AddWith.assoc_type => constants.%AddWith.assoc_type.ace
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.a9f
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F.1(constants.%C, constants.%AddWith.facet) {}

+ 55 - 65
toolchain/check/testdata/interface/no_prelude/import.carbon

@@ -55,20 +55,18 @@ var f: ForwardDeclared* = &f_ref.f;
 // CHECK:STDOUT:   %Self.193: %Empty.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %Basic.type: type = facet_type <@Basic> [template]
 // CHECK:STDOUT:   %Self.1c7: %Basic.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type.6af: type = assoc_entity_type %Basic.type, type [template]
-// CHECK:STDOUT:   %assoc0.d6f: %assoc_type.6af = assoc_entity element0, @Basic.%T [template]
+// CHECK:STDOUT:   %Basic.assoc_type: type = assoc_entity_type %Basic.type [template]
+// CHECK:STDOUT:   %assoc0.017: %Basic.assoc_type = assoc_entity element0, @Basic.%T [template]
 // CHECK:STDOUT:   %F.type.320: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.952: %F.type.320 = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type.94b: type = assoc_entity_type %Basic.type, %F.type.320 [template]
-// CHECK:STDOUT:   %assoc1.07d: %F.assoc_type.94b = assoc_entity element1, @Basic.%F.decl [template]
+// CHECK:STDOUT:   %assoc1.9c9: %Basic.assoc_type = assoc_entity element1, @Basic.%F.decl [template]
 // CHECK:STDOUT:   %ForwardDeclared.type: type = facet_type <@ForwardDeclared> [template]
 // CHECK:STDOUT:   %Self.efa: %ForwardDeclared.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type.3e8: type = assoc_entity_type %ForwardDeclared.type, type [template]
-// CHECK:STDOUT:   %assoc0.bef: %assoc_type.3e8 = assoc_entity element0, @ForwardDeclared.%T [template]
+// CHECK:STDOUT:   %ForwardDeclared.assoc_type: type = assoc_entity_type %ForwardDeclared.type [template]
+// CHECK:STDOUT:   %assoc0.ec6: %ForwardDeclared.assoc_type = assoc_entity element0, @ForwardDeclared.%T [template]
 // CHECK:STDOUT:   %F.type.505: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.eb5: %F.type.505 = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type.1e3: type = assoc_entity_type %ForwardDeclared.type, %F.type.505 [template]
-// CHECK:STDOUT:   %assoc1.ce8: %F.assoc_type.1e3 = assoc_entity element1, @ForwardDeclared.%F.decl [template]
+// CHECK:STDOUT:   %assoc1.02a: %ForwardDeclared.assoc_type = assoc_entity element1, @ForwardDeclared.%F.decl [template]
 // CHECK:STDOUT:   %struct_type.f.2f5: type = struct_type {.f: %ForwardDeclared.type} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -104,44 +102,56 @@ var f: ForwardDeclared* = &f_ref.f;
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Basic {
 // CHECK:STDOUT:   %Self: %Basic.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.1c7]
-// CHECK:STDOUT:   %T: type = assoc_const_decl T [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type.6af = assoc_entity element0, %T [template = constants.%assoc0.d6f]
+// CHECK:STDOUT:   %T: type = assoc_const_decl @T.loc8 [template] {
+// CHECK:STDOUT:     %assoc0: %Basic.assoc_type = assoc_entity element0, @Basic.%T [template = constants.%assoc0.017]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type.320 = fn_decl @F.1 [template = constants.%F.952] {} {}
-// CHECK:STDOUT:   %assoc1: %F.assoc_type.94b = assoc_entity element1, %F.decl [template = constants.%assoc1.07d]
+// CHECK:STDOUT:   %assoc1: %Basic.assoc_type = assoc_entity element1, %F.decl [template = constants.%assoc1.9c9]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .T = %assoc0
+// CHECK:STDOUT:   .T = @T.loc8.%assoc0
 // CHECK:STDOUT:   .F = %assoc1
 // CHECK:STDOUT:   witness = (%T, %F.decl)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @ForwardDeclared {
 // CHECK:STDOUT:   %Self: %ForwardDeclared.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.efa]
-// CHECK:STDOUT:   %T: type = assoc_const_decl T [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type.3e8 = assoc_entity element0, %T [template = constants.%assoc0.bef]
+// CHECK:STDOUT:   %T: type = assoc_const_decl @T.loc16 [template] {
+// CHECK:STDOUT:     %assoc0: %ForwardDeclared.assoc_type = assoc_entity element0, @ForwardDeclared.%T [template = constants.%assoc0.ec6]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type.505 = fn_decl @F.2 [template = constants.%F.eb5] {} {}
-// CHECK:STDOUT:   %assoc1: %F.assoc_type.1e3 = assoc_entity element1, %F.decl [template = constants.%assoc1.ce8]
+// CHECK:STDOUT:   %assoc1: %ForwardDeclared.assoc_type = assoc_entity element1, %F.decl [template = constants.%assoc1.02a]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .T = %assoc0
+// CHECK:STDOUT:   .T = @T.loc16.%assoc0
 // CHECK:STDOUT:   .F = %assoc1
 // CHECK:STDOUT:   witness = (%T, %F.decl)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: generic fn @F.1(@Basic.%Self: %Basic.type) {
+// CHECK:STDOUT: generic assoc_const @T.loc8(@Basic.%Self: %Basic.type) {
+// CHECK:STDOUT:   assoc_const T:! type;
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @T.loc16(@ForwardDeclared.%Self: %ForwardDeclared.type) {
+// CHECK:STDOUT:   assoc_const T:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @F.1(@Basic.%Self: %Basic.type) {
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F.2(@ForwardDeclared.%Self: %ForwardDeclared.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @T.loc8(constants.%Self.1c7) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @F.1(constants.%Self.1c7) {}
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @T.loc16(constants.%Self.efa) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @F.2(constants.%Self.efa) {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- b.carbon
@@ -151,23 +161,17 @@ var f: ForwardDeclared* = &f_ref.f;
 // CHECK:STDOUT:   %UseEmpty.type: type = fn_type @UseEmpty [template]
 // CHECK:STDOUT:   %UseEmpty: %UseEmpty.type = struct_value () [template]
 // CHECK:STDOUT:   %Basic.type: type = facet_type <@Basic> [template]
-// CHECK:STDOUT:   %Self.1c7: %Basic.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %UseBasic.type: type = fn_type @UseBasic [template]
 // CHECK:STDOUT:   %UseBasic: %UseBasic.type = struct_value () [template]
 // CHECK:STDOUT:   %ForwardDeclared.type: type = facet_type <@ForwardDeclared> [template]
-// CHECK:STDOUT:   %Self.efa: %ForwardDeclared.type = 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:   %assoc_type.6af: type = assoc_entity_type %Basic.type, type [template]
-// CHECK:STDOUT:   %assoc0.1d6: %assoc_type.6af = assoc_entity element0, imports.%Main.import_ref.ef4597.1 [template]
-// CHECK:STDOUT:   %F.type.320: type = fn_type @F.1 [template]
-// CHECK:STDOUT:   %F.assoc_type.94b: type = assoc_entity_type %Basic.type, %F.type.320 [template]
-// CHECK:STDOUT:   %assoc1.d7b: %F.assoc_type.94b = assoc_entity element1, imports.%Main.import_ref.0be [template]
-// CHECK:STDOUT:   %assoc_type.3e8: type = assoc_entity_type %ForwardDeclared.type, type [template]
-// CHECK:STDOUT:   %assoc0.910: %assoc_type.3e8 = assoc_entity element0, imports.%Main.import_ref.ef4597.2 [template]
-// CHECK:STDOUT:   %F.type.505: type = fn_type @F.2 [template]
-// CHECK:STDOUT:   %F.assoc_type.1e3: type = assoc_entity_type %ForwardDeclared.type, %F.type.505 [template]
-// CHECK:STDOUT:   %assoc1.68e: %F.assoc_type.1e3 = assoc_entity element1, imports.%Main.import_ref.1cc [template]
+// CHECK:STDOUT:   %Basic.assoc_type: type = assoc_entity_type %Basic.type [template]
+// CHECK:STDOUT:   %assoc0.b26: %Basic.assoc_type = assoc_entity element0, imports.%Main.import_ref.a4a [template]
+// CHECK:STDOUT:   %assoc1.0bf: %Basic.assoc_type = assoc_entity element1, imports.%Main.import_ref.0be [template]
+// CHECK:STDOUT:   %ForwardDeclared.assoc_type: type = assoc_entity_type %ForwardDeclared.type [template]
+// CHECK:STDOUT:   %assoc0.c94: %ForwardDeclared.assoc_type = assoc_entity element0, imports.%Main.import_ref.69a [template]
+// CHECK:STDOUT:   %assoc1.660: %ForwardDeclared.assoc_type = assoc_entity element1, imports.%Main.import_ref.1cc [template]
 // CHECK:STDOUT:   %ptr: type = ptr_type %ForwardDeclared.type [template]
 // CHECK:STDOUT:   %struct_type.f.2f5: type = struct_type {.f: %ForwardDeclared.type} [template]
 // CHECK:STDOUT: }
@@ -179,14 +183,14 @@ var f: ForwardDeclared* = &f_ref.f;
 // CHECK:STDOUT:   %Main.f_ref: ref %struct_type.f.2f5 = import_ref Main//a, f_ref, loaded
 // CHECK:STDOUT:   %Main.import_ref.cc0 = import_ref Main//a, inst15 [no loc], unloaded
 // CHECK:STDOUT:   %Main.import_ref.37f = import_ref Main//a, inst19 [no loc], unloaded
-// CHECK:STDOUT:   %Main.import_ref.42e: %assoc_type.6af = import_ref Main//a, loc8_8, loaded [template = constants.%assoc0.1d6]
-// CHECK:STDOUT:   %Main.import_ref.b06: %F.assoc_type.94b = import_ref Main//a, loc9_9, loaded [template = constants.%assoc1.d7b]
-// CHECK:STDOUT:   %Main.T.08d600.1 = import_ref Main//a, T, unloaded
+// CHECK:STDOUT:   %Main.import_ref.152: %Basic.assoc_type = import_ref Main//a, loc8_8, loaded [template = constants.%assoc0.b26]
+// CHECK:STDOUT:   %Main.import_ref.30b: %Basic.assoc_type = import_ref Main//a, loc9_9, loaded [template = constants.%assoc1.0bf]
+// CHECK:STDOUT:   %Main.T.44f = import_ref Main//a, T, unloaded
 // CHECK:STDOUT:   %Main.F.eea = import_ref Main//a, F, unloaded
-// CHECK:STDOUT:   %Main.import_ref.52b = import_ref Main//a, inst34 [no loc], unloaded
-// CHECK:STDOUT:   %Main.import_ref.95f: %assoc_type.3e8 = import_ref Main//a, loc16_8, loaded [template = constants.%assoc0.910]
-// CHECK:STDOUT:   %Main.import_ref.7f1: %F.assoc_type.1e3 = import_ref Main//a, loc17_9, loaded [template = constants.%assoc1.68e]
-// CHECK:STDOUT:   %Main.T.08d600.2 = import_ref Main//a, T, unloaded
+// CHECK:STDOUT:   %Main.import_ref.52b = import_ref Main//a, inst33 [no loc], unloaded
+// CHECK:STDOUT:   %Main.import_ref.de0: %ForwardDeclared.assoc_type = import_ref Main//a, loc16_8, loaded [template = constants.%assoc0.c94]
+// CHECK:STDOUT:   %Main.import_ref.c9c: %ForwardDeclared.assoc_type = import_ref Main//a, loc17_9, loaded [template = constants.%assoc1.660]
+// CHECK:STDOUT:   %Main.T.6ee = import_ref Main//a, T, unloaded
 // CHECK:STDOUT:   %Main.F.5d0 = import_ref Main//a, F, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -231,17 +235,17 @@ var f: ForwardDeclared* = &f_ref.f;
 // CHECK:STDOUT:     %f: %ForwardDeclared.type = bind_name f, %f.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Basic.ref.loc10: type = name_ref Basic, imports.%Main.Basic [template = constants.%Basic.type]
-// CHECK:STDOUT:   %T.ref.loc10: %assoc_type.6af = name_ref T, imports.%Main.import_ref.42e [template = constants.%assoc0.1d6]
-// CHECK:STDOUT:   %UseBasicT: %assoc_type.6af = bind_alias UseBasicT, imports.%Main.import_ref.42e [template = constants.%assoc0.1d6]
+// CHECK:STDOUT:   %T.ref.loc10: %Basic.assoc_type = name_ref T, imports.%Main.import_ref.152 [template = constants.%assoc0.b26]
+// CHECK:STDOUT:   %UseBasicT: %Basic.assoc_type = bind_alias UseBasicT, imports.%Main.import_ref.152 [template = constants.%assoc0.b26]
 // CHECK:STDOUT:   %Basic.ref.loc11: type = name_ref Basic, imports.%Main.Basic [template = constants.%Basic.type]
-// CHECK:STDOUT:   %F.ref.loc11: %F.assoc_type.94b = name_ref F, imports.%Main.import_ref.b06 [template = constants.%assoc1.d7b]
-// CHECK:STDOUT:   %UseBasicF: %F.assoc_type.94b = bind_alias UseBasicF, imports.%Main.import_ref.b06 [template = constants.%assoc1.d7b]
+// CHECK:STDOUT:   %F.ref.loc11: %Basic.assoc_type = name_ref F, imports.%Main.import_ref.30b [template = constants.%assoc1.0bf]
+// CHECK:STDOUT:   %UseBasicF: %Basic.assoc_type = bind_alias UseBasicF, imports.%Main.import_ref.30b [template = constants.%assoc1.0bf]
 // CHECK:STDOUT:   %ForwardDeclared.ref.loc13: type = name_ref ForwardDeclared, imports.%Main.ForwardDeclared [template = constants.%ForwardDeclared.type]
-// CHECK:STDOUT:   %T.ref.loc13: %assoc_type.3e8 = name_ref T, imports.%Main.import_ref.95f [template = constants.%assoc0.910]
-// CHECK:STDOUT:   %UseForwardDeclaredT: %assoc_type.3e8 = bind_alias UseForwardDeclaredT, imports.%Main.import_ref.95f [template = constants.%assoc0.910]
+// CHECK:STDOUT:   %T.ref.loc13: %ForwardDeclared.assoc_type = name_ref T, imports.%Main.import_ref.de0 [template = constants.%assoc0.c94]
+// CHECK:STDOUT:   %UseForwardDeclaredT: %ForwardDeclared.assoc_type = bind_alias UseForwardDeclaredT, imports.%Main.import_ref.de0 [template = constants.%assoc0.c94]
 // CHECK:STDOUT:   %ForwardDeclared.ref.loc14: type = name_ref ForwardDeclared, imports.%Main.ForwardDeclared [template = constants.%ForwardDeclared.type]
-// CHECK:STDOUT:   %F.ref.loc14: %F.assoc_type.1e3 = name_ref F, imports.%Main.import_ref.7f1 [template = constants.%assoc1.68e]
-// CHECK:STDOUT:   %UseForwardDeclaredF: %F.assoc_type.1e3 = bind_alias UseForwardDeclaredF, imports.%Main.import_ref.7f1 [template = constants.%assoc1.68e]
+// CHECK:STDOUT:   %F.ref.loc14: %ForwardDeclared.assoc_type = name_ref F, imports.%Main.import_ref.c9c [template = constants.%assoc1.660]
+// CHECK:STDOUT:   %UseForwardDeclaredF: %ForwardDeclared.assoc_type = bind_alias UseForwardDeclaredF, imports.%Main.import_ref.c9c [template = constants.%assoc1.660]
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %f.patt: %ptr = binding_pattern f
 // CHECK:STDOUT:     %.loc16_1: %ptr = var_pattern %f.patt
@@ -263,17 +267,17 @@ var f: ForwardDeclared* = &f_ref.f;
 // CHECK:STDOUT: interface @Basic [from "a.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = imports.%Main.import_ref.37f
-// CHECK:STDOUT:   .T = imports.%Main.import_ref.42e
-// CHECK:STDOUT:   .F = imports.%Main.import_ref.b06
-// CHECK:STDOUT:   witness = (imports.%Main.T.08d600.1, imports.%Main.F.eea)
+// CHECK:STDOUT:   .T = imports.%Main.import_ref.152
+// CHECK:STDOUT:   .F = imports.%Main.import_ref.30b
+// CHECK:STDOUT:   witness = (imports.%Main.T.44f, imports.%Main.F.eea)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @ForwardDeclared [from "a.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = imports.%Main.import_ref.52b
-// CHECK:STDOUT:   .T = imports.%Main.import_ref.95f
-// CHECK:STDOUT:   .F = imports.%Main.import_ref.7f1
-// CHECK:STDOUT:   witness = (imports.%Main.T.08d600.2, imports.%Main.F.5d0)
+// CHECK:STDOUT:   .T = imports.%Main.import_ref.de0
+// CHECK:STDOUT:   .F = imports.%Main.import_ref.c9c
+// CHECK:STDOUT:   witness = (imports.%Main.T.6ee, imports.%Main.F.5d0)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @UseEmpty(%e.param_patt: %Empty.type) {
@@ -291,16 +295,6 @@ var f: ForwardDeclared* = &f_ref.f;
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: generic fn @F.1(constants.%Self.1c7: %Basic.type) [from "a.carbon"] {
-// CHECK:STDOUT:
-// CHECK:STDOUT:   fn();
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
-// CHECK:STDOUT: generic fn @F.2(constants.%Self.efa: %ForwardDeclared.type) [from "a.carbon"] {
-// CHECK:STDOUT:
-// CHECK:STDOUT:   fn();
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %f_ref.ref: ref %struct_type.f.2f5 = name_ref f_ref, imports.%Main.f_ref
@@ -310,7 +304,3 @@ var f: ForwardDeclared* = &f_ref.f;
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @F.1(constants.%Self.1c7) {}
-// CHECK:STDOUT:
-// CHECK:STDOUT: specific @F.2(constants.%Self.efa) {}
-// CHECK:STDOUT:

+ 4 - 5
toolchain/check/testdata/interface/no_prelude/local.carbon

@@ -28,8 +28,8 @@ fn F() {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %G.type.bff: type = fn_type @G.1 [template]
 // CHECK:STDOUT:   %G.f0a: %G.type.bff = struct_value () [template]
-// CHECK:STDOUT:   %G.assoc_type: type = assoc_entity_type %I.type, %G.type.bff [template]
-// CHECK:STDOUT:   %assoc0: %G.assoc_type = assoc_entity element0, @I.%G.decl [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @I.%G.decl [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (@impl.%G.decl) [template]
 // CHECK:STDOUT:   %G.type.c84: type = fn_type @G.2 [template]
 // CHECK:STDOUT:   %G.5a2: %G.type.c84 = struct_value () [template]
@@ -46,7 +46,7 @@ fn F() {
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %G.decl: %G.type.bff = fn_decl @G.1 [template = constants.%G.f0a] {} {}
-// CHECK:STDOUT:   %assoc0: %G.assoc_type = assoc_entity element0, %G.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, %G.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -73,14 +73,13 @@ fn F() {
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (@impl.%G.decl) [template = constants.%impl_witness]
 // CHECK:STDOUT:   %.loc18: %empty_tuple.type = tuple_literal ()
 // CHECK:STDOUT:   %I.ref: type = name_ref I, %I.decl [template = constants.%I.type]
-// CHECK:STDOUT:   %G.ref: %G.assoc_type = name_ref G, @I.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:   %G.ref: %I.assoc_type = name_ref G, @I.%assoc0 [template = constants.%assoc0]
 // CHECK:STDOUT:   %impl.elem0: %G.type.bff = impl_witness_access constants.%impl_witness, element0 [template = constants.%G.5a2]
 // CHECK:STDOUT:   %G.call: init %empty_tuple.type = call %impl.elem0()
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @G.1(@I.%Self: %I.type) {
-// CHECK:STDOUT:
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

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

@@ -20,8 +20,8 @@ interface UseSelf {
 // CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %UseSelf.type, %F.type [template]
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, @UseSelf.%F.decl [template]
+// CHECK:STDOUT:   %UseSelf.assoc_type: type = assoc_entity_type %UseSelf.type [template]
+// CHECK:STDOUT:   %assoc0: %UseSelf.assoc_type = assoc_entity element0, @UseSelf.%F.decl [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -52,7 +52,7 @@ interface UseSelf {
 // CHECK:STDOUT:     %return.param: ref @F.%Self.as_type.loc12_14.1 (%Self.as_type) = out_param runtime_param1
 // CHECK:STDOUT:     %return: ref @F.%Self.as_type.loc12_14.1 (%Self.as_type) = return_slot %return.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
+// CHECK:STDOUT:   %assoc0: %UseSelf.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self

+ 44 - 29
toolchain/check/testdata/interface/todo_define_not_default.carbon

@@ -26,20 +26,17 @@ interface I {
 // CHECK:STDOUT:   %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %I.type, %F.type [template]
-// CHECK:STDOUT:   %assoc0.fa7: %F.assoc_type = assoc_entity element0, @I.%F.decl [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0.a5e: %I.assoc_type = assoc_entity element0, @I.%F.decl [template]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
-// CHECK:STDOUT:   %G.assoc_type: type = assoc_entity_type %I.type, %G.type [template]
-// CHECK:STDOUT:   %assoc1: %G.assoc_type = assoc_entity element1, @I.%G.decl [template]
-// CHECK:STDOUT:   %assoc_type.579: type = assoc_entity_type %I.type, type [template]
-// CHECK:STDOUT:   %assoc2: %assoc_type.579 = assoc_entity element2, @I.%T [template]
+// CHECK:STDOUT:   %assoc1: %I.assoc_type = assoc_entity element1, @I.%G.decl [template]
+// CHECK:STDOUT:   %assoc2: %I.assoc_type = assoc_entity element2, @I.%T [template]
 // CHECK:STDOUT:   %tuple.type.24b: type = tuple_type (type, type) [template]
 // CHECK:STDOUT:   %tuple.type.d07: type = tuple_type (%i32, %i32) [template]
-// CHECK:STDOUT:   %assoc_type.4fb: type = assoc_entity_type %I.type, %i32 [template]
-// CHECK:STDOUT:   %assoc3: %assoc_type.4fb = assoc_entity element3, @I.%N [template]
+// CHECK:STDOUT:   %assoc3: %I.assoc_type = assoc_entity element3, @I.%N [template]
 // CHECK:STDOUT:   %int_42.20e: Core.IntLiteral = int_value 42 [template]
 // CHECK:STDOUT:   %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [template]
 // CHECK:STDOUT:   %impl_witness.d39: <witness> = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [template]
@@ -71,7 +68,7 @@ interface I {
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826]
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {}
-// CHECK:STDOUT:   %assoc0: %F.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0.fa7]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, %F.decl [template = constants.%assoc0.a5e]
 // CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [template = constants.%G] {
 // CHECK:STDOUT:     %a.patt: %i32 = binding_pattern a
 // CHECK:STDOUT:     %a.param_patt: %i32 = value_param_pattern %a.patt, runtime_param0
@@ -97,34 +94,48 @@ interface I {
 // CHECK:STDOUT:     %return.param: ref %i32 = out_param runtime_param2
 // CHECK:STDOUT:     %return: ref %i32 = return_slot %return.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc1: %G.assoc_type = assoc_entity element1, %G.decl [template = constants.%assoc1]
-// CHECK:STDOUT:   %T: type = assoc_const_decl T [template]
-// CHECK:STDOUT:   %assoc2: %assoc_type.579 = assoc_entity element2, %T [template = constants.%assoc2]
-// CHECK:STDOUT:   %int_32.loc18_19: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:   %i32.loc18_19: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
-// CHECK:STDOUT:   %int_32.loc18_24: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:   %i32.loc18_24: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
-// CHECK:STDOUT:   %.loc18_27: %tuple.type.24b = tuple_literal (%i32.loc18_19, %i32.loc18_24)
-// CHECK:STDOUT:   %.loc18_28: type = converted %.loc18_27, constants.%tuple.type.d07 [template = constants.%tuple.type.d07]
-// CHECK:STDOUT:   %N: %i32 = assoc_const_decl N [template]
-// CHECK:STDOUT:   %assoc3: %assoc_type.4fb = assoc_entity element3, %N [template = constants.%assoc3]
-// CHECK:STDOUT:   %int_42: Core.IntLiteral = int_value 42 [template = constants.%int_42.20e]
-// CHECK:STDOUT:   %impl.elem0: %Convert.type.1b6 = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
-// CHECK:STDOUT:   %Convert.bound: <bound method> = bound_method %int_42, %impl.elem0 [template = constants.%Convert.bound]
-// CHECK:STDOUT:   %Convert.specific_fn: <specific function> = specific_function %Convert.bound, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn]
-// CHECK:STDOUT:   %int.convert_checked: init %i32 = call %Convert.specific_fn(%int_42) [template = constants.%int_42.c68]
-// CHECK:STDOUT:   %.loc19_19.1: %i32 = value_of_initializer %int.convert_checked [template = constants.%int_42.c68]
-// CHECK:STDOUT:   %.loc19_19.2: %i32 = converted %int_42, %.loc19_19.1 [template = constants.%int_42.c68]
+// CHECK:STDOUT:   %assoc1: %I.assoc_type = assoc_entity element1, %G.decl [template = constants.%assoc1]
+// CHECK:STDOUT:   %T: type = assoc_const_decl @T [template] {
+// CHECK:STDOUT:     %assoc2: %I.assoc_type = assoc_entity element2, @I.%T [template = constants.%assoc2]
+// CHECK:STDOUT:     %int_32.loc18_19: Core.IntLiteral = int_value 32 [template = constants.%int_32]
+// CHECK:STDOUT:     %i32.loc18_19: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
+// CHECK:STDOUT:     %int_32.loc18_24: Core.IntLiteral = int_value 32 [template = constants.%int_32]
+// CHECK:STDOUT:     %i32.loc18_24: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
+// CHECK:STDOUT:     %.loc18_27: %tuple.type.24b = tuple_literal (%i32.loc18_19, %i32.loc18_24)
+// CHECK:STDOUT:     %.loc18_28: type = converted %.loc18_27, constants.%tuple.type.d07 [template = constants.%tuple.type.d07]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %N: %i32 = assoc_const_decl @N [template] {
+// CHECK:STDOUT:     %assoc3: %I.assoc_type = assoc_entity element3, @I.%N [template = constants.%assoc3]
+// CHECK:STDOUT:     %int_42: Core.IntLiteral = int_value 42 [template = constants.%int_42.20e]
+// CHECK:STDOUT:     %impl.elem0: %Convert.type.1b6 = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
+// CHECK:STDOUT:     %Convert.bound: <bound method> = bound_method %int_42, %impl.elem0 [template = constants.%Convert.bound]
+// CHECK:STDOUT:     %Convert.specific_fn: <specific function> = specific_function %Convert.bound, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn]
+// CHECK:STDOUT:     %int.convert_checked: init %i32 = call %Convert.specific_fn(%int_42) [template = constants.%int_42.c68]
+// CHECK:STDOUT:     %.loc19_19.1: %i32 = value_of_initializer %int.convert_checked [template = constants.%int_42.c68]
+// CHECK:STDOUT:     %.loc19_19.2: %i32 = converted %int_42, %.loc19_19.1 [template = constants.%int_42.c68]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
 // CHECK:STDOUT:   .F = %assoc0
 // CHECK:STDOUT:   .G = %assoc1
-// CHECK:STDOUT:   .T = %assoc2
-// CHECK:STDOUT:   .N = %assoc3
+// CHECK:STDOUT:   .T = @T.%assoc2
+// CHECK:STDOUT:   .N = @N.%assoc3
 // CHECK:STDOUT:   witness = (%F.decl, %G.decl, %T, %N)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @T(@I.%Self: %I.type) {
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   assoc_const T:! type = %.loc18_28;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @N(@I.%Self: %I.type) {
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   assoc_const N:! %i32 = %.loc19_19.2;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(@I.%Self: %I.type) {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
@@ -144,3 +155,7 @@ interface I {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @G(constants.%Self.826) {}
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @T(constants.%Self.826) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @N(constants.%Self.826) {}
+// CHECK:STDOUT:

+ 21 - 14
toolchain/check/testdata/let/compile_time_bindings.carbon

@@ -107,10 +107,10 @@ library "[[@TEST_NAME]]";
 
 interface I {
   let T:! type = i32;
-  // CHECK:STDERR: fail_return_in_interface.carbon:[[@LINE+7]]:13: error: cannot implicitly convert from `<associated type in I>` to `type` [ImplicitAsConversionFailure]
+  // CHECK:STDERR: fail_return_in_interface.carbon:[[@LINE+7]]:13: error: cannot implicitly convert from `<associated entity in I>` to `type` [ImplicitAsConversionFailure]
   // CHECK:STDERR:   fn F() -> T;
   // CHECK:STDERR:             ^
-  // CHECK:STDERR: fail_return_in_interface.carbon:[[@LINE+4]]:13: note: type `<associated type in I>` does not implement interface `Core.ImplicitAs(type)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR: fail_return_in_interface.carbon:[[@LINE+4]]:13: note: type `<associated entity in I>` does not implement interface `Core.ImplicitAs(type)` [MissingImplInMemberAccessNote]
   // CHECK:STDERR:   fn F() -> T;
   // CHECK:STDERR:             ^
   // CHECK:STDERR:
@@ -739,14 +739,13 @@ impl i32 as Empty {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %I.type: type = facet_type <@I> [template]
 // CHECK:STDOUT:   %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %I.type, type [template]
-// CHECK:STDOUT:   %assoc0.790: %assoc_type = assoc_entity element0, @I.%T [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0.c7e: %I.assoc_type = assoc_entity element0, @I.%T [template]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %F.assoc_type: type = assoc_entity_type %I.type, %F.type [template]
-// CHECK:STDOUT:   %assoc1: %F.assoc_type = assoc_entity element1, @I.%F.decl [template]
+// CHECK:STDOUT:   %assoc1: %I.assoc_type = assoc_entity element1, @I.%F.decl [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -769,33 +768,41 @@ impl i32 as Empty {
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826]
-// CHECK:STDOUT:   %T: type = assoc_const_decl T [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %T [template = constants.%assoc0.790]
-// CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:   %i32: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
+// CHECK:STDOUT:   %T: type = assoc_const_decl @T [template] {
+// CHECK:STDOUT:     %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [template = constants.%assoc0.c7e]
+// CHECK:STDOUT:     %int_32: Core.IntLiteral = int_value 32 [template = constants.%int_32]
+// CHECK:STDOUT:     %i32: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
 // CHECK:STDOUT:     %return.patt: <error> = return_slot_pattern
 // CHECK:STDOUT:     %return.param_patt: <error> = out_param_pattern %return.patt, runtime_param0
 // CHECK:STDOUT:   } {
-// CHECK:STDOUT:     %T.ref: %assoc_type = name_ref T, @I.%assoc0 [template = constants.%assoc0.790]
+// CHECK:STDOUT:     %T.ref: %I.assoc_type = name_ref T, @T.%assoc0 [template = constants.%assoc0.c7e]
 // CHECK:STDOUT:     %.loc13: type = converted %T.ref, <error> [template = <error>]
 // CHECK:STDOUT:     %return.param: ref <error> = out_param runtime_param0
 // CHECK:STDOUT:     %return: ref <error> = return_slot %return.param
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %assoc1: %F.assoc_type = assoc_entity element1, %F.decl [template = constants.%assoc1]
+// CHECK:STDOUT:   %assoc1: %I.assoc_type = assoc_entity element1, %F.decl [template = constants.%assoc1]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .T = %assoc0
+// CHECK:STDOUT:   .T = @T.%assoc0
 // CHECK:STDOUT:   .F = %assoc1
 // CHECK:STDOUT:   witness = (%T, %F.decl)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: generic fn @F(@I.%Self: %I.type) {
+// CHECK:STDOUT: generic assoc_const @T(@I.%Self: %I.type) {
+// CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
+// CHECK:STDOUT:   assoc_const T:! type = %i32;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @F(@I.%Self: %I.type) {
 // CHECK:STDOUT:   fn() -> <error>;
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @T(constants.%Self.826) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%Self.826) {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_return_in_class.carbon

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

@@ -27,8 +27,8 @@ fn Main() -> i32 {
 // CHECK:STDOUT:   %Main: %Main.type = struct_value () [template]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %float: f64 = float_literal 3.4000000000000004 [template]
-// CHECK:STDOUT:   %Op.type: type = fn_type @Op [template]
 // CHECK:STDOUT:   %int_12: Core.IntLiteral = int_value 12 [template]
+// CHECK:STDOUT:   %Op.type: type = fn_type @Op [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {

+ 9 - 9
toolchain/check/testdata/operators/overloaded/no_prelude/index.carbon

@@ -126,13 +126,13 @@ fn F() { ()[()]; }
 // CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic]
 // CHECK:STDOUT:   %At.type.b28: type = fn_type @At.1, @IndexWith(%SubscriptType) [symbolic]
 // CHECK:STDOUT:   %At.921: %At.type.b28 = struct_value () [symbolic]
-// CHECK:STDOUT:   %At.assoc_type.315: type = assoc_entity_type %IndexWith.type.518, %At.type.b28 [symbolic]
-// CHECK:STDOUT:   %assoc0.d83: %At.assoc_type.315 = assoc_entity element0, @IndexWith.%At.decl [symbolic]
+// CHECK:STDOUT:   %IndexWith.assoc_type.c82: type = assoc_entity_type %IndexWith.type.518 [symbolic]
+// CHECK:STDOUT:   %assoc0.d63: %IndexWith.assoc_type.c82 = assoc_entity element0, @IndexWith.%At.decl [symbolic]
 // CHECK:STDOUT:   %IndexWith.type.4ab: type = facet_type <@IndexWith, @IndexWith(%empty_tuple.type)> [template]
 // CHECK:STDOUT:   %At.type.082: type = fn_type @At.1, @IndexWith(%empty_tuple.type) [template]
 // CHECK:STDOUT:   %At.d80: %At.type.082 = struct_value () [template]
-// CHECK:STDOUT:   %At.assoc_type.61a: type = assoc_entity_type %IndexWith.type.4ab, %At.type.082 [template]
-// CHECK:STDOUT:   %assoc0.ca3: %At.assoc_type.61a = assoc_entity element0, @IndexWith.%At.decl [template]
+// CHECK:STDOUT:   %IndexWith.assoc_type.81e: type = assoc_entity_type %IndexWith.type.4ab [template]
+// CHECK:STDOUT:   %assoc0.5bc: %IndexWith.assoc_type.81e = assoc_entity element0, @IndexWith.%At.decl [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (@impl.%At.decl) [template]
 // CHECK:STDOUT:   %At.type.8fc: type = fn_type @At.2 [template]
 // CHECK:STDOUT:   %At.8ba: %At.type.8fc = struct_value () [template]
@@ -180,8 +180,8 @@ fn F() { ()[()]; }
 // CHECK:STDOUT:   %Self.2: %IndexWith.type.518 = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
 // CHECK:STDOUT:   %At.type: type = fn_type @At.1, @IndexWith(%SubscriptType.loc5_26.2) [symbolic = %At.type (constants.%At.type.b28)]
 // CHECK:STDOUT:   %At: @IndexWith.%At.type (%At.type.b28) = struct_value () [symbolic = %At (constants.%At.921)]
-// CHECK:STDOUT:   %At.assoc_type: type = assoc_entity_type @IndexWith.%IndexWith.type (%IndexWith.type.518), @IndexWith.%At.type (%At.type.b28) [symbolic = %At.assoc_type (constants.%At.assoc_type.315)]
-// CHECK:STDOUT:   %assoc0.loc6_52.2: @IndexWith.%At.assoc_type (%At.assoc_type.315) = assoc_entity element0, %At.decl [symbolic = %assoc0.loc6_52.2 (constants.%assoc0.d83)]
+// CHECK:STDOUT:   %IndexWith.assoc_type: type = assoc_entity_type @IndexWith.%IndexWith.type (%IndexWith.type.518) [symbolic = %IndexWith.assoc_type (constants.%IndexWith.assoc_type.c82)]
+// CHECK:STDOUT:   %assoc0.loc6_52.2: @IndexWith.%IndexWith.assoc_type (%IndexWith.assoc_type.c82) = assoc_entity element0, %At.decl [symbolic = %assoc0.loc6_52.2 (constants.%assoc0.d63)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:     %Self.1: @IndexWith.%IndexWith.type (%IndexWith.type.518) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
@@ -209,7 +209,7 @@ fn F() { ()[()]; }
 // CHECK:STDOUT:       %return.param: ref %empty_tuple.type = out_param runtime_param2
 // CHECK:STDOUT:       %return: ref %empty_tuple.type = return_slot %return.param
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %assoc0.loc6_52.1: @IndexWith.%At.assoc_type (%At.assoc_type.315) = assoc_entity element0, %At.decl [symbolic = %assoc0.loc6_52.2 (constants.%assoc0.d83)]
+// CHECK:STDOUT:     %assoc0.loc6_52.1: @IndexWith.%IndexWith.assoc_type (%IndexWith.assoc_type.c82) = assoc_entity element0, %At.decl [symbolic = %assoc0.loc6_52.2 (constants.%assoc0.d63)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = %Self.1
@@ -303,8 +303,8 @@ fn F() { ()[()]; }
 // CHECK:STDOUT:   %Self.2 => constants.%Self
 // CHECK:STDOUT:   %At.type => constants.%At.type.082
 // CHECK:STDOUT:   %At => constants.%At.d80
-// CHECK:STDOUT:   %At.assoc_type => constants.%At.assoc_type.61a
-// CHECK:STDOUT:   %assoc0.loc6_52.2 => constants.%assoc0.ca3
+// CHECK:STDOUT:   %IndexWith.assoc_type => constants.%IndexWith.assoc_type.81e
+// CHECK:STDOUT:   %assoc0.loc6_52.2 => constants.%assoc0.5bc
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @At.1(constants.%empty_tuple.type, constants.%IndexWith.facet) {

+ 41 - 41
toolchain/check/testdata/return/no_prelude/import_convert_function.carbon

@@ -78,15 +78,15 @@ fn F0(n: i32) -> P.D {
 // CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic]
 // CHECK:STDOUT:   %Convert.type.4cf: type = fn_type @Convert.1, @ImplicitAs(%T) [symbolic]
 // CHECK:STDOUT:   %Convert.147: %Convert.type.4cf = struct_value () [symbolic]
-// CHECK:STDOUT:   %Convert.assoc_type.154: type = assoc_entity_type %ImplicitAs.type.07f, %Convert.type.4cf [symbolic]
-// CHECK:STDOUT:   %assoc0.1f7: %Convert.assoc_type.154 = assoc_entity element0, @ImplicitAs.%Convert.decl [symbolic]
+// CHECK:STDOUT:   %ImplicitAs.assoc_type.94e: type = assoc_entity_type %ImplicitAs.type.07f [symbolic]
+// CHECK:STDOUT:   %assoc0.a50: %ImplicitAs.assoc_type.94e = assoc_entity element0, @ImplicitAs.%Convert.decl [symbolic]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
 // CHECK:STDOUT:   %i32.builtin: type = int_type signed, %int_32 [template]
 // CHECK:STDOUT:   %ImplicitAs.type.11a: type = facet_type <@ImplicitAs, @ImplicitAs(%i32.builtin)> [template]
 // CHECK:STDOUT:   %Convert.type.752: type = fn_type @Convert.1, @ImplicitAs(%i32.builtin) [template]
 // CHECK:STDOUT:   %Convert.fcc: %Convert.type.752 = struct_value () [template]
-// CHECK:STDOUT:   %Convert.assoc_type.93b: type = assoc_entity_type %ImplicitAs.type.11a, %Convert.type.752 [template]
-// CHECK:STDOUT:   %assoc0.8ce: %Convert.assoc_type.93b = assoc_entity element0, @ImplicitAs.%Convert.decl [template]
+// CHECK:STDOUT:   %ImplicitAs.assoc_type.dd3: type = assoc_entity_type %ImplicitAs.type.11a [template]
+// CHECK:STDOUT:   %assoc0.7cc: %ImplicitAs.assoc_type.dd3 = assoc_entity element0, @ImplicitAs.%Convert.decl [template]
 // CHECK:STDOUT:   %impl_witness: <witness> = impl_witness (@impl.%Convert.decl) [template]
 // CHECK:STDOUT:   %Convert.type.c2a: type = fn_type @Convert.2 [template]
 // CHECK:STDOUT:   %Convert.40d: %Convert.type.c2a = struct_value () [template]
@@ -154,8 +154,8 @@ fn F0(n: i32) -> P.D {
 // CHECK:STDOUT:   %Self.2: %ImplicitAs.type.07f = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
 // CHECK:STDOUT:   %Convert.type: type = fn_type @Convert.1, @ImplicitAs(%T.loc8_22.2) [symbolic = %Convert.type (constants.%Convert.type.4cf)]
 // CHECK:STDOUT:   %Convert: @ImplicitAs.%Convert.type (%Convert.type.4cf) = struct_value () [symbolic = %Convert (constants.%Convert.147)]
-// CHECK:STDOUT:   %Convert.assoc_type: type = assoc_entity_type @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.07f), @ImplicitAs.%Convert.type (%Convert.type.4cf) [symbolic = %Convert.assoc_type (constants.%Convert.assoc_type.154)]
-// CHECK:STDOUT:   %assoc0.loc9_32.2: @ImplicitAs.%Convert.assoc_type (%Convert.assoc_type.154) = assoc_entity element0, %Convert.decl [symbolic = %assoc0.loc9_32.2 (constants.%assoc0.1f7)]
+// CHECK:STDOUT:   %ImplicitAs.assoc_type: type = assoc_entity_type @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.07f) [symbolic = %ImplicitAs.assoc_type (constants.%ImplicitAs.assoc_type.94e)]
+// CHECK:STDOUT:   %assoc0.loc9_32.2: @ImplicitAs.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.94e) = assoc_entity element0, %Convert.decl [symbolic = %assoc0.loc9_32.2 (constants.%assoc0.a50)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:     %Self.1: @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.07f) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
@@ -177,7 +177,7 @@ fn F0(n: i32) -> P.D {
 // CHECK:STDOUT:       %return.param: ref @Convert.1.%T (%T) = out_param runtime_param1
 // CHECK:STDOUT:       %return: ref @Convert.1.%T (%T) = return_slot %return.param
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %assoc0.loc9_32.1: @ImplicitAs.%Convert.assoc_type (%Convert.assoc_type.154) = assoc_entity element0, %Convert.decl [symbolic = %assoc0.loc9_32.2 (constants.%assoc0.1f7)]
+// CHECK:STDOUT:     %assoc0.loc9_32.1: @ImplicitAs.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.94e) = assoc_entity element0, %Convert.decl [symbolic = %assoc0.loc9_32.2 (constants.%assoc0.a50)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = %Self.1
@@ -249,8 +249,8 @@ fn F0(n: i32) -> P.D {
 // CHECK:STDOUT:   %Self.2 => constants.%Self
 // CHECK:STDOUT:   %Convert.type => constants.%Convert.type.752
 // CHECK:STDOUT:   %Convert => constants.%Convert.fcc
-// CHECK:STDOUT:   %Convert.assoc_type => constants.%Convert.assoc_type.93b
-// CHECK:STDOUT:   %assoc0.loc9_32.2 => constants.%assoc0.8ce
+// CHECK:STDOUT:   %ImplicitAs.assoc_type => constants.%ImplicitAs.assoc_type.dd3
+// CHECK:STDOUT:   %assoc0.loc9_32.2 => constants.%assoc0.7cc
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @Convert.1(constants.%i32.builtin, constants.%ImplicitAs.facet) {
@@ -291,14 +291,14 @@ fn F0(n: i32) -> P.D {
 // CHECK:STDOUT:   %Convert.type.275: type = fn_type @Convert.1, @ImplicitAs(%T) [symbolic]
 // CHECK:STDOUT:   %Convert.42e: %Convert.type.275 = struct_value () [symbolic]
 // CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic]
-// CHECK:STDOUT:   %Convert.assoc_type.c0e: type = assoc_entity_type %ImplicitAs.type.d62, %Convert.type.275 [symbolic]
-// CHECK:STDOUT:   %assoc0.5048c6.1: %Convert.assoc_type.c0e = assoc_entity element0, imports.%Core.import_ref.207961.1 [symbolic]
+// CHECK:STDOUT:   %ImplicitAs.assoc_type.837: type = assoc_entity_type %ImplicitAs.type.d62 [symbolic]
+// CHECK:STDOUT:   %assoc0.02f: %ImplicitAs.assoc_type.837 = assoc_entity element0, imports.%Core.import_ref.1c7 [symbolic]
 // CHECK:STDOUT:   %ImplicitAs.type.61e: type = facet_type <@ImplicitAs, @ImplicitAs(%i32.builtin)> [template]
 // CHECK:STDOUT:   %Convert.type.059: type = fn_type @Convert.1, @ImplicitAs(%i32.builtin) [template]
 // CHECK:STDOUT:   %Convert.4d7: %Convert.type.059 = struct_value () [template]
-// CHECK:STDOUT:   %Convert.assoc_type.40f: type = assoc_entity_type %ImplicitAs.type.61e, %Convert.type.059 [template]
-// CHECK:STDOUT:   %assoc0.44d: %Convert.assoc_type.40f = assoc_entity element0, imports.%Core.import_ref.207961.1 [template]
-// CHECK:STDOUT:   %assoc0.5048c6.2: %Convert.assoc_type.c0e = assoc_entity element0, imports.%Core.import_ref.207961.2 [symbolic]
+// CHECK:STDOUT:   %ImplicitAs.assoc_type.740: type = assoc_entity_type %ImplicitAs.type.61e [template]
+// CHECK:STDOUT:   %assoc0.a81: %ImplicitAs.assoc_type.740 = assoc_entity element0, imports.%Core.import_ref.1c7 [template]
+// CHECK:STDOUT:   %assoc0.43d: %ImplicitAs.assoc_type.837 = assoc_entity element0, imports.%Core.import_ref.207 [symbolic]
 // CHECK:STDOUT:   %impl_witness.39c7: <witness> = impl_witness (imports.%Core.import_ref.f35) [template]
 // CHECK:STDOUT:   %Convert.type.49f: type = fn_type @Convert.2 [template]
 // CHECK:STDOUT:   %Convert.cb5: %Convert.type.49f = struct_value () [template]
@@ -309,8 +309,8 @@ fn F0(n: i32) -> P.D {
 // CHECK:STDOUT:   %ImplicitAs.type.94e: type = facet_type <@ImplicitAs, @ImplicitAs(%D)> [template]
 // CHECK:STDOUT:   %Convert.type.010: type = fn_type @Convert.1, @ImplicitAs(%D) [template]
 // CHECK:STDOUT:   %Convert.d38: %Convert.type.010 = struct_value () [template]
-// CHECK:STDOUT:   %Convert.assoc_type.514: type = assoc_entity_type %ImplicitAs.type.94e, %Convert.type.010 [template]
-// CHECK:STDOUT:   %assoc0.bce: %Convert.assoc_type.514 = assoc_entity element0, imports.%Core.import_ref.207961.1 [template]
+// CHECK:STDOUT:   %ImplicitAs.assoc_type.06a: type = assoc_entity_type %ImplicitAs.type.94e [template]
+// CHECK:STDOUT:   %assoc0.69d: %ImplicitAs.assoc_type.06a = assoc_entity element0, imports.%Core.import_ref.1c7 [template]
 // CHECK:STDOUT:   %impl_witness.39cb: <witness> = impl_witness (@impl.2.%Convert.decl) [template]
 // CHECK:STDOUT:   %Convert.type.fff: type = fn_type @Convert.3 [template]
 // CHECK:STDOUT:   %Convert.606: %Convert.type.fff = struct_value () [template]
@@ -381,9 +381,9 @@ fn F0(n: i32) -> P.D {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//default, ImplicitAs, loaded [template = constants.%ImplicitAs.generic]
 // CHECK:STDOUT:   %Core.import_ref.ff5 = import_ref Core//default, inst49 [no loc], unloaded
-// CHECK:STDOUT:   %Core.import_ref.589: @ImplicitAs.%Convert.assoc_type (%Convert.assoc_type.c0e) = import_ref Core//default, loc9_32, loaded [symbolic = @ImplicitAs.%assoc0 (constants.%assoc0.5048c6.2)]
+// CHECK:STDOUT:   %Core.import_ref.630: @ImplicitAs.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.837) = import_ref Core//default, loc9_32, loaded [symbolic = @ImplicitAs.%assoc0 (constants.%assoc0.43d)]
 // CHECK:STDOUT:   %Core.Convert: @ImplicitAs.%Convert.type (%Convert.type.275) = import_ref Core//default, Convert, loaded [symbolic = @ImplicitAs.%Convert (constants.%Convert.42e)]
-// CHECK:STDOUT:   %Core.import_ref.207961.1 = import_ref Core//default, loc9_32, unloaded
+// CHECK:STDOUT:   %Core.import_ref.1c7: @ImplicitAs.%Convert.type (%Convert.type.275) = import_ref Core//default, loc9_32, loaded [symbolic = @ImplicitAs.%Convert (constants.%Convert.42e)]
 // CHECK:STDOUT:   %Core.import_ref.de9: <witness> = import_ref Core//default, loc12_38, loaded [template = constants.%impl_witness.39c7]
 // CHECK:STDOUT:   %Core.import_ref.872: type = import_ref Core//default, loc12_17, loaded [template = Core.IntLiteral]
 // CHECK:STDOUT:   %Core.import_ref.4d9: type = import_ref Core//default, loc12_36, loaded [template = constants.%ImplicitAs.type.61e]
@@ -550,13 +550,13 @@ fn F0(n: i32) -> P.D {
 // CHECK:STDOUT:   %Self: %ImplicitAs.type.d62 = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self)]
 // CHECK:STDOUT:   %Convert.type: type = fn_type @Convert.1, @ImplicitAs(%T) [symbolic = %Convert.type (constants.%Convert.type.275)]
 // CHECK:STDOUT:   %Convert: @ImplicitAs.%Convert.type (%Convert.type.275) = struct_value () [symbolic = %Convert (constants.%Convert.42e)]
-// CHECK:STDOUT:   %Convert.assoc_type: type = assoc_entity_type @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.d62), @ImplicitAs.%Convert.type (%Convert.type.275) [symbolic = %Convert.assoc_type (constants.%Convert.assoc_type.c0e)]
-// CHECK:STDOUT:   %assoc0: @ImplicitAs.%Convert.assoc_type (%Convert.assoc_type.c0e) = assoc_entity element0, imports.%Core.import_ref.207961.1 [symbolic = %assoc0 (constants.%assoc0.5048c6.1)]
+// CHECK:STDOUT:   %ImplicitAs.assoc_type: type = assoc_entity_type @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.d62) [symbolic = %ImplicitAs.assoc_type (constants.%ImplicitAs.assoc_type.837)]
+// CHECK:STDOUT:   %assoc0: @ImplicitAs.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.837) = assoc_entity element0, imports.%Core.import_ref.1c7 [symbolic = %assoc0 (constants.%assoc0.02f)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = imports.%Core.import_ref.ff5
-// CHECK:STDOUT:     .Convert = imports.%Core.import_ref.589
+// CHECK:STDOUT:     .Convert = imports.%Core.import_ref.630
 // CHECK:STDOUT:     witness = (imports.%Core.Convert)
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -890,8 +890,8 @@ fn F0(n: i32) -> P.D {
 // CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT:   %Convert.type => constants.%Convert.type.059
 // CHECK:STDOUT:   %Convert => constants.%Convert.4d7
-// CHECK:STDOUT:   %Convert.assoc_type => constants.%Convert.assoc_type.40f
-// CHECK:STDOUT:   %assoc0 => constants.%assoc0.44d
+// CHECK:STDOUT:   %ImplicitAs.assoc_type => constants.%ImplicitAs.assoc_type.740
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.a81
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @C(constants.%int_0.a54) {
@@ -910,8 +910,8 @@ fn F0(n: i32) -> P.D {
 // CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT:   %Convert.type => constants.%Convert.type.010
 // CHECK:STDOUT:   %Convert => constants.%Convert.d38
-// CHECK:STDOUT:   %Convert.assoc_type => constants.%Convert.assoc_type.514
-// CHECK:STDOUT:   %assoc0 => constants.%assoc0.bce
+// CHECK:STDOUT:   %ImplicitAs.assoc_type => constants.%ImplicitAs.assoc_type.06a
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.69d
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @Convert.1(constants.%D, constants.%ImplicitAs.facet.3d3) {
@@ -1046,14 +1046,14 @@ fn F0(n: i32) -> P.D {
 // CHECK:STDOUT:   %Convert.type.275: type = fn_type @Convert.1, @ImplicitAs(%T) [symbolic]
 // CHECK:STDOUT:   %Convert.42e: %Convert.type.275 = struct_value () [symbolic]
 // CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic]
-// CHECK:STDOUT:   %Convert.assoc_type.c0e: type = assoc_entity_type %ImplicitAs.type.d62, %Convert.type.275 [symbolic]
-// CHECK:STDOUT:   %assoc0.5048c6.1: %Convert.assoc_type.c0e = assoc_entity element0, imports.%Core.import_ref.207961.1 [symbolic]
+// CHECK:STDOUT:   %ImplicitAs.assoc_type.837: type = assoc_entity_type %ImplicitAs.type.d62 [symbolic]
+// CHECK:STDOUT:   %assoc0.02f: %ImplicitAs.assoc_type.837 = assoc_entity element0, imports.%Core.import_ref.1c7 [symbolic]
 // CHECK:STDOUT:   %ImplicitAs.type.61e: type = facet_type <@ImplicitAs, @ImplicitAs(%i32.builtin)> [template]
 // CHECK:STDOUT:   %Convert.type.059: type = fn_type @Convert.1, @ImplicitAs(%i32.builtin) [template]
 // CHECK:STDOUT:   %Convert.4d7: %Convert.type.059 = struct_value () [template]
-// CHECK:STDOUT:   %Convert.assoc_type.40f: type = assoc_entity_type %ImplicitAs.type.61e, %Convert.type.059 [template]
-// CHECK:STDOUT:   %assoc0.44d: %Convert.assoc_type.40f = assoc_entity element0, imports.%Core.import_ref.207961.1 [template]
-// CHECK:STDOUT:   %assoc0.5048c6.2: %Convert.assoc_type.c0e = assoc_entity element0, imports.%Core.import_ref.207961.2 [symbolic]
+// CHECK:STDOUT:   %ImplicitAs.assoc_type.740: type = assoc_entity_type %ImplicitAs.type.61e [template]
+// CHECK:STDOUT:   %assoc0.a81: %ImplicitAs.assoc_type.740 = assoc_entity element0, imports.%Core.import_ref.1c7 [template]
+// CHECK:STDOUT:   %assoc0.43d: %ImplicitAs.assoc_type.837 = assoc_entity element0, imports.%Core.import_ref.207 [symbolic]
 // CHECK:STDOUT:   %impl_witness.39c: <witness> = impl_witness (imports.%Core.import_ref.f35) [template]
 // CHECK:STDOUT:   %Convert.type.49f: type = fn_type @Convert.2 [template]
 // CHECK:STDOUT:   %Convert.cb5: %Convert.type.49f = struct_value () [template]
@@ -1064,8 +1064,8 @@ fn F0(n: i32) -> P.D {
 // CHECK:STDOUT:   %ImplicitAs.type.5f9: type = facet_type <@ImplicitAs, @ImplicitAs(%D)> [template]
 // CHECK:STDOUT:   %Convert.type.334: type = fn_type @Convert.1, @ImplicitAs(%D) [template]
 // CHECK:STDOUT:   %Convert.87c: %Convert.type.334 = struct_value () [template]
-// CHECK:STDOUT:   %Convert.assoc_type.f99: type = assoc_entity_type %ImplicitAs.type.5f9, %Convert.type.334 [template]
-// CHECK:STDOUT:   %assoc0.4b2: %Convert.assoc_type.f99 = assoc_entity element0, imports.%Core.import_ref.207961.1 [template]
+// CHECK:STDOUT:   %ImplicitAs.assoc_type.8ec: type = assoc_entity_type %ImplicitAs.type.5f9 [template]
+// CHECK:STDOUT:   %assoc0.7a7: %ImplicitAs.assoc_type.8ec = assoc_entity element0, imports.%Core.import_ref.1c7 [template]
 // CHECK:STDOUT:   %int_1.f38: %i32.builtin = int_value 1 [template]
 // CHECK:STDOUT:   %C.012: type = class_type @C, @C(%int_1.f38) [template]
 // CHECK:STDOUT:   %int_2.5a1: %i32.builtin = int_value 2 [template]
@@ -1150,9 +1150,9 @@ fn F0(n: i32) -> P.D {
 // CHECK:STDOUT:   %P.import_ref.8f2: <witness> = import_ref P//library, loc6_19, loaded [template = constants.%complete_type.357]
 // CHECK:STDOUT:   %P.import_ref.d9b = import_ref P//library, inst42 [no loc], unloaded
 // CHECK:STDOUT:   %Core.import_ref.ff5 = import_ref Core//default, inst49 [no loc], unloaded
-// CHECK:STDOUT:   %Core.import_ref.589: @ImplicitAs.%Convert.assoc_type (%Convert.assoc_type.c0e) = import_ref Core//default, loc9_32, loaded [symbolic = @ImplicitAs.%assoc0 (constants.%assoc0.5048c6.2)]
+// CHECK:STDOUT:   %Core.import_ref.630: @ImplicitAs.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.837) = import_ref Core//default, loc9_32, loaded [symbolic = @ImplicitAs.%assoc0 (constants.%assoc0.43d)]
 // CHECK:STDOUT:   %Core.Convert = import_ref Core//default, Convert, unloaded
-// CHECK:STDOUT:   %Core.import_ref.207961.1 = import_ref Core//default, loc9_32, unloaded
+// CHECK:STDOUT:   %Core.import_ref.1c7: @ImplicitAs.%Convert.type (%Convert.type.275) = import_ref Core//default, loc9_32, loaded [symbolic = @ImplicitAs.%Convert (constants.%Convert.42e)]
 // CHECK:STDOUT:   %Core.import_ref.de9: <witness> = import_ref Core//default, loc12_38, loaded [template = constants.%impl_witness.39c]
 // CHECK:STDOUT:   %Core.import_ref.872: type = import_ref Core//default, loc12_17, loaded [template = Core.IntLiteral]
 // CHECK:STDOUT:   %Core.import_ref.4d9: type = import_ref Core//default, loc12_36, loaded [template = constants.%ImplicitAs.type.61e]
@@ -1221,13 +1221,13 @@ fn F0(n: i32) -> P.D {
 // CHECK:STDOUT:   %Self: %ImplicitAs.type.d62 = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self)]
 // CHECK:STDOUT:   %Convert.type: type = fn_type @Convert.1, @ImplicitAs(%T) [symbolic = %Convert.type (constants.%Convert.type.275)]
 // CHECK:STDOUT:   %Convert: @ImplicitAs.%Convert.type (%Convert.type.275) = struct_value () [symbolic = %Convert (constants.%Convert.42e)]
-// CHECK:STDOUT:   %Convert.assoc_type: type = assoc_entity_type @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.d62), @ImplicitAs.%Convert.type (%Convert.type.275) [symbolic = %Convert.assoc_type (constants.%Convert.assoc_type.c0e)]
-// CHECK:STDOUT:   %assoc0: @ImplicitAs.%Convert.assoc_type (%Convert.assoc_type.c0e) = assoc_entity element0, imports.%Core.import_ref.207961.1 [symbolic = %assoc0 (constants.%assoc0.5048c6.1)]
+// CHECK:STDOUT:   %ImplicitAs.assoc_type: type = assoc_entity_type @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.d62) [symbolic = %ImplicitAs.assoc_type (constants.%ImplicitAs.assoc_type.837)]
+// CHECK:STDOUT:   %assoc0: @ImplicitAs.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.837) = assoc_entity element0, imports.%Core.import_ref.1c7 [symbolic = %assoc0 (constants.%assoc0.02f)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = imports.%Core.import_ref.ff5
-// CHECK:STDOUT:     .Convert = imports.%Core.import_ref.589
+// CHECK:STDOUT:     .Convert = imports.%Core.import_ref.630
 // CHECK:STDOUT:     witness = (imports.%Core.Convert)
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -1586,8 +1586,8 @@ fn F0(n: i32) -> P.D {
 // CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT:   %Convert.type => constants.%Convert.type.059
 // CHECK:STDOUT:   %Convert => constants.%Convert.4d7
-// CHECK:STDOUT:   %Convert.assoc_type => constants.%Convert.assoc_type.40f
-// CHECK:STDOUT:   %assoc0 => constants.%assoc0.44d
+// CHECK:STDOUT:   %ImplicitAs.assoc_type => constants.%ImplicitAs.assoc_type.740
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.a81
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @C(constants.%int_0.a54) {
@@ -1606,8 +1606,8 @@ fn F0(n: i32) -> P.D {
 // CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT:   %Convert.type => constants.%Convert.type.334
 // CHECK:STDOUT:   %Convert => constants.%Convert.87c
-// CHECK:STDOUT:   %Convert.assoc_type => constants.%Convert.assoc_type.f99
-// CHECK:STDOUT:   %assoc0 => constants.%assoc0.4b2
+// CHECK:STDOUT:   %ImplicitAs.assoc_type => constants.%ImplicitAs.assoc_type.8ec
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.7a7
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @C(constants.%int_1.f38) {

+ 1 - 1
toolchain/check/testdata/tuple/access/fail_negative_indexing.carbon

@@ -37,8 +37,8 @@ var b: i32 = a.(-10);
 // CHECK:STDOUT:   %int_6.e56: %i32 = int_value 6 [template]
 // CHECK:STDOUT:   %tuple: %tuple.type.d07 = tuple_value (%int_12.1e1, %int_6.e56) [template]
 // CHECK:STDOUT:   %int_10: Core.IntLiteral = int_value 10 [template]
-// CHECK:STDOUT:   %Op.type.e42: type = fn_type @Op.13 [template]
 // CHECK:STDOUT:   %impl_witness.0f6: <witness> = impl_witness (imports.%Core.import_ref.c15) [template]
+// CHECK:STDOUT:   %Op.type.e42: type = fn_type @Op.13 [template]
 // CHECK:STDOUT:   %Op.type.1be: type = fn_type @Op.14 [template]
 // CHECK:STDOUT:   %Op.bba: %Op.type.1be = struct_value () [template]
 // CHECK:STDOUT:   %Op.bound: <bound method> = bound_method %int_10, %Op.bba [template]

+ 52 - 21
toolchain/check/testdata/where_expr/constraints.carbon

@@ -124,11 +124,10 @@ fn NotEmptyStruct() {
 // CHECK:STDOUT:   %Self.ccd: %J.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %I.type: type = facet_type <@I> [template]
 // CHECK:STDOUT:   %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type.579: type = assoc_entity_type %I.type, type [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type.579 = assoc_entity element0, @I.%Member [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @I.%Member [template]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
-// CHECK:STDOUT:   %assoc_type.4dd: type = assoc_entity_type %I.type, %J.type [template]
-// CHECK:STDOUT:   %assoc1: %assoc_type.4dd = assoc_entity element1, @I.%Second [template]
+// CHECK:STDOUT:   %assoc1: %I.assoc_type = assoc_entity element1, @I.%Second [template]
 // CHECK:STDOUT:   %.Self.258: %I.type = bind_symbolic_name .Self [symbolic]
 // CHECK:STDOUT:   %I_where.type: type = facet_type <@I where TODO> [template]
 // CHECK:STDOUT:   %U: %I_where.type = bind_symbolic_name U, 0 [symbolic]
@@ -144,6 +143,7 @@ fn NotEmptyStruct() {
 // CHECK:STDOUT:   %Impls: %Impls.type = struct_value () [template]
 // CHECK:STDOUT:   %.Self.as_type.541: type = facet_access_type %.Self.258 [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self.258 [symbolic]
+// CHECK:STDOUT:   %I.facet: %I.type = facet_value %.Self.as_type.541, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT:   %W: %I_where.type = bind_symbolic_name W, 0 [symbolic]
 // CHECK:STDOUT:   %W.patt: %I_where.type = symbolic_binding_pattern W, 0 [symbolic]
@@ -214,10 +214,12 @@ fn NotEmptyStruct() {
 // CHECK:STDOUT:       %.Self: %I.type = bind_symbolic_name .Self [symbolic = constants.%.Self.258]
 // CHECK:STDOUT:       %.Self.ref.loc15_20: %I.type = name_ref .Self, %.Self [symbolic = constants.%.Self.258]
 // CHECK:STDOUT:       %J.ref: type = name_ref J, file.%J.decl [template = constants.%J.type]
-// CHECK:STDOUT:       %.Self.as_type: type = facet_access_type %.Self.ref.loc15_20 [symbolic = constants.%.Self.as_type.541]
-// CHECK:STDOUT:       %.loc15_20: type = converted %.Self.ref.loc15_20, %.Self.as_type [symbolic = constants.%.Self.as_type.541]
+// CHECK:STDOUT:       %.Self.as_type.loc15_20: type = facet_access_type %.Self.ref.loc15_20 [symbolic = constants.%.Self.as_type.541]
+// CHECK:STDOUT:       %.loc15_20: type = converted %.Self.ref.loc15_20, %.Self.as_type.loc15_20 [symbolic = constants.%.Self.as_type.541]
 // CHECK:STDOUT:       %.Self.ref.loc15_38: %I.type = name_ref .Self, %.Self [symbolic = constants.%.Self.258]
-// CHECK:STDOUT:       %Member.ref: %assoc_type.579 = name_ref Member, @I.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %Member.ref: %I.assoc_type = name_ref Member, @Member.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %.Self.as_type.loc15_38: type = facet_access_type %.Self.ref.loc15_38 [symbolic = constants.%.Self.as_type.541]
+// CHECK:STDOUT:       %.loc15_38: type = converted %.Self.ref.loc15_38, %.Self.as_type.loc15_38 [symbolic = constants.%.Self.as_type.541]
 // CHECK:STDOUT:       %.Self.as_wit: <witness> = facet_access_witness %.Self.ref.loc15_38 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:       %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:       %.loc15_50: %empty_tuple.type = tuple_literal ()
@@ -240,18 +242,28 @@ fn NotEmptyStruct() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826]
-// CHECK:STDOUT:   %Member: type = assoc_const_decl Member [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type.579 = assoc_entity element0, %Member [template = constants.%assoc0]
-// CHECK:STDOUT:   %Second: %J.type = assoc_const_decl Second [template]
-// CHECK:STDOUT:   %assoc1: %assoc_type.4dd = assoc_entity element1, %Second [template = constants.%assoc1]
+// CHECK:STDOUT:   %Member: type = assoc_const_decl @Member [template] {
+// CHECK:STDOUT:     %assoc0: %I.assoc_type = assoc_entity element0, @I.%Member [template = constants.%assoc0]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Second: %J.type = assoc_const_decl @Second [template] {
+// CHECK:STDOUT:     %assoc1: %I.assoc_type = assoc_entity element1, @I.%Second [template = constants.%assoc1]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .Member = %assoc0
-// CHECK:STDOUT:   .Second = %assoc1
+// CHECK:STDOUT:   .Member = @Member.%assoc0
+// CHECK:STDOUT:   .Second = @Second.%assoc1
 // CHECK:STDOUT:   witness = (%Member, %Second)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @Member(@I.%Self: %I.type) {
+// CHECK:STDOUT:   assoc_const Member:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @Second(@I.%Self: %I.type) {
+// CHECK:STDOUT:   assoc_const Second:! %J.type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @EqualEqual(%U.loc11_15.1: %I_where.type) {
 // CHECK:STDOUT:   %U.loc11_15.2: %I_where.type = bind_symbolic_name U, 0 [symbolic = %U.loc11_15.2 (constants.%U)]
 // CHECK:STDOUT:   %U.patt.loc11_15.2: %I_where.type = symbolic_binding_pattern U, 0 [symbolic = %U.patt.loc11_15.2 (constants.%U.patt)]
@@ -273,6 +285,10 @@ fn NotEmptyStruct() {
 // CHECK:STDOUT:   fn(%W.param_patt: %I_where.type);
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @Member(constants.%Self.826) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Second(constants.%Self.826) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @EqualEqual(constants.%U) {
 // CHECK:STDOUT:   %U.loc11_15.2 => constants.%U
 // CHECK:STDOUT:   %U.patt.loc11_15.2 => constants.%U
@@ -283,6 +299,8 @@ fn NotEmptyStruct() {
 // CHECK:STDOUT:   %V.patt.loc13_10.2 => constants.%V
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @Member(constants.%I.facet) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @And(constants.%W) {
 // CHECK:STDOUT:   %W.loc15_8.2 => constants.%W
 // CHECK:STDOUT:   %W.patt.loc15_8.2 => constants.%W
@@ -297,10 +315,12 @@ fn NotEmptyStruct() {
 // CHECK:STDOUT:   %Self.bcc: %M.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %K.type: type = facet_type <@K> [template]
 // CHECK:STDOUT:   %Self.09f: %K.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %K.type, %L.type [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, @K.%Associated [template]
+// CHECK:STDOUT:   %K.assoc_type: type = assoc_entity_type %K.type [template]
+// CHECK:STDOUT:   %assoc0: %K.assoc_type = assoc_entity element0, @K.%Associated [template]
 // CHECK:STDOUT:   %.Self: %K.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %K.facet: %K.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: %L.type = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT:   %as_type: type = facet_access_type %impl.elem0 [symbolic]
 // CHECK:STDOUT:   %K_where.type: type = facet_type <@K where TODO> [template]
@@ -338,14 +358,16 @@ fn NotEmptyStruct() {
 // CHECK:STDOUT:       %K.ref: type = name_ref K, file.%K.decl [template = constants.%K.type]
 // CHECK:STDOUT:       %.Self: %K.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:       %.Self.ref: %K.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:       %Associated.ref: %assoc_type = name_ref Associated, @K.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %Associated.ref: %K.assoc_type = name_ref Associated, @Associated.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.loc11_36.1: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:       %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:       %impl.elem0: %L.type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:       %M.ref: type = name_ref M, file.%M.decl [template = constants.%M.type]
 // CHECK:STDOUT:       %as_type: type = facet_access_type %impl.elem0 [symbolic = constants.%as_type]
-// CHECK:STDOUT:       %.loc11_36: type = converted %impl.elem0, %as_type [symbolic = constants.%as_type]
+// CHECK:STDOUT:       %.loc11_36.2: type = converted %impl.elem0, %as_type [symbolic = constants.%as_type]
 // CHECK:STDOUT:       %.loc11_30.2: type = where_expr %.Self [template = constants.%K_where.type] {
-// CHECK:STDOUT:         requirement_impls %.loc11_36, %M.ref
+// CHECK:STDOUT:         requirement_impls %.loc11_36.2, %M.ref
 // CHECK:STDOUT:       }
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %W.loc11_24.1: %K_where.type = bind_symbolic_name W, 0, %W.param [symbolic = %W.loc11_24.2 (constants.%W)]
@@ -370,15 +392,20 @@ fn NotEmptyStruct() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @K {
 // CHECK:STDOUT:   %Self: %K.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.09f]
-// CHECK:STDOUT:   %Associated: %L.type = assoc_const_decl Associated [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %Associated [template = constants.%assoc0]
+// CHECK:STDOUT:   %Associated: %L.type = assoc_const_decl @Associated [template] {
+// CHECK:STDOUT:     %assoc0: %K.assoc_type = assoc_entity element0, @K.%Associated [template = constants.%assoc0]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .Associated = %assoc0
+// CHECK:STDOUT:   .Associated = @Associated.%assoc0
 // CHECK:STDOUT:   witness = (%Associated)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @Associated(@K.%Self: %K.type) {
+// CHECK:STDOUT:   assoc_const Associated:! %L.type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @AssociatedTypeImpls(%W.loc11_24.1: %K_where.type) {
 // CHECK:STDOUT:   %W.loc11_24.2: %K_where.type = bind_symbolic_name W, 0 [symbolic = %W.loc11_24.2 (constants.%W)]
 // CHECK:STDOUT:   %W.patt.loc11_24.2: %K_where.type = symbolic_binding_pattern W, 0 [symbolic = %W.patt.loc11_24.2 (constants.%W.patt)]
@@ -386,6 +413,10 @@ fn NotEmptyStruct() {
 // CHECK:STDOUT:   fn(%W.param_patt: %K_where.type);
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @Associated(constants.%Self.09f) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Associated(constants.%K.facet) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @AssociatedTypeImpls(constants.%W) {
 // CHECK:STDOUT:   %W.loc11_24.2 => constants.%W
 // CHECK:STDOUT:   %W.patt.loc11_24.2 => constants.%W

+ 31 - 11
toolchain/check/testdata/where_expr/designator.carbon

@@ -92,8 +92,8 @@ class D {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %I.type: type = facet_type <@I> [template]
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %I.type, type [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, @I.%Member [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @I.%Member [template]
 // CHECK:STDOUT:   %.Self.258: %I.type = bind_symbolic_name .Self [symbolic]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
 // CHECK:STDOUT:   %I_where.type: type = facet_type <@I where TODO> [template]
@@ -101,7 +101,9 @@ class D {
 // CHECK:STDOUT:   %T.patt: %I_where.type = symbolic_binding_pattern T, 0 [symbolic]
 // CHECK:STDOUT:   %PeriodSelf.type: type = fn_type @PeriodSelf [template]
 // CHECK:STDOUT:   %PeriodSelf: %PeriodSelf.type = struct_value () [template]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self.258 [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self.258 [symbolic]
+// CHECK:STDOUT:   %I.facet: %I.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT:   %U: %I_where.type = bind_symbolic_name U, 0 [symbolic]
 // CHECK:STDOUT:   %U.patt: %I_where.type = symbolic_binding_pattern U, 0 [symbolic]
@@ -157,7 +159,9 @@ class D {
 // CHECK:STDOUT:       %I.ref: type = name_ref I, file.%I.decl [template = constants.%I.type]
 // CHECK:STDOUT:       %.Self: %I.type = bind_symbolic_name .Self [symbolic = constants.%.Self.258]
 // CHECK:STDOUT:       %.Self.ref: %I.type = name_ref .Self, %.Self [symbolic = constants.%.Self.258]
-// CHECK:STDOUT:       %Member.ref: %assoc_type = name_ref Member, @I.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %Member.ref: %I.assoc_type = name_ref Member, @Member.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.loc10_29: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:       %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:       %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:       %.loc10_41: %empty_tuple.type = tuple_literal ()
@@ -186,15 +190,20 @@ class D {
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %Member: type = assoc_const_decl Member [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %Member [template = constants.%assoc0]
+// CHECK:STDOUT:   %Member: type = assoc_const_decl @Member [template] {
+// CHECK:STDOUT:     %assoc0: %I.assoc_type = assoc_entity element0, @I.%Member [template = constants.%assoc0]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .Member = %assoc0
+// CHECK:STDOUT:   .Member = @Member.%assoc0
 // CHECK:STDOUT:   witness = (%Member)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @Member(@I.%Self: %I.type) {
+// CHECK:STDOUT:   assoc_const Member:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @PeriodSelf(%T.loc8_15.1: %I_where.type) {
 // CHECK:STDOUT:   %T.loc8_15.2: %I_where.type = bind_symbolic_name T, 0 [symbolic = %T.loc8_15.2 (constants.%T)]
 // CHECK:STDOUT:   %T.patt.loc8_15.2: %I_where.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_15.2 (constants.%T.patt)]
@@ -216,11 +225,15 @@ class D {
 // CHECK:STDOUT:   fn(%V.param_patt: %type_where);
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @Member(constants.%Self) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @PeriodSelf(constants.%T) {
 // CHECK:STDOUT:   %T.loc8_15.2 => constants.%T
 // CHECK:STDOUT:   %T.patt.loc8_15.2 => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @Member(constants.%I.facet) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @PeriodMember(constants.%U) {
 // CHECK:STDOUT:   %U.loc10_17.2 => constants.%U
 // CHECK:STDOUT:   %U.patt.loc10_17.2 => constants.%U
@@ -236,8 +249,8 @@ class D {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %J.type: type = facet_type <@J> [template]
 // CHECK:STDOUT:   %Self: %J.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %J.type, type [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, @J.%Member [template]
+// CHECK:STDOUT:   %J.assoc_type: type = assoc_entity_type %J.type [template]
+// CHECK:STDOUT:   %assoc0: %J.assoc_type = assoc_entity element0, @J.%Member [template]
 // CHECK:STDOUT:   %.Self: %J.type = bind_symbolic_name .Self [symbolic]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %W.patt: <error> = symbolic_binding_pattern W, 0 [symbolic]
@@ -281,21 +294,28 @@ class D {
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @J {
 // CHECK:STDOUT:   %Self: %J.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %Member: type = assoc_const_decl Member [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %Member [template = constants.%assoc0]
+// CHECK:STDOUT:   %Member: type = assoc_const_decl @Member [template] {
+// CHECK:STDOUT:     %assoc0: %J.assoc_type = assoc_entity element0, @J.%Member [template = constants.%assoc0]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .Member = %assoc0
+// CHECK:STDOUT:   .Member = @Member.%assoc0
 // CHECK:STDOUT:   witness = (%Member)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @Member(@J.%Self: %J.type) {
+// CHECK:STDOUT:   assoc_const Member:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @PeriodMismatch(%W: <error>) {
 // CHECK:STDOUT:   %W.patt.loc12_19.2: <error> = symbolic_binding_pattern W, 0 [symbolic = %W.patt.loc12_19.2 (constants.%W.patt)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%W.param_patt: <error>);
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @Member(constants.%Self) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @PeriodMismatch(<error>) {
 // CHECK:STDOUT:   %W.patt.loc12_19.2 => <error>
 // CHECK:STDOUT: }

+ 47 - 25
toolchain/check/testdata/where_expr/dot_self_index.carbon

@@ -31,16 +31,18 @@ fn G(U: Empty(i32) where .A = i32*) {
 // CHECK:STDOUT:   %Empty.generic: %Empty.type.d5a = struct_value () [template]
 // CHECK:STDOUT:   %Empty.type.3e5fde.1: type = facet_type <@Empty, @Empty(%W)> [symbolic]
 // CHECK:STDOUT:   %Self: %Empty.type.3e5fde.1 = bind_symbolic_name Self, 1 [symbolic]
-// CHECK:STDOUT:   %assoc_type.79df66.1: type = assoc_entity_type %Empty.type.3e5fde.1, type [symbolic]
-// CHECK:STDOUT:   %assoc0.b2890e.1: %assoc_type.79df66.1 = assoc_entity element0, @Empty.%A [symbolic]
+// CHECK:STDOUT:   %Empty.assoc_type.54c14f.1: type = assoc_entity_type %Empty.type.3e5fde.1 [symbolic]
+// CHECK:STDOUT:   %assoc0.68f673.1: %Empty.assoc_type.54c14f.1 = assoc_entity element0, @Empty.%A [symbolic]
 // CHECK:STDOUT:   %T: type = bind_symbolic_name T, 0 [symbolic]
 // CHECK:STDOUT:   %T.patt: type = symbolic_binding_pattern T, 0 [symbolic]
 // CHECK:STDOUT:   %Empty.type.3e5fde.2: type = facet_type <@Empty, @Empty(%T)> [symbolic]
 // CHECK:STDOUT:   %.Self.c95: %Empty.type.3e5fde.2 = bind_symbolic_name .Self [symbolic]
 // CHECK:STDOUT:   %require_complete.22f: <witness> = require_complete_type %Empty.type.3e5fde.2 [symbolic]
-// CHECK:STDOUT:   %assoc_type.79df66.2: type = assoc_entity_type %Empty.type.3e5fde.2, type [symbolic]
-// CHECK:STDOUT:   %assoc0.b2890e.2: %assoc_type.79df66.2 = assoc_entity element0, @Empty.%A [symbolic]
+// CHECK:STDOUT:   %Empty.assoc_type.54c14f.2: type = assoc_entity_type %Empty.type.3e5fde.2 [symbolic]
+// CHECK:STDOUT:   %assoc0.68f673.2: %Empty.assoc_type.54c14f.2 = assoc_entity element0, @Empty.%A [symbolic]
+// CHECK:STDOUT:   %.Self.as_type.a75: type = facet_access_type %.Self.c95 [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit.da4: <witness> = facet_access_witness %.Self.c95 [symbolic]
+// CHECK:STDOUT:   %Empty.facet.bea: %Empty.type.3e5fde.1 = facet_value %.Self.as_type.a75, %.Self.as_wit.da4 [symbolic]
 // CHECK:STDOUT:   %impl.elem0.41c: type = impl_witness_access %.Self.as_wit.da4, element0 [symbolic]
 // CHECK:STDOUT:   %ptr.79f: type = ptr_type %T [symbolic]
 // CHECK:STDOUT:   %Empty_where.type.4ed: type = facet_type <@Empty, @Empty(%T) where %impl.elem0.41c = %ptr.79f> [symbolic]
@@ -53,9 +55,11 @@ fn G(U: Empty(i32) where .A = i32*) {
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [template]
 // CHECK:STDOUT:   %Empty.type.f0b: type = facet_type <@Empty, @Empty(%i32)> [template]
 // CHECK:STDOUT:   %.Self.e6e: %Empty.type.f0b = bind_symbolic_name .Self [symbolic]
-// CHECK:STDOUT:   %assoc_type.eda: type = assoc_entity_type %Empty.type.f0b, type [template]
-// CHECK:STDOUT:   %assoc0.da0: %assoc_type.eda = assoc_entity element0, @Empty.%A [template]
+// CHECK:STDOUT:   %Empty.assoc_type.a46: type = assoc_entity_type %Empty.type.f0b [template]
+// CHECK:STDOUT:   %assoc0.0c3: %Empty.assoc_type.a46 = assoc_entity element0, @Empty.%A [template]
+// CHECK:STDOUT:   %.Self.as_type.920: type = facet_access_type %.Self.e6e [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit.581: <witness> = facet_access_witness %.Self.e6e [symbolic]
+// CHECK:STDOUT:   %Empty.facet.a44: %Empty.type.3e5fde.1 = facet_value %.Self.as_type.920, %.Self.as_wit.581 [symbolic]
 // CHECK:STDOUT:   %impl.elem0.797: type = impl_witness_access %.Self.as_wit.581, element0 [symbolic]
 // CHECK:STDOUT:   %ptr.235: type = ptr_type %i32 [template]
 // CHECK:STDOUT:   %Empty_where.type.a58: type = facet_type <@Empty, @Empty(%i32) where %impl.elem0.797 = %ptr.235> [template]
@@ -109,8 +113,10 @@ fn G(U: Empty(i32) where .A = i32*) {
 // CHECK:STDOUT:       %Empty.type.loc18_26.1: type = facet_type <@Empty, @Empty(constants.%T)> [symbolic = %Empty.type.loc18_26.2 (constants.%Empty.type.3e5fde.2)]
 // CHECK:STDOUT:       %.Self.1: @H.%Empty.type.loc18_26.2 (%Empty.type.3e5fde.2) = bind_symbolic_name .Self [symbolic = %.Self.2 (constants.%.Self.c95)]
 // CHECK:STDOUT:       %.Self.ref: @H.%Empty.type.loc18_26.2 (%Empty.type.3e5fde.2) = name_ref .Self, %.Self.1 [symbolic = %.Self.2 (constants.%.Self.c95)]
-// CHECK:STDOUT:       %.loc18_34: @H.%assoc_type (%assoc_type.79df66.2) = specific_constant @Empty.%assoc0.loc12_8.1, @Empty(constants.%T) [symbolic = %assoc0 (constants.%assoc0.b2890e.2)]
-// CHECK:STDOUT:       %A.ref: @H.%assoc_type (%assoc_type.79df66.2) = name_ref A, %.loc18_34 [symbolic = %assoc0 (constants.%assoc0.b2890e.2)]
+// CHECK:STDOUT:       %.loc18_34.1: @H.%Empty.assoc_type (%Empty.assoc_type.54c14f.2) = specific_constant @A.%assoc0, @Empty(constants.%T) [symbolic = %assoc0 (constants.%assoc0.68f673.2)]
+// CHECK:STDOUT:       %A.ref: @H.%Empty.assoc_type (%Empty.assoc_type.54c14f.2) = name_ref A, %.loc18_34.1 [symbolic = %assoc0 (constants.%assoc0.68f673.2)]
+// CHECK:STDOUT:       %.Self.as_type.loc18_34.1: type = facet_access_type %.Self.ref [symbolic = %.Self.as_type.loc18_34.2 (constants.%.Self.as_type.a75)]
+// CHECK:STDOUT:       %.loc18_34.2: type = converted %.Self.ref, %.Self.as_type.loc18_34.1 [symbolic = %.Self.as_type.loc18_34.2 (constants.%.Self.as_type.a75)]
 // CHECK:STDOUT:       %.Self.as_wit.loc18_34.1: <witness> = facet_access_witness %.Self.ref [symbolic = %.Self.as_wit.loc18_34.2 (constants.%.Self.as_wit.da4)]
 // CHECK:STDOUT:       %impl.elem0.loc18_34.1: type = impl_witness_access %.Self.as_wit.loc18_34.1, element0 [symbolic = %impl.elem0.loc18_34.2 (constants.%impl.elem0.41c)]
 // CHECK:STDOUT:       %T.ref.loc18_39: type = name_ref T, %T.loc18_6.1 [symbolic = %T.loc18_6.2 (constants.%T)]
@@ -135,8 +141,10 @@ fn G(U: Empty(i32) where .A = i32*) {
 // CHECK:STDOUT:       %Empty.type: type = facet_type <@Empty, @Empty(constants.%i32)> [template = constants.%Empty.type.f0b]
 // CHECK:STDOUT:       %.Self: %Empty.type.f0b = bind_symbolic_name .Self [symbolic = constants.%.Self.e6e]
 // CHECK:STDOUT:       %.Self.ref: %Empty.type.f0b = name_ref .Self, %.Self [symbolic = constants.%.Self.e6e]
-// CHECK:STDOUT:       %.loc20_26: %assoc_type.eda = specific_constant @Empty.%assoc0.loc12_8.1, @Empty(constants.%i32) [template = constants.%assoc0.da0]
-// CHECK:STDOUT:       %A.ref: %assoc_type.eda = name_ref A, %.loc20_26 [template = constants.%assoc0.da0]
+// CHECK:STDOUT:       %.loc20_26.1: %Empty.assoc_type.a46 = specific_constant @A.%assoc0, @Empty(constants.%i32) [template = constants.%assoc0.0c3]
+// CHECK:STDOUT:       %A.ref: %Empty.assoc_type.a46 = name_ref A, %.loc20_26.1 [template = constants.%assoc0.0c3]
+// CHECK:STDOUT:       %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type.920]
+// CHECK:STDOUT:       %.loc20_26.2: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type.920]
 // CHECK:STDOUT:       %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit.581]
 // CHECK:STDOUT:       %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0.797]
 // CHECK:STDOUT:       %int_32.loc20_31: Core.IntLiteral = int_value 32 [template = constants.%int_32]
@@ -157,29 +165,35 @@ fn G(U: Empty(i32) where .A = i32*) {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %Empty.type: type = facet_type <@Empty, @Empty(%W.loc11_17.2)> [symbolic = %Empty.type (constants.%Empty.type.3e5fde.1)]
 // CHECK:STDOUT:   %Self.2: %Empty.type.3e5fde.1 = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type @Empty.%Empty.type (%Empty.type.3e5fde.1), type [symbolic = %assoc_type (constants.%assoc_type.79df66.1)]
-// CHECK:STDOUT:   %assoc0.loc12_8.2: @Empty.%assoc_type (%assoc_type.79df66.1) = assoc_entity element0, %A [symbolic = %assoc0.loc12_8.2 (constants.%assoc0.b2890e.1)]
+// CHECK:STDOUT:   %Empty.assoc_type: type = assoc_entity_type @Empty.%Empty.type (%Empty.type.3e5fde.1) [symbolic = %Empty.assoc_type (constants.%Empty.assoc_type.54c14f.1)]
+// CHECK:STDOUT:   %assoc0: @Empty.%Empty.assoc_type (%Empty.assoc_type.54c14f.1) = assoc_entity element0, %A [symbolic = %assoc0 (constants.%assoc0.68f673.1)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:     %Self.1: @Empty.%Empty.type (%Empty.type.3e5fde.1) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
-// CHECK:STDOUT:     %A: type = assoc_const_decl A [template]
-// CHECK:STDOUT:     %assoc0.loc12_8.1: @Empty.%assoc_type (%assoc_type.79df66.1) = assoc_entity element0, %A [symbolic = %assoc0.loc12_8.2 (constants.%assoc0.b2890e.1)]
+// CHECK:STDOUT:     %A: type = assoc_const_decl @A [template] {
+// CHECK:STDOUT:       %assoc0: @Empty.%Empty.assoc_type (%Empty.assoc_type.54c14f.1) = assoc_entity element0, @Empty.%A [symbolic = @Empty.%assoc0 (constants.%assoc0.68f673.1)]
+// CHECK:STDOUT:     }
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = %Self.1
-// CHECK:STDOUT:     .A = %assoc0.loc12_8.1
+// CHECK:STDOUT:     .A = @A.%assoc0
 // CHECK:STDOUT:     witness = (%A)
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @A(@Empty.%W.loc11_17.1: type, @Empty.%Self.1: @Empty.%Empty.type (%Empty.type.3e5fde.1)) {
+// CHECK:STDOUT:   assoc_const A:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @H(%T.loc18_6.1: type, %V.loc18_43.1: type) {
 // CHECK:STDOUT:   %T.loc18_6.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc18_6.2 (constants.%T)]
 // CHECK:STDOUT:   %T.patt.loc18_6.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc18_6.2 (constants.%T.patt)]
 // CHECK:STDOUT:   %Empty.type.loc18_26.2: type = facet_type <@Empty, @Empty(%T.loc18_6.2)> [symbolic = %Empty.type.loc18_26.2 (constants.%Empty.type.3e5fde.2)]
 // CHECK:STDOUT:   %.Self.2: @H.%Empty.type.loc18_26.2 (%Empty.type.3e5fde.2) = bind_symbolic_name .Self [symbolic = %.Self.2 (constants.%.Self.c95)]
 // CHECK:STDOUT:   %require_complete.loc18_34: <witness> = require_complete_type @H.%Empty.type.loc18_26.2 (%Empty.type.3e5fde.2) [symbolic = %require_complete.loc18_34 (constants.%require_complete.22f)]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type @H.%Empty.type.loc18_26.2 (%Empty.type.3e5fde.2), type [symbolic = %assoc_type (constants.%assoc_type.79df66.2)]
-// CHECK:STDOUT:   %assoc0: @H.%assoc_type (%assoc_type.79df66.2) = assoc_entity element0, @Empty.%A [symbolic = %assoc0 (constants.%assoc0.b2890e.2)]
+// CHECK:STDOUT:   %Empty.assoc_type: type = assoc_entity_type @H.%Empty.type.loc18_26.2 (%Empty.type.3e5fde.2) [symbolic = %Empty.assoc_type (constants.%Empty.assoc_type.54c14f.2)]
+// CHECK:STDOUT:   %assoc0: @H.%Empty.assoc_type (%Empty.assoc_type.54c14f.2) = assoc_entity element0, @Empty.%A [symbolic = %assoc0 (constants.%assoc0.68f673.2)]
+// CHECK:STDOUT:   %.Self.as_type.loc18_34.2: type = facet_access_type %.Self.2 [symbolic = %.Self.as_type.loc18_34.2 (constants.%.Self.as_type.a75)]
 // CHECK:STDOUT:   %.Self.as_wit.loc18_34.2: <witness> = facet_access_witness %.Self.2 [symbolic = %.Self.as_wit.loc18_34.2 (constants.%.Self.as_wit.da4)]
 // CHECK:STDOUT:   %impl.elem0.loc18_34.2: type = impl_witness_access %.Self.as_wit.loc18_34.2, element0 [symbolic = %impl.elem0.loc18_34.2 (constants.%impl.elem0.41c)]
 // CHECK:STDOUT:   %ptr.loc18_40.2: type = ptr_type @H.%T.loc18_6.2 (%T) [symbolic = %ptr.loc18_40.2 (constants.%ptr.79f)]
@@ -215,6 +229,8 @@ fn G(U: Empty(i32) where .A = i32*) {
 // CHECK:STDOUT:   %W.patt.loc11_17.2 => constants.%W
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @A(constants.%W, constants.%Self) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @Empty(%W.loc11_17.2) {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @Empty(constants.%T) {
@@ -224,18 +240,21 @@ fn G(U: Empty(i32) where .A = i32*) {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %Empty.type => constants.%Empty.type.3e5fde.2
 // CHECK:STDOUT:   %Self.2 => constants.%Self
-// CHECK:STDOUT:   %assoc_type => constants.%assoc_type.79df66.2
-// CHECK:STDOUT:   %assoc0.loc12_8.2 => constants.%assoc0.b2890e.2
+// CHECK:STDOUT:   %Empty.assoc_type => constants.%Empty.assoc_type.54c14f.2
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.68f673.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @A(constants.%T, constants.%Empty.facet.bea) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @H(constants.%T, constants.%V) {
 // CHECK:STDOUT:   %T.loc18_6.2 => constants.%T
 // CHECK:STDOUT:   %T.patt.loc18_6.2 => constants.%T
 // CHECK:STDOUT:   %Empty.type.loc18_26.2 => constants.%Empty.type.3e5fde.2
 // CHECK:STDOUT:   %.Self.2 => constants.%.Self.c95
 // CHECK:STDOUT:   %require_complete.loc18_34 => constants.%require_complete.22f
-// CHECK:STDOUT:   %assoc_type => constants.%assoc_type.79df66.2
-// CHECK:STDOUT:   %assoc0 => constants.%assoc0.b2890e.2
+// CHECK:STDOUT:   %Empty.assoc_type => constants.%Empty.assoc_type.54c14f.2
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.68f673.2
+// CHECK:STDOUT:   %.Self.as_type.loc18_34.2 => constants.%.Self.as_type.a75
 // CHECK:STDOUT:   %.Self.as_wit.loc18_34.2 => constants.%.Self.as_wit.da4
 // CHECK:STDOUT:   %impl.elem0.loc18_34.2 => constants.%impl.elem0.41c
 // CHECK:STDOUT:   %ptr.loc18_40.2 => constants.%ptr.79f
@@ -253,18 +272,21 @@ fn G(U: Empty(i32) where .A = i32*) {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %Empty.type => constants.%Empty.type.f0b
 // CHECK:STDOUT:   %Self.2 => constants.%Self
-// CHECK:STDOUT:   %assoc_type => constants.%assoc_type.eda
-// CHECK:STDOUT:   %assoc0.loc12_8.2 => constants.%assoc0.da0
+// CHECK:STDOUT:   %Empty.assoc_type => constants.%Empty.assoc_type.a46
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.0c3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @A(constants.%i32, constants.%Empty.facet.a44) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @H(constants.%i32, bool) {
 // CHECK:STDOUT:   %T.loc18_6.2 => constants.%i32
 // CHECK:STDOUT:   %T.patt.loc18_6.2 => constants.%i32
 // CHECK:STDOUT:   %Empty.type.loc18_26.2 => constants.%Empty.type.f0b
 // CHECK:STDOUT:   %.Self.2 => constants.%.Self.e6e
 // CHECK:STDOUT:   %require_complete.loc18_34 => constants.%complete_type.091
-// CHECK:STDOUT:   %assoc_type => constants.%assoc_type.eda
-// CHECK:STDOUT:   %assoc0 => constants.%assoc0.da0
+// CHECK:STDOUT:   %Empty.assoc_type => constants.%Empty.assoc_type.a46
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.0c3
+// CHECK:STDOUT:   %.Self.as_type.loc18_34.2 => constants.%.Self.as_type.920
 // CHECK:STDOUT:   %.Self.as_wit.loc18_34.2 => constants.%.Self.as_wit.581
 // CHECK:STDOUT:   %impl.elem0.loc18_34.2 => constants.%impl.elem0.797
 // CHECK:STDOUT:   %ptr.loc18_40.2 => constants.%ptr.235

+ 258 - 84
toolchain/check/testdata/where_expr/equal_rewrite.carbon

@@ -224,10 +224,12 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %N.type: type = facet_type <@N> [template]
 // CHECK:STDOUT:   %Self: %N.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %N.type, type [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, @N.%P [template]
+// CHECK:STDOUT:   %N.assoc_type: type = assoc_entity_type %N.type [template]
+// CHECK:STDOUT:   %assoc0: %N.assoc_type = assoc_entity element0, @N.%P [template]
 // CHECK:STDOUT:   %.Self: %N.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %N.facet: %N.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %N_where.type: type = facet_type <@N where %impl.elem0 = %empty_struct_type> [template]
@@ -261,7 +263,9 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:       %N.ref: type = name_ref N, file.%N.decl [template = constants.%N.type]
 // CHECK:STDOUT:       %.Self: %N.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:       %.Self.ref: %N.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:       %P.ref: %assoc_type = name_ref P, @N.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %P.ref: %N.assoc_type = name_ref P, @P.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.loc8_22: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:       %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:       %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:       %.loc8_28.1: %empty_struct_type = struct_literal ()
@@ -276,15 +280,20 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @N {
 // CHECK:STDOUT:   %Self: %N.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %P: type = assoc_const_decl P [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %P [template = constants.%assoc0]
+// CHECK:STDOUT:   %P: type = assoc_const_decl @P [template] {
+// CHECK:STDOUT:     %assoc0: %N.assoc_type = assoc_entity element0, @N.%P [template = constants.%assoc0]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .P = %assoc0
+// CHECK:STDOUT:   .P = @P.%assoc0
 // CHECK:STDOUT:   witness = (%P)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @P(@N.%Self: %N.type) {
+// CHECK:STDOUT:   assoc_const P:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @Equal(%T.loc8_10.1: %N_where.type) {
 // CHECK:STDOUT:   %T.loc8_10.2: %N_where.type = bind_symbolic_name T, 0 [symbolic = %T.loc8_10.2 (constants.%T)]
 // CHECK:STDOUT:   %T.patt.loc8_10.2: %N_where.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_10.2 (constants.%T.patt)]
@@ -292,6 +301,10 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:   fn(%T.param_patt: %N_where.type);
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @P(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @P(constants.%N.facet) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @Equal(constants.%T) {
 // CHECK:STDOUT:   %T.loc8_10.2 => constants.%T
 // CHECK:STDOUT:   %T.patt.loc8_10.2 => constants.%T
@@ -302,18 +315,22 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %A.type: type = facet_type <@A> [template]
 // CHECK:STDOUT:   %Self: %A.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %A.type, type [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, @A.%B [template]
-// CHECK:STDOUT:   %assoc1: %assoc_type = assoc_entity element1, @A.%C [template]
+// CHECK:STDOUT:   %A.assoc_type: type = assoc_entity_type %A.type [template]
+// CHECK:STDOUT:   %assoc0: %A.assoc_type = assoc_entity element0, @A.%B [template]
+// CHECK:STDOUT:   %assoc1: %A.assoc_type = assoc_entity element1, @A.%C [template]
 // CHECK:STDOUT:   %.Self.3ca: %A.type = bind_symbolic_name .Self [symbolic]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
+// CHECK:STDOUT:   %.Self.as_type.adb: type = facet_access_type %.Self.3ca [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit.794: <witness> = facet_access_witness %.Self.3ca [symbolic]
+// CHECK:STDOUT:   %A.facet.213: %A.type = facet_value %.Self.as_type.adb, %.Self.as_wit.794 [symbolic]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit.794, element0 [symbolic]
 // CHECK:STDOUT:   %Bool.type: type = fn_type @Bool [template]
 // CHECK:STDOUT:   %Bool: %Bool.type = struct_value () [template]
 // CHECK:STDOUT:   %A_where.type.ef9: type = facet_type <@A where %impl.elem0 = bool> [template]
 // CHECK:STDOUT:   %.Self.e46: %A_where.type.ef9 = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type.6f3: type = facet_access_type %.Self.e46 [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit.a35: <witness> = facet_access_witness %.Self.e46 [symbolic]
+// CHECK:STDOUT:   %A.facet.e67: %A.type = facet_value %.Self.as_type.6f3, %.Self.as_wit.a35 [symbolic]
 // CHECK:STDOUT:   %impl.elem1: type = impl_witness_access %.Self.as_wit.a35, element1 [symbolic]
 // CHECK:STDOUT:   %A_where.type.791: type = facet_type <@A where %impl.elem1 = %empty_tuple.type and %impl.elem0 = bool> [template]
 // CHECK:STDOUT:   %D: %A_where.type.791 = bind_symbolic_name D, 0 [symbolic]
@@ -347,7 +364,9 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:       %A.ref: type = name_ref A, file.%A.decl [template = constants.%A.type]
 // CHECK:STDOUT:       %.Self.1: %A.type = bind_symbolic_name .Self [symbolic = constants.%.Self.3ca]
 // CHECK:STDOUT:       %.Self.ref.loc9_31: %A.type = name_ref .Self, %.Self.1 [symbolic = constants.%.Self.3ca]
-// CHECK:STDOUT:       %B.ref: %assoc_type = name_ref B, @A.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %B.ref: %A.assoc_type = name_ref B, @B.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %.Self.as_type.loc9_31: type = facet_access_type %.Self.ref.loc9_31 [symbolic = constants.%.Self.as_type.adb]
+// CHECK:STDOUT:       %.loc9_31: type = converted %.Self.ref.loc9_31, %.Self.as_type.loc9_31 [symbolic = constants.%.Self.as_type.adb]
 // CHECK:STDOUT:       %.Self.as_wit.loc9_31: <witness> = facet_access_witness %.Self.ref.loc9_31 [symbolic = constants.%.Self.as_wit.794]
 // CHECK:STDOUT:       %impl.elem0: type = impl_witness_access %.Self.as_wit.loc9_31, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:       %bool.make_type: init type = call constants.%Bool() [template = bool]
@@ -358,7 +377,9 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:       }
 // CHECK:STDOUT:       %.Self.2: %A_where.type.ef9 = bind_symbolic_name .Self [symbolic = constants.%.Self.e46]
 // CHECK:STDOUT:       %.Self.ref.loc9_48: %A_where.type.ef9 = name_ref .Self, %.Self.2 [symbolic = constants.%.Self.e46]
-// CHECK:STDOUT:       %C.ref: %assoc_type = name_ref C, @A.%assoc1 [template = constants.%assoc1]
+// CHECK:STDOUT:       %C.ref: %A.assoc_type = name_ref C, @C.%assoc1 [template = constants.%assoc1]
+// CHECK:STDOUT:       %.Self.as_type.loc9_48: type = facet_access_type %.Self.ref.loc9_48 [symbolic = constants.%.Self.as_type.6f3]
+// CHECK:STDOUT:       %.loc9_48: type = converted %.Self.ref.loc9_48, %.Self.as_type.loc9_48 [symbolic = constants.%.Self.as_type.6f3]
 // CHECK:STDOUT:       %.Self.as_wit.loc9_48: <witness> = facet_access_witness %.Self.ref.loc9_48 [symbolic = constants.%.Self.as_wit.a35]
 // CHECK:STDOUT:       %impl.elem1: type = impl_witness_access %.Self.as_wit.loc9_48, element1 [symbolic = constants.%impl.elem1]
 // CHECK:STDOUT:       %.loc9_54.1: %empty_tuple.type = tuple_literal ()
@@ -373,18 +394,28 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @A {
 // CHECK:STDOUT:   %Self: %A.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %B: type = assoc_const_decl B [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %B [template = constants.%assoc0]
-// CHECK:STDOUT:   %C: type = assoc_const_decl C [template]
-// CHECK:STDOUT:   %assoc1: %assoc_type = assoc_entity element1, %C [template = constants.%assoc1]
+// CHECK:STDOUT:   %B: type = assoc_const_decl @B [template] {
+// CHECK:STDOUT:     %assoc0: %A.assoc_type = assoc_entity element0, @A.%B [template = constants.%assoc0]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %C: type = assoc_const_decl @C [template] {
+// CHECK:STDOUT:     %assoc1: %A.assoc_type = assoc_entity element1, @A.%C [template = constants.%assoc1]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .B = %assoc0
-// CHECK:STDOUT:   .C = %assoc1
+// CHECK:STDOUT:   .B = @B.%assoc0
+// CHECK:STDOUT:   .C = @C.%assoc1
 // CHECK:STDOUT:   witness = (%B, %C)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @B(@A.%Self: %A.type) {
+// CHECK:STDOUT:   assoc_const B:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @C(@A.%Self: %A.type) {
+// CHECK:STDOUT:   assoc_const C:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @NestedRewrite(%D.loc9_18.1: %A_where.type.791) {
 // CHECK:STDOUT:   %D.loc9_18.2: %A_where.type.791 = bind_symbolic_name D, 0 [symbolic = %D.loc9_18.2 (constants.%D)]
 // CHECK:STDOUT:   %D.patt.loc9_18.2: %A_where.type.791 = symbolic_binding_pattern D, 0 [symbolic = %D.patt.loc9_18.2 (constants.%D.patt)]
@@ -392,6 +423,14 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:   fn(%D.param_patt: %A_where.type.791);
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @B(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @C(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @B(constants.%A.facet.213) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @C(constants.%A.facet.e67) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @NestedRewrite(constants.%D) {
 // CHECK:STDOUT:   %D.loc9_18.2 => constants.%D
 // CHECK:STDOUT:   %D.patt.loc9_18.2 => constants.%D
@@ -402,11 +441,13 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %E.type: type = facet_type <@E> [template]
 // CHECK:STDOUT:   %Self: %E.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %E.type, type [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, @E.%F [template]
+// CHECK:STDOUT:   %E.assoc_type: type = assoc_entity_type %E.type [template]
+// CHECK:STDOUT:   %assoc0: %E.assoc_type = assoc_entity element0, @E.%F [template]
 // CHECK:STDOUT:   %.Self: %E.type = bind_symbolic_name .Self [symbolic]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %E.facet: %E.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [template]
@@ -455,7 +496,9 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:       %E.ref: type = name_ref E, file.%E.decl [template = constants.%E.type]
 // CHECK:STDOUT:       %.Self: %E.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:       %.Self.ref: %E.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:       %F.ref: %assoc_type = name_ref F, @E.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %F.ref: %E.assoc_type = name_ref F, @F.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.loc8_27: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:       %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:       %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:       %int_32: Core.IntLiteral = int_value 32 [template = constants.%int_32]
@@ -475,13 +518,17 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:       %E.ref: type = name_ref E, file.%E.decl [template = constants.%E.type]
 // CHECK:STDOUT:       %.Self: %E.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:       %.Self.ref.loc10_32: %E.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:       %F.ref.loc10_32: %assoc_type = name_ref F, @E.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %F.ref.loc10_32: %E.assoc_type = name_ref F, @F.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %.Self.as_type.loc10_32: type = facet_access_type %.Self.ref.loc10_32 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.loc10_32: type = converted %.Self.ref.loc10_32, %.Self.as_type.loc10_32 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:       %.Self.as_wit.loc10_32: <witness> = facet_access_witness %.Self.ref.loc10_32 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:       %impl.elem0.loc10_32: type = impl_witness_access %.Self.as_wit.loc10_32, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:       %int_32.loc10_37: Core.IntLiteral = int_value 32 [template = constants.%int_32]
 // CHECK:STDOUT:       %i32.loc10_37: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
 // CHECK:STDOUT:       %.Self.ref.loc10_45: %E.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:       %F.ref.loc10_45: %assoc_type = name_ref F, @E.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %F.ref.loc10_45: %E.assoc_type = name_ref F, @F.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %.Self.as_type.loc10_45: type = facet_access_type %.Self.ref.loc10_45 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.loc10_45: type = converted %.Self.ref.loc10_45, %.Self.as_type.loc10_45 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:       %.Self.as_wit.loc10_45: <witness> = facet_access_witness %.Self.ref.loc10_45 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:       %impl.elem0.loc10_45: type = impl_witness_access %.Self.as_wit.loc10_45, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:       %int_32.loc10_50: Core.IntLiteral = int_value 32 [template = constants.%int_32]
@@ -502,7 +549,9 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:       %E.ref: type = name_ref E, file.%E.decl [template = constants.%E.type]
 // CHECK:STDOUT:       %.Self: %E.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:       %.Self.ref: %E.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:       %F.ref: %assoc_type = name_ref F, @E.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %F.ref: %E.assoc_type = name_ref F, @F.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.loc14_32: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:       %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:       %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:       %int_32: Core.IntLiteral = int_value 32 [template = constants.%int_32]
@@ -517,15 +566,20 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @E {
 // CHECK:STDOUT:   %Self: %E.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %F: type = assoc_const_decl F [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %F [template = constants.%assoc0]
+// CHECK:STDOUT:   %F: type = assoc_const_decl @F [template] {
+// CHECK:STDOUT:     %assoc0: %E.assoc_type = assoc_entity element0, @E.%F [template = constants.%assoc0]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .F = %assoc0
+// CHECK:STDOUT:   .F = @F.%assoc0
 // CHECK:STDOUT:   witness = (%F)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @F(@E.%Self: %E.type) {
+// CHECK:STDOUT:   assoc_const F:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @OneRewrite(%G.loc8_15.1: %E_where.type) {
 // CHECK:STDOUT:   %G.loc8_15.2: %E_where.type = bind_symbolic_name G, 0 [symbolic = %G.loc8_15.2 (constants.%G)]
 // CHECK:STDOUT:   %G.patt.loc8_15.2: %E_where.type = symbolic_binding_pattern G, 0 [symbolic = %G.patt.loc8_15.2 (constants.%G.patt)]
@@ -572,6 +626,10 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @F(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F(constants.%E.facet) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @OneRewrite(constants.%G) {
 // CHECK:STDOUT:   %G.loc8_15.2 => constants.%G
 // CHECK:STDOUT:   %G.patt.loc8_15.2 => constants.%G
@@ -616,12 +674,14 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %J.type: type = facet_type <@J> [template]
 // CHECK:STDOUT:   %Self: %J.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %J.type, type [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, @J.%K [template]
-// CHECK:STDOUT:   %assoc1: %assoc_type = assoc_entity element1, @J.%L [template]
+// CHECK:STDOUT:   %J.assoc_type: type = assoc_entity_type %J.type [template]
+// CHECK:STDOUT:   %assoc0: %J.assoc_type = assoc_entity element0, @J.%K [template]
+// CHECK:STDOUT:   %assoc1: %J.assoc_type = assoc_entity element1, @J.%L [template]
 // CHECK:STDOUT:   %.Self: %J.type = bind_symbolic_name .Self [symbolic]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %J.facet: %J.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT:   %impl.elem1: type = impl_witness_access %.Self.as_wit, element1 [symbolic]
 // CHECK:STDOUT:   %Bool.type: type = fn_type @Bool [template]
@@ -664,13 +724,17 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:       %J.ref: type = name_ref J, file.%J.decl [template = constants.%J.type]
 // CHECK:STDOUT:       %.Self: %J.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:       %.Self.ref.loc9_29: %J.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:       %K.ref: %assoc_type = name_ref K, @J.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %K.ref: %J.assoc_type = name_ref K, @K.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %.Self.as_type.loc9_29: type = facet_access_type %.Self.ref.loc9_29 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.loc9_29: type = converted %.Self.ref.loc9_29, %.Self.as_type.loc9_29 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:       %.Self.as_wit.loc9_29: <witness> = facet_access_witness %.Self.ref.loc9_29 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:       %impl.elem0: type = impl_witness_access %.Self.as_wit.loc9_29, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:       %.loc9_35.1: %empty_tuple.type = tuple_literal ()
 // CHECK:STDOUT:       %.loc9_35.2: type = converted %.loc9_35.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type]
 // CHECK:STDOUT:       %.Self.ref.loc9_41: %J.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:       %L.ref: %assoc_type = name_ref L, @J.%assoc1 [template = constants.%assoc1]
+// CHECK:STDOUT:       %L.ref: %J.assoc_type = name_ref L, @L.%assoc1 [template = constants.%assoc1]
+// CHECK:STDOUT:       %.Self.as_type.loc9_41: type = facet_access_type %.Self.ref.loc9_41 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.loc9_41: type = converted %.Self.ref.loc9_41, %.Self.as_type.loc9_41 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:       %.Self.as_wit.loc9_41: <witness> = facet_access_witness %.Self.ref.loc9_41 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:       %impl.elem1: type = impl_witness_access %.Self.as_wit.loc9_41, element1 [symbolic = constants.%impl.elem1]
 // CHECK:STDOUT:       %bool.make_type: init type = call constants.%Bool() [template = bool]
@@ -692,14 +756,18 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:       %J.ref: type = name_ref J, file.%J.decl [template = constants.%J.type]
 // CHECK:STDOUT:       %.Self: %J.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:       %.Self.ref.loc11_25: %J.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:       %L.ref: %assoc_type = name_ref L, @J.%assoc1 [template = constants.%assoc1]
+// CHECK:STDOUT:       %L.ref: %J.assoc_type = name_ref L, @L.%assoc1 [template = constants.%assoc1]
+// CHECK:STDOUT:       %.Self.as_type.loc11_25: type = facet_access_type %.Self.ref.loc11_25 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.loc11_25: type = converted %.Self.ref.loc11_25, %.Self.as_type.loc11_25 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:       %.Self.as_wit.loc11_25: <witness> = facet_access_witness %.Self.ref.loc11_25 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:       %impl.elem1: type = impl_witness_access %.Self.as_wit.loc11_25, element1 [symbolic = constants.%impl.elem1]
 // CHECK:STDOUT:       %bool.make_type: init type = call constants.%Bool() [template = bool]
 // CHECK:STDOUT:       %.loc11_30.1: type = value_of_initializer %bool.make_type [template = bool]
 // CHECK:STDOUT:       %.loc11_30.2: type = converted %bool.make_type, %.loc11_30.1 [template = bool]
 // CHECK:STDOUT:       %.Self.ref.loc11_39: %J.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:       %K.ref: %assoc_type = name_ref K, @J.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %K.ref: %J.assoc_type = name_ref K, @K.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %.Self.as_type.loc11_39: type = facet_access_type %.Self.ref.loc11_39 [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.loc11_39: type = converted %.Self.ref.loc11_39, %.Self.as_type.loc11_39 [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:       %.Self.as_wit.loc11_39: <witness> = facet_access_witness %.Self.ref.loc11_39 [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:       %impl.elem0: type = impl_witness_access %.Self.as_wit.loc11_39, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:       %.loc11_45.1: %empty_tuple.type = tuple_literal ()
@@ -715,18 +783,28 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @J {
 // CHECK:STDOUT:   %Self: %J.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %K: type = assoc_const_decl K [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %K [template = constants.%assoc0]
-// CHECK:STDOUT:   %L: type = assoc_const_decl L [template]
-// CHECK:STDOUT:   %assoc1: %assoc_type = assoc_entity element1, %L [template = constants.%assoc1]
+// CHECK:STDOUT:   %K: type = assoc_const_decl @K [template] {
+// CHECK:STDOUT:     %assoc0: %J.assoc_type = assoc_entity element0, @J.%K [template = constants.%assoc0]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %L: type = assoc_const_decl @L [template] {
+// CHECK:STDOUT:     %assoc1: %J.assoc_type = assoc_entity element1, @J.%L [template = constants.%assoc1]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .K = %assoc0
-// CHECK:STDOUT:   .L = %assoc1
+// CHECK:STDOUT:   .K = @K.%assoc0
+// CHECK:STDOUT:   .L = @L.%assoc1
 // CHECK:STDOUT:   witness = (%K, %L)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @K(@J.%Self: %J.type) {
+// CHECK:STDOUT:   assoc_const K:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @L(@J.%Self: %J.type) {
+// CHECK:STDOUT:   assoc_const L:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @Alphabetical(%M.loc9_17.1: %J_where.type) {
 // CHECK:STDOUT:   %M.loc9_17.2: %J_where.type = bind_symbolic_name M, 0 [symbolic = %M.loc9_17.2 (constants.%M)]
 // CHECK:STDOUT:   %M.patt.loc9_17.2: %J_where.type = symbolic_binding_pattern M, 0 [symbolic = %M.patt.loc9_17.2 (constants.%M.patt)]
@@ -756,6 +834,14 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @K(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @L(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @K(constants.%J.facet) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @L(constants.%J.facet) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @Alphabetical(constants.%M) {
 // CHECK:STDOUT:   %M.loc9_17.2 => constants.%M
 // CHECK:STDOUT:   %M.patt.loc9_17.2 => constants.%M
@@ -780,10 +866,12 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %O.type: type = facet_type <@O> [template]
 // CHECK:STDOUT:   %Self.040: %O.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %O.type, type [template]
-// CHECK:STDOUT:   %assoc0.20f: %assoc_type = assoc_entity element0, @O.%P [template]
+// CHECK:STDOUT:   %O.assoc_type: type = assoc_entity_type %O.type [template]
+// CHECK:STDOUT:   %assoc0.0e4: %O.assoc_type = assoc_entity element0, @O.%P [template]
 // CHECK:STDOUT:   %.Self: %O.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %O.facet: %O.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [template]
@@ -829,7 +917,9 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:       %O.ref: type = name_ref O, file.%O.decl [template = constants.%O.type]
 // CHECK:STDOUT:       %.Self: %O.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:       %.Self.ref: %O.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:       %P.ref: %assoc_type = name_ref P, @O.%assoc0 [template = constants.%assoc0.20f]
+// CHECK:STDOUT:       %P.ref: %O.assoc_type = name_ref P, @P.%assoc0 [template = constants.%assoc0.0e4]
+// CHECK:STDOUT:       %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.loc8_28: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:       %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:       %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:       %int_32: Core.IntLiteral = int_value 32 [template = constants.%int_32]
@@ -849,7 +939,9 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:       %O.ref: type = name_ref O, file.%O.decl [template = constants.%O.type]
 // CHECK:STDOUT:       %.Self: %O.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:       %.Self.ref: %O.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:       %P.ref: %assoc_type = name_ref P, @O.%assoc0 [template = constants.%assoc0.20f]
+// CHECK:STDOUT:       %P.ref: %O.assoc_type = name_ref P, @P.%assoc0 [template = constants.%assoc0.0e4]
+// CHECK:STDOUT:       %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.loc10_25: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:       %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:       %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:       %bool.make_type: init type = call constants.%Bool() [template = bool]
@@ -865,15 +957,20 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @O {
 // CHECK:STDOUT:   %Self: %O.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.040]
-// CHECK:STDOUT:   %P: type = assoc_const_decl P [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %P [template = constants.%assoc0.20f]
+// CHECK:STDOUT:   %P: type = assoc_const_decl @P [template] {
+// CHECK:STDOUT:     %assoc0: %O.assoc_type = assoc_entity element0, @O.%P [template = constants.%assoc0.0e4]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .P = %assoc0
+// CHECK:STDOUT:   .P = @P.%assoc0
 // CHECK:STDOUT:   witness = (%P)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @P(@O.%Self: %O.type) {
+// CHECK:STDOUT:   assoc_const P:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @WithInteger(%Q.loc8_16.1: %O_where.type.9eb) {
 // CHECK:STDOUT:   %Q.loc8_16.2: %O_where.type.9eb = bind_symbolic_name Q, 0 [symbolic = %Q.loc8_16.2 (constants.%Q)]
 // CHECK:STDOUT:   %Q.patt.loc8_16.2: %O_where.type.9eb = symbolic_binding_pattern Q, 0 [symbolic = %Q.patt.loc8_16.2 (constants.%Q.patt)]
@@ -901,6 +998,10 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @P(constants.%Self.040) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @P(constants.%O.facet) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @WithInteger(constants.%Q) {
 // CHECK:STDOUT:   %Q.loc8_16.2 => constants.%Q
 // CHECK:STDOUT:   %Q.patt.loc8_16.2 => constants.%Q
@@ -916,12 +1017,14 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %S.type: type = facet_type <@S> [template]
 // CHECK:STDOUT:   %Self.b33: %S.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %S.type, type [template]
-// CHECK:STDOUT:   %assoc0.e49: %assoc_type = assoc_entity element0, @S.%T [template]
-// CHECK:STDOUT:   %assoc1: %assoc_type = assoc_entity element1, @S.%U [template]
+// CHECK:STDOUT:   %S.assoc_type: type = assoc_entity_type %S.type [template]
+// CHECK:STDOUT:   %assoc0.720: %S.assoc_type = assoc_entity element0, @S.%T [template]
+// CHECK:STDOUT:   %assoc1: %S.assoc_type = assoc_entity element1, @S.%U [template]
 // CHECK:STDOUT:   %.Self: %S.type = bind_symbolic_name .Self [symbolic]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %S.facet: %S.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT:   %S_where.type.e40: type = facet_type <@S where %impl.elem0 = %empty_tuple.type> [template]
 // CHECK:STDOUT:   %V: %S_where.type.e40 = bind_symbolic_name V, 0 [symbolic]
@@ -962,7 +1065,9 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:       %S.ref: type = name_ref S, file.%S.decl [template = constants.%S.type]
 // CHECK:STDOUT:       %.Self: %S.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:       %.Self.ref: %S.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:       %T.ref: %assoc_type = name_ref T, @S.%assoc0 [template = constants.%assoc0.e49]
+// CHECK:STDOUT:       %T.ref: %S.assoc_type = name_ref T, @T.%assoc0 [template = constants.%assoc0.720]
+// CHECK:STDOUT:       %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.loc9_22: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:       %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:       %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:       %.loc9_28.1: %empty_tuple.type = tuple_literal ()
@@ -982,7 +1087,9 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:       %S.ref: type = name_ref S, file.%S.decl [template = constants.%S.type]
 // CHECK:STDOUT:       %.Self: %S.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:       %.Self.ref: %S.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:       %U.ref: %assoc_type = name_ref U, @S.%assoc1 [template = constants.%assoc1]
+// CHECK:STDOUT:       %U.ref: %S.assoc_type = name_ref U, @U.%assoc1 [template = constants.%assoc1]
+// CHECK:STDOUT:       %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.loc11_22: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:       %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:       %impl.elem1: type = impl_witness_access %.Self.as_wit, element1 [symbolic = constants.%impl.elem1]
 // CHECK:STDOUT:       %.loc11_28.1: %empty_tuple.type = tuple_literal ()
@@ -997,18 +1104,28 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @S {
 // CHECK:STDOUT:   %Self: %S.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.b33]
-// CHECK:STDOUT:   %T: type = assoc_const_decl T [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %T [template = constants.%assoc0.e49]
-// CHECK:STDOUT:   %U: type = assoc_const_decl U [template]
-// CHECK:STDOUT:   %assoc1: %assoc_type = assoc_entity element1, %U [template = constants.%assoc1]
+// CHECK:STDOUT:   %T: type = assoc_const_decl @T [template] {
+// CHECK:STDOUT:     %assoc0: %S.assoc_type = assoc_entity element0, @S.%T [template = constants.%assoc0.720]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %U: type = assoc_const_decl @U [template] {
+// CHECK:STDOUT:     %assoc1: %S.assoc_type = assoc_entity element1, @S.%U [template = constants.%assoc1]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .T = %assoc0
-// CHECK:STDOUT:   .U = %assoc1
+// CHECK:STDOUT:   .T = @T.%assoc0
+// CHECK:STDOUT:   .U = @U.%assoc1
 // CHECK:STDOUT:   witness = (%T, %U)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @T(@S.%Self: %S.type) {
+// CHECK:STDOUT:   assoc_const T:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @U(@S.%Self: %S.type) {
+// CHECK:STDOUT:   assoc_const U:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @WithT(%V.loc9_10.1: %S_where.type.e40) {
 // CHECK:STDOUT:   %V.loc9_10.2: %S_where.type.e40 = bind_symbolic_name V, 0 [symbolic = %V.loc9_10.2 (constants.%V)]
 // CHECK:STDOUT:   %V.patt.loc9_10.2: %S_where.type.e40 = symbolic_binding_pattern V, 0 [symbolic = %V.patt.loc9_10.2 (constants.%V.patt)]
@@ -1036,11 +1153,19 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @T(constants.%Self.b33) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @U(constants.%Self.b33) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @T(constants.%S.facet) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @WithT(constants.%V) {
 // CHECK:STDOUT:   %V.loc9_10.2 => constants.%V
 // CHECK:STDOUT:   %V.patt.loc9_10.2 => constants.%V
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @U(constants.%S.facet) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @WithU(constants.%W) {
 // CHECK:STDOUT:   %W.loc11_10.2 => constants.%W
 // CHECK:STDOUT:   %W.patt.loc11_10.2 => constants.%W
@@ -1094,11 +1219,11 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Main.import_ref.169 = import_ref Main//equal_constraint, inst17 [no loc], unloaded
-// CHECK:STDOUT:   %Main.import_ref.d17 = import_ref Main//equal_constraint, loc5_8, unloaded
+// CHECK:STDOUT:   %Main.import_ref.020 = import_ref Main//equal_constraint, loc5_8, unloaded
 // CHECK:STDOUT:   %Main.P = import_ref Main//equal_constraint, P, unloaded
 // CHECK:STDOUT:   %Main.import_ref.b61 = import_ref Main//nested_rewrites, inst17 [no loc], unloaded
-// CHECK:STDOUT:   %Main.import_ref.2a9 = import_ref Main//nested_rewrites, loc5_8, unloaded
-// CHECK:STDOUT:   %Main.import_ref.508 = import_ref Main//nested_rewrites, loc6_8, unloaded
+// CHECK:STDOUT:   %Main.import_ref.91a = import_ref Main//nested_rewrites, loc5_8, unloaded
+// CHECK:STDOUT:   %Main.import_ref.55d = import_ref Main//nested_rewrites, loc6_8, unloaded
 // CHECK:STDOUT:   %Main.B = import_ref Main//nested_rewrites, B, unloaded
 // CHECK:STDOUT:   %Main.C = import_ref Main//nested_rewrites, C, unloaded
 // CHECK:STDOUT: }
@@ -1120,15 +1245,15 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT: interface @N [from "equal_constraint.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = imports.%Main.import_ref.169
-// CHECK:STDOUT:   .P = imports.%Main.import_ref.d17
+// CHECK:STDOUT:   .P = imports.%Main.import_ref.020
 // CHECK:STDOUT:   witness = (imports.%Main.P)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @A [from "nested_rewrites.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = imports.%Main.import_ref.b61
-// CHECK:STDOUT:   .B = imports.%Main.import_ref.2a9
-// CHECK:STDOUT:   .C = imports.%Main.import_ref.508
+// CHECK:STDOUT:   .B = imports.%Main.import_ref.91a
+// CHECK:STDOUT:   .C = imports.%Main.import_ref.55d
 // CHECK:STDOUT:   witness = (imports.%Main.B, imports.%Main.C)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -1173,10 +1298,12 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %I.type: type = facet_type <@I> [template]
 // CHECK:STDOUT:   %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %I.type, type [template]
-// CHECK:STDOUT:   %assoc0.ea2: %assoc_type = assoc_entity element0, @I.%Member [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0.05b: %I.assoc_type = assoc_entity element0, @I.%Member [template]
 // CHECK:STDOUT:   %.Self: %I.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %I.facet: %I.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT:   %int_2: Core.IntLiteral = int_value 2 [template]
 // CHECK:STDOUT:   %X.patt: <error> = symbolic_binding_pattern X, 0 [symbolic]
@@ -1209,7 +1336,9 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:       %I.ref: type = name_ref I, file.%I.decl [template = constants.%I.type]
 // CHECK:STDOUT:       %.Self: %I.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:       %.Self.ref: %I.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:       %Member.ref: %assoc_type = name_ref Member, @I.%assoc0 [template = constants.%assoc0.ea2]
+// CHECK:STDOUT:       %Member.ref: %I.assoc_type = name_ref Member, @Member.%assoc0 [template = constants.%assoc0.05b]
+// CHECK:STDOUT:       %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.loc16_36: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:       %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:       %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:       %int_2: Core.IntLiteral = int_value 2 [template = constants.%int_2]
@@ -1224,21 +1353,30 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826]
-// CHECK:STDOUT:   %Member: type = assoc_const_decl Member [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %Member [template = constants.%assoc0.ea2]
+// CHECK:STDOUT:   %Member: type = assoc_const_decl @Member [template] {
+// CHECK:STDOUT:     %assoc0: %I.assoc_type = assoc_entity element0, @I.%Member [template = constants.%assoc0.05b]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .Member = %assoc0
+// CHECK:STDOUT:   .Member = @Member.%assoc0
 // CHECK:STDOUT:   witness = (%Member)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @Member(@I.%Self: %I.type) {
+// CHECK:STDOUT:   assoc_const Member:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @RewriteTypeMismatch(%X: <error>) {
 // CHECK:STDOUT:   %X.patt.loc16_24.2: <error> = symbolic_binding_pattern X, 0 [symbolic = %X.patt.loc16_24.2 (constants.%X.patt)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%X.param_patt: <error>);
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @Member(constants.%Self.826) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Member(constants.%I.facet) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @RewriteTypeMismatch(<error>) {
 // CHECK:STDOUT:   %X.patt.loc16_24.2 => <error>
 // CHECK:STDOUT: }
@@ -1326,12 +1464,14 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %E.type: type = facet_type <@E> [template]
 // CHECK:STDOUT:   %Self.19a: %E.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %E.type, type [template]
-// CHECK:STDOUT:   %assoc0.4b1: %assoc_type = assoc_entity element0, @E.%F [template]
-// CHECK:STDOUT:   %assoc1: %assoc_type = assoc_entity element1, @E.%G [template]
+// CHECK:STDOUT:   %E.assoc_type: type = assoc_entity_type %E.type [template]
+// CHECK:STDOUT:   %assoc0.9c3: %E.assoc_type = assoc_entity element0, @E.%F [template]
+// CHECK:STDOUT:   %assoc1: %E.assoc_type = assoc_entity element1, @E.%G [template]
 // CHECK:STDOUT:   %.Self.da5: %E.type = bind_symbolic_name .Self [symbolic]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [template]
+// CHECK:STDOUT:   %.Self.as_type.34e: type = facet_access_type %.Self.da5 [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit.f42: <witness> = facet_access_witness %.Self.da5 [symbolic]
+// CHECK:STDOUT:   %E.facet.74f: %E.type = facet_value %.Self.as_type.34e, %.Self.as_wit.f42 [symbolic]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit.f42, element0 [symbolic]
 // CHECK:STDOUT:   %Bool.type: type = fn_type @Bool [template]
 // CHECK:STDOUT:   %Bool: %Bool.type = struct_value () [template]
@@ -1343,7 +1483,9 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
 // CHECK:STDOUT:   %E_where.type.324: type = facet_type <@E where %impl.elem0 = %empty_struct_type> [template]
 // CHECK:STDOUT:   %.Self.665: %E_where.type.324 = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type.c08: type = facet_access_type %.Self.665 [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit.bb3: <witness> = facet_access_witness %.Self.665 [symbolic]
+// CHECK:STDOUT:   %E.facet.f08: %E.type = facet_value %.Self.as_type.c08, %.Self.as_wit.bb3 [symbolic]
 // CHECK:STDOUT:   %impl.elem1.244: type = impl_witness_access %.Self.as_wit.bb3, element1 [symbolic]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [template]
@@ -1379,14 +1521,18 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:     %E.ref.loc18: type = name_ref E, %E.decl [template = constants.%E.type]
 // CHECK:STDOUT:     %.Self.1: %E.type = bind_symbolic_name .Self [symbolic = constants.%.Self.da5]
 // CHECK:STDOUT:     %.Self.ref.loc18_17: %E.type = name_ref .Self, %.Self.1 [symbolic = constants.%.Self.da5]
-// CHECK:STDOUT:     %F.ref.loc18: %assoc_type = name_ref F, @E.%assoc0 [template = constants.%assoc0.4b1]
+// CHECK:STDOUT:     %F.ref.loc18: %E.assoc_type = name_ref F, @F.%assoc0 [template = constants.%assoc0.9c3]
+// CHECK:STDOUT:     %.Self.as_type.loc18_17: type = facet_access_type %.Self.ref.loc18_17 [symbolic = constants.%.Self.as_type.34e]
+// CHECK:STDOUT:     %.loc18_17: type = converted %.Self.ref.loc18_17, %.Self.as_type.loc18_17 [symbolic = constants.%.Self.as_type.34e]
 // CHECK:STDOUT:     %.Self.as_wit.loc18_17: <witness> = facet_access_witness %.Self.ref.loc18_17 [symbolic = constants.%.Self.as_wit.f42]
 // CHECK:STDOUT:     %impl.elem0.loc18: type = impl_witness_access %.Self.as_wit.loc18_17, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %bool.make_type: init type = call constants.%Bool() [template = bool]
 // CHECK:STDOUT:     %.loc18_22.1: type = value_of_initializer %bool.make_type [template = bool]
 // CHECK:STDOUT:     %.loc18_22.2: type = converted %bool.make_type, %.loc18_22.1 [template = bool]
 // CHECK:STDOUT:     %.Self.ref.loc18_31: %E.type = name_ref .Self, %.Self.1 [symbolic = constants.%.Self.da5]
-// CHECK:STDOUT:     %G.ref.loc18: %assoc_type = name_ref G, @E.%assoc1 [template = constants.%assoc1]
+// CHECK:STDOUT:     %G.ref.loc18: %E.assoc_type = name_ref G, @G.%assoc1 [template = constants.%assoc1]
+// CHECK:STDOUT:     %.Self.as_type.loc18_31: type = facet_access_type %.Self.ref.loc18_31 [symbolic = constants.%.Self.as_type.34e]
+// CHECK:STDOUT:     %.loc18_31: type = converted %.Self.ref.loc18_31, %.Self.as_type.loc18_31 [symbolic = constants.%.Self.as_type.34e]
 // CHECK:STDOUT:     %.Self.as_wit.loc18_31: <witness> = facet_access_witness %.Self.ref.loc18_31 [symbolic = constants.%.Self.as_wit.f42]
 // CHECK:STDOUT:     %impl.elem1.loc18: type = impl_witness_access %.Self.as_wit.loc18_31, element1 [symbolic = constants.%impl.elem1.91f]
 // CHECK:STDOUT:     %.loc18_37.1: %empty_tuple.type = tuple_literal ()
@@ -1405,7 +1551,9 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:     %E.ref.loc27: type = name_ref E, %E.decl [template = constants.%E.type]
 // CHECK:STDOUT:     %.Self.2: %E.type = bind_symbolic_name .Self [symbolic = constants.%.Self.da5]
 // CHECK:STDOUT:     %.Self.ref.loc27_18: %E.type = name_ref .Self, %.Self.2 [symbolic = constants.%.Self.da5]
-// CHECK:STDOUT:     %F.ref.loc27: %assoc_type = name_ref F, @E.%assoc0 [template = constants.%assoc0.4b1]
+// CHECK:STDOUT:     %F.ref.loc27: %E.assoc_type = name_ref F, @F.%assoc0 [template = constants.%assoc0.9c3]
+// CHECK:STDOUT:     %.Self.as_type.loc27_18: type = facet_access_type %.Self.ref.loc27_18 [symbolic = constants.%.Self.as_type.34e]
+// CHECK:STDOUT:     %.loc27_18: type = converted %.Self.ref.loc27_18, %.Self.as_type.loc27_18 [symbolic = constants.%.Self.as_type.34e]
 // CHECK:STDOUT:     %.Self.as_wit.loc27_18: <witness> = facet_access_witness %.Self.ref.loc27_18 [symbolic = constants.%.Self.as_wit.f42]
 // CHECK:STDOUT:     %impl.elem0.loc27: type = impl_witness_access %.Self.as_wit.loc27_18, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %.loc27_24.1: %empty_struct_type = struct_literal ()
@@ -1415,7 +1563,9 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %.Self.3: %E_where.type.324 = bind_symbolic_name .Self [symbolic = constants.%.Self.665]
 // CHECK:STDOUT:     %.Self.ref.loc27_33: %E_where.type.324 = name_ref .Self, %.Self.3 [symbolic = constants.%.Self.665]
-// CHECK:STDOUT:     %G.ref.loc27: %assoc_type = name_ref G, @E.%assoc1 [template = constants.%assoc1]
+// CHECK:STDOUT:     %G.ref.loc27: %E.assoc_type = name_ref G, @G.%assoc1 [template = constants.%assoc1]
+// CHECK:STDOUT:     %.Self.as_type.loc27_33: type = facet_access_type %.Self.ref.loc27_33 [symbolic = constants.%.Self.as_type.c08]
+// CHECK:STDOUT:     %.loc27_33: type = converted %.Self.ref.loc27_33, %.Self.as_type.loc27_33 [symbolic = constants.%.Self.as_type.c08]
 // CHECK:STDOUT:     %.Self.as_wit.loc27_33: <witness> = facet_access_witness %.Self.ref.loc27_33 [symbolic = constants.%.Self.as_wit.bb3]
 // CHECK:STDOUT:     %impl.elem1.loc27: type = impl_witness_access %.Self.as_wit.loc27_33, element1 [symbolic = constants.%impl.elem1.244]
 // CHECK:STDOUT:     %int_32: Core.IntLiteral = int_value 32 [template = constants.%int_32]
@@ -1433,11 +1583,15 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:     %E.ref.loc36: type = name_ref E, %E.decl [template = constants.%E.type]
 // CHECK:STDOUT:     %.Self.4: %E.type = bind_symbolic_name .Self [symbolic = constants.%.Self.da5]
 // CHECK:STDOUT:     %.Self.ref.loc36_17: %E.type = name_ref .Self, %.Self.4 [symbolic = constants.%.Self.da5]
-// CHECK:STDOUT:     %F.ref.loc36: %assoc_type = name_ref F, @E.%assoc0 [template = constants.%assoc0.4b1]
+// CHECK:STDOUT:     %F.ref.loc36: %E.assoc_type = name_ref F, @F.%assoc0 [template = constants.%assoc0.9c3]
+// CHECK:STDOUT:     %.Self.as_type.loc36_17: type = facet_access_type %.Self.ref.loc36_17 [symbolic = constants.%.Self.as_type.34e]
+// CHECK:STDOUT:     %.loc36_17: type = converted %.Self.ref.loc36_17, %.Self.as_type.loc36_17 [symbolic = constants.%.Self.as_type.34e]
 // CHECK:STDOUT:     %.Self.as_wit.loc36_17: <witness> = facet_access_witness %.Self.ref.loc36_17 [symbolic = constants.%.Self.as_wit.f42]
 // CHECK:STDOUT:     %impl.elem0.loc36: type = impl_witness_access %.Self.as_wit.loc36_17, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:     %.Self.ref.loc36_22: %E.type = name_ref .Self, %.Self.4 [symbolic = constants.%.Self.da5]
-// CHECK:STDOUT:     %G.ref.loc36: %assoc_type = name_ref G, @E.%assoc1 [template = constants.%assoc1]
+// CHECK:STDOUT:     %G.ref.loc36: %E.assoc_type = name_ref G, @G.%assoc1 [template = constants.%assoc1]
+// CHECK:STDOUT:     %.Self.as_type.loc36_27: type = facet_access_type %.Self.ref.loc36_22 [symbolic = constants.%.Self.as_type.34e]
+// CHECK:STDOUT:     %.loc36_27: type = converted %.Self.ref.loc36_22, %.Self.as_type.loc36_27 [symbolic = constants.%.Self.as_type.34e]
 // CHECK:STDOUT:     %.Self.as_wit.loc36_27: <witness> = facet_access_witness %.Self.ref.loc36_22 [symbolic = constants.%.Self.as_wit.f42]
 // CHECK:STDOUT:     %impl.elem1.loc36: type = impl_witness_access %.Self.as_wit.loc36_27, element1 [symbolic = constants.%impl.elem1.91f]
 // CHECK:STDOUT:     %.loc36_11.2: type = where_expr %.Self.4 [template = constants.%E_where.type.503] {
@@ -1450,18 +1604,28 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @E {
 // CHECK:STDOUT:   %Self: %E.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.19a]
-// CHECK:STDOUT:   %F: type = assoc_const_decl F [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %F [template = constants.%assoc0.4b1]
-// CHECK:STDOUT:   %G: type = assoc_const_decl G [template]
-// CHECK:STDOUT:   %assoc1: %assoc_type = assoc_entity element1, %G [template = constants.%assoc1]
+// CHECK:STDOUT:   %F: type = assoc_const_decl @F [template] {
+// CHECK:STDOUT:     %assoc0: %E.assoc_type = assoc_entity element0, @E.%F [template = constants.%assoc0.9c3]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %G: type = assoc_const_decl @G [template] {
+// CHECK:STDOUT:     %assoc1: %E.assoc_type = assoc_entity element1, @E.%G [template = constants.%assoc1]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .F = %assoc0
-// CHECK:STDOUT:   .G = %assoc1
+// CHECK:STDOUT:   .F = @F.%assoc0
+// CHECK:STDOUT:   .G = @G.%assoc1
 // CHECK:STDOUT:   witness = (%F, %G)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @F(@E.%Self: %E.type) {
+// CHECK:STDOUT:   assoc_const F:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @G(@E.%Self: %E.type) {
+// CHECK:STDOUT:   assoc_const G:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %int_64: Core.IntLiteral = int_value 64 [template = constants.%int_64]
@@ -1471,3 +1635,13 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @F(constants.%Self.19a) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @G(constants.%Self.19a) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F(constants.%E.facet.74f) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @G(constants.%E.facet.74f) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @G(constants.%E.facet.f08) {}
+// CHECK:STDOUT:

+ 19 - 6
toolchain/check/testdata/where_expr/non_generic.carbon

@@ -18,10 +18,12 @@ fn NotGenericF(U: I where .T == i32) {}
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %I.type: type = facet_type <@I> [template]
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %assoc_type: type = assoc_entity_type %I.type, type [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, @I.%T [template]
+// CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type %I.type [template]
+// CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [template]
 // CHECK:STDOUT:   %.Self: %I.type = bind_symbolic_name .Self [symbolic]
+// CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic]
 // CHECK:STDOUT:   %.Self.as_wit: <witness> = facet_access_witness %.Self [symbolic]
+// CHECK:STDOUT:   %I.facet: %I.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [template]
@@ -55,7 +57,9 @@ fn NotGenericF(U: I where .T == i32) {}
 // CHECK:STDOUT:       %I.ref: type = name_ref I, file.%I.decl [template = constants.%I.type]
 // CHECK:STDOUT:       %.Self: %I.type = bind_symbolic_name .Self [symbolic = constants.%.Self]
 // CHECK:STDOUT:       %.Self.ref: %I.type = name_ref .Self, %.Self [symbolic = constants.%.Self]
-// CHECK:STDOUT:       %T.ref: %assoc_type = name_ref T, @I.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %T.ref: %I.assoc_type = name_ref T, @T.%assoc0 [template = constants.%assoc0]
+// CHECK:STDOUT:       %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.loc14_27: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type]
 // CHECK:STDOUT:       %.Self.as_wit: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit]
 // CHECK:STDOUT:       %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0]
 // CHECK:STDOUT:       %int_32: Core.IntLiteral = int_value 32 [template = constants.%int_32]
@@ -70,17 +74,26 @@ fn NotGenericF(U: I where .T == i32) {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %T: type = assoc_const_decl T [template]
-// CHECK:STDOUT:   %assoc0: %assoc_type = assoc_entity element0, %T [template = constants.%assoc0]
+// CHECK:STDOUT:   %T: type = assoc_const_decl @T [template] {
+// CHECK:STDOUT:     %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [template = constants.%assoc0]
+// CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .T = %assoc0
+// CHECK:STDOUT:   .T = @T.%assoc0
 // CHECK:STDOUT:   witness = (%T)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: generic assoc_const @T(@I.%Self: %I.type) {
+// CHECK:STDOUT:   assoc_const T:! type;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @NotGenericF(%U.param_patt: %I_where.type) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @T(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @T(constants.%I.facet) {}
+// CHECK:STDOUT:

+ 1 - 0
toolchain/diagnostics/diagnostic_kind.def

@@ -259,6 +259,7 @@ CARBON_DIAGNOSTIC_KIND(InterfaceUndefinedWithinDefinition)
 CARBON_DIAGNOSTIC_KIND(AssociatedConstantDifferentInRedecl)
 CARBON_DIAGNOSTIC_KIND(AssociatedConstantHere)
 CARBON_DIAGNOSTIC_KIND(AssociatedConstantMissingInRedecl)
+CARBON_DIAGNOSTIC_KIND(AssociatedConstantNotConstantAfterConversion)
 CARBON_DIAGNOSTIC_KIND(AssociatedFunctionHere)
 CARBON_DIAGNOSTIC_KIND(ExtendImplForall)
 CARBON_DIAGNOSTIC_KIND(ExtendImplOutsideClass)

+ 1 - 0
toolchain/sem_ir/BUILD

@@ -81,6 +81,7 @@ cc_library(
         "type_info.cpp",
     ],
     hdrs = [
+        "associated_constant.h",
         "builtin_function_kind.h",
         "class.h",
         "constant.h",

+ 53 - 0
toolchain/sem_ir/associated_constant.h

@@ -0,0 +1,53 @@
+// 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
+
+#ifndef CARBON_TOOLCHAIN_SEM_IR_ASSOCIATED_CONSTANT_H_
+#define CARBON_TOOLCHAIN_SEM_IR_ASSOCIATED_CONSTANT_H_
+
+#include "common/ostream.h"
+#include "toolchain/sem_ir/ids.h"
+
+namespace Carbon::SemIR {
+
+// An associated constant entity. For example:
+//
+//   interface I {
+//     let AssocConst:! type;
+//    }
+//
+// TODO: This overlaps a lot with EntityName and EntityWithParamsBase.
+// Investigate ways of factoring out the common parts.
+struct AssociatedConstant : public Printable<AssociatedConstant> {
+  auto Print(llvm::raw_ostream& out) const -> void {
+    out << "{"
+        << "name: " << name_id << ", parent_scope: " << parent_scope_id << "}";
+  }
+
+  // The following fields are set at the `:!` binding, when the
+  // `AssociatedConstant` is created.
+
+  // The entity's name.
+  NameId name_id;
+
+  // The parent scope.
+  NameScopeId parent_scope_id;
+
+  // The declaration of this associated constant.
+  InstId decl_id;
+
+  // The following fields are set at the `=` or `;`.
+
+  // Information about the generic. An associated constant is always
+  // parameterized by `Self`, so this is always present.
+  GenericId generic_id;
+
+  // The following fields are set at the `;`.
+
+  // The default value of the constant.
+  InstId default_value_id = InstId::None;
+};
+
+}  // namespace Carbon::SemIR
+
+#endif  // CARBON_TOOLCHAIN_SEM_IR_ASSOCIATED_CONSTANT_H_

+ 2 - 2
toolchain/sem_ir/entity_with_params_base.h

@@ -86,13 +86,13 @@ struct EntityWithParamsBase {
   // The following members always have values, and do not change throughout the
   // lifetime of the entity.
 
-  // The class name.
+  // The entity's name.
   NameId name_id;
 
   // The parent scope.
   NameScopeId parent_scope_id;
 
-  // If this is a generic function, information about the generic.
+  // If this is a generic entity, information about the generic.
   GenericId generic_id;
 
   // Parse tree bounds for the parameters, including both implicit and explicit

+ 10 - 0
toolchain/sem_ir/file.h

@@ -15,6 +15,7 @@
 #include "toolchain/base/value_store.h"
 #include "toolchain/base/yaml.h"
 #include "toolchain/parse/tree.h"
+#include "toolchain/sem_ir/associated_constant.h"
 #include "toolchain/sem_ir/class.h"
 #include "toolchain/sem_ir/constant.h"
 #include "toolchain/sem_ir/entity_name.h"
@@ -137,6 +138,12 @@ class File : public Printable<File> {
   auto interfaces() const -> const ValueStore<InterfaceId>& {
     return interfaces_;
   }
+  auto associated_constants() -> ValueStore<AssociatedConstantId>& {
+    return associated_constants_;
+  }
+  auto associated_constants() const -> const ValueStore<AssociatedConstantId>& {
+    return associated_constants_;
+  }
   auto facet_types() -> CanonicalValueStore<FacetTypeId>& {
     return facet_types_;
   }
@@ -246,6 +253,9 @@ class File : public Printable<File> {
   // Storage for interfaces.
   ValueStore<InterfaceId> interfaces_;
 
+  // Storage for associated constants.
+  ValueStore<AssociatedConstantId> associated_constants_;
+
   // Storage for facet types.
   CanonicalValueStore<FacetTypeId> facet_types_;
 

+ 58 - 8
toolchain/sem_ir/formatter.cpp

@@ -74,6 +74,10 @@ class FormatterImpl {
       FormatInterface(InterfaceId(i));
     }
 
+    for (int i : llvm::seq(sem_ir_->associated_constants().size())) {
+      FormatAssociatedConstant(AssociatedConstantId(i));
+    }
+
     for (int i : llvm::seq(sem_ir_->impls().size())) {
       FormatImpl(ImplId(i));
     }
@@ -181,11 +185,15 @@ class FormatterImpl {
 
   // Determines whether the specified entity should be included in the formatted
   // output.
-  auto ShouldFormatEntity(const EntityWithParamsBase& entity) -> bool {
-    if (!entity.latest_decl_id().has_value()) {
+  auto ShouldFormatEntity(SemIR::InstId decl_id) -> bool {
+    if (!decl_id.has_value()) {
       return true;
     }
-    return should_format_entity_(entity.latest_decl_id());
+    return should_format_entity_(decl_id);
+  }
+
+  auto ShouldFormatEntity(const EntityWithParamsBase& entity) -> bool {
+    return ShouldFormatEntity(entity.latest_decl_id());
   }
 
   // Begins a braced block. Writes an open brace, and prepares to insert a
@@ -327,6 +335,33 @@ class FormatterImpl {
     FormatEntityEnd(interface_info.generic_id);
   }
 
+  // Formats an associated constant entity.
+  auto FormatAssociatedConstant(AssociatedConstantId id) -> void {
+    const AssociatedConstant& assoc_const =
+        sem_ir_->associated_constants().Get(id);
+    if (!ShouldFormatEntity(assoc_const.decl_id)) {
+      return;
+    }
+
+    FormatEntityStart("assoc_const", assoc_const.decl_id,
+                      assoc_const.generic_id, id);
+
+    llvm::SaveAndRestore assoc_const_scope(scope_,
+                                           inst_namer_->GetScopeFor(id));
+
+    out_ << " ";
+    FormatName(assoc_const.name_id);
+    out_ << ":! ";
+    FormatArg(sem_ir_->insts().Get(assoc_const.decl_id).type_id());
+    if (assoc_const.default_value_id.has_value()) {
+      out_ << " = ";
+      FormatArg(assoc_const.default_value_id);
+    }
+    out_ << ";\n";
+
+    FormatEntityEnd(assoc_const.generic_id);
+  }
+
   // Formats a full impl.
   auto FormatImpl(ImplId id) -> void {
     const Impl& impl_info = sem_ir_->impls().Get(id);
@@ -528,12 +563,12 @@ class FormatterImpl {
   // Provides common formatting for entities, paired with FormatEntityEnd.
   template <typename IdT>
   auto FormatEntityStart(llvm::StringRef entity_kind,
-                         const EntityWithParamsBase& entity, IdT entity_id)
-      -> void {
+                         InstId first_owning_decl_id, GenericId generic_id,
+                         IdT entity_id) -> void {
     // If this entity was imported from a different IR, annotate the name of
     // that IR in the output before the `{` or `;`.
-    if (entity.first_owning_decl_id.has_value()) {
-      auto loc_id = sem_ir_->insts().GetLocId(entity.first_owning_decl_id);
+    if (first_owning_decl_id.has_value()) {
+      auto loc_id = sem_ir_->insts().GetLocId(first_owning_decl_id);
       if (loc_id.is_import_ir_inst_id()) {
         auto import_ir_id =
             sem_ir_->import_ir_insts().Get(loc_id.import_ir_inst_id()).ir_id;
@@ -543,12 +578,12 @@ class FormatterImpl {
       }
     }
 
-    auto generic_id = entity.generic_id;
     if (generic_id.has_value()) {
       FormatGenericStart(entity_kind, generic_id);
     }
 
     out_ << "\n";
+    after_open_brace_ = false;
     Indent();
     out_ << entity_kind;
 
@@ -560,6 +595,14 @@ class FormatterImpl {
     }
   }
 
+  template <typename IdT>
+  auto FormatEntityStart(llvm::StringRef entity_kind,
+                         const EntityWithParamsBase& entity, IdT entity_id)
+      -> void {
+    FormatEntityStart(entity_kind, entity.first_owning_decl_id,
+                      entity.generic_id, entity_id);
+  }
+
   // Provides common formatting for entities, paired with FormatEntityStart.
   auto FormatEntityEnd(GenericId generic_id) -> void {
     if (generic_id.has_value()) {
@@ -1015,6 +1058,13 @@ class FormatterImpl {
     FormatTrailingBlock(inst.decl_block_id);
   }
 
+  auto FormatInstRHS(AssociatedConstantDecl inst) -> void {
+    FormatArgs(inst.assoc_const_id);
+    llvm::SaveAndRestore assoc_const_scope(
+        scope_, inst_namer_->GetScopeFor(inst.assoc_const_id));
+    FormatTrailingBlock(inst.decl_block_id);
+  }
+
   auto FormatInstRHS(IntValue inst) -> void {
     out_ << " ";
     sem_ir_->ints()

Некоторые файлы не были показаны из-за большого количества измененных файлов