Bladeren bron

Rebuild all constants in the eval block. (#4155)

Instead of reusing instructions from the generic entity in the eval
block, rebuild constants in the same way we rebuild types. The previous
attempt to not rebuild these constants assumed that every constant used
in a generic would be built in that generic, and not referenced directly
or referenced from some enclosing scope, which isn't true in practice
and is a fragile assumption in any case.

We could add back some reuse of instructions from the generic -- if we
happen to see the right instruction to build a constant, we could
opportunistically reuse it -- but given the complexity added by doing
so, I'm not pursuing that here.

Now that the eval block for a generic consists of instructions uniquely
owned by that generic, rather than often being shared with another
entity, include the generic in the formatted SemIR output. I'm using the
same scope name for the generic object itself as for the parameterized
class / function / interface, because there are very frequently
references between them and this keeps the IR simpler and more readable,
and avoids needing to invent a second name for the scope.
Richard Smith 1 jaar geleden
bovenliggende
commit
fc8e686607
96 gewijzigde bestanden met toevoegingen van 3024 en 2371 verwijderingen
  1. 71 36
      toolchain/check/generic.cpp
  2. 23 17
      toolchain/check/testdata/array/generic_empty.carbon
  3. 54 44
      toolchain/check/testdata/basics/no_prelude/raw_ir.carbon
  4. 25 20
      toolchain/check/testdata/builtins/int/make_type_signed.carbon
  5. 25 20
      toolchain/check/testdata/builtins/int/make_type_unsigned.carbon
  6. 55 39
      toolchain/check/testdata/class/fail_generic_method.carbon
  7. 111 66
      toolchain/check/testdata/class/generic/basic.carbon
  8. 74 56
      toolchain/check/testdata/class/generic/call.carbon
  9. 68 54
      toolchain/check/testdata/class/generic/fail_todo_use.carbon
  10. 95 75
      toolchain/check/testdata/class/generic/field.carbon
  11. 110 99
      toolchain/check/testdata/class/generic/import.carbon
  12. 74 56
      toolchain/check/testdata/class/generic/member_inline.carbon
  13. 238 174
      toolchain/check/testdata/class/generic/member_out_of_line.carbon
  14. 122 88
      toolchain/check/testdata/class/generic/redeclare.carbon
  15. 89 63
      toolchain/check/testdata/class/generic/self.carbon
  16. 51 38
      toolchain/check/testdata/class/generic_method.carbon
  17. 4 4
      toolchain/check/testdata/class/syntactic_merge_literal.carbon
  18. 19 15
      toolchain/check/testdata/eval/fail_symbolic.carbon
  19. 34 25
      toolchain/check/testdata/eval/symbolic.carbon
  20. 20 18
      toolchain/check/testdata/function/builtin/method.carbon
  21. 21 19
      toolchain/check/testdata/function/builtin/no_prelude/call_from_operator.carbon
  22. 9 7
      toolchain/check/testdata/function/generic/fail_todo_param_in_type.carbon
  23. 25 19
      toolchain/check/testdata/function/generic/no_prelude/fail_type_param_mismatch.carbon
  24. 41 0
      toolchain/check/testdata/function/generic/no_prelude/forward_decl.carbon
  25. 26 20
      toolchain/check/testdata/function/generic/no_prelude/indirect_generic_type.carbon
  26. 23 18
      toolchain/check/testdata/function/generic/no_prelude/type_param.carbon
  27. 20 16
      toolchain/check/testdata/function/generic/no_prelude/type_param_scope.carbon
  28. 139 99
      toolchain/check/testdata/function/generic/redeclare.carbon
  29. 17 15
      toolchain/check/testdata/impl/compound.carbon
  30. 5 5
      toolchain/check/testdata/impl/extend_impl.carbon
  31. 12 10
      toolchain/check/testdata/impl/fail_call_invalid.carbon
  32. 47 36
      toolchain/check/testdata/impl/fail_extend_impl_forall.carbon
  33. 12 11
      toolchain/check/testdata/impl/fail_extend_partially_defined_interface.carbon
  34. 5 5
      toolchain/check/testdata/impl/fail_impl_as_scope.carbon
  35. 70 64
      toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon
  36. 5 5
      toolchain/check/testdata/impl/impl_as.carbon
  37. 12 11
      toolchain/check/testdata/impl/impl_forall.carbon
  38. 5 5
      toolchain/check/testdata/impl/lookup/alias.carbon
  39. 5 5
      toolchain/check/testdata/impl/lookup/fail_alias_impl_not_found.carbon
  40. 5 5
      toolchain/check/testdata/impl/lookup/fail_todo_undefined_impl.carbon
  41. 5 5
      toolchain/check/testdata/impl/lookup/import.carbon
  42. 12 10
      toolchain/check/testdata/impl/lookup/instance_method.carbon
  43. 5 5
      toolchain/check/testdata/impl/lookup/no_prelude/import.carbon
  44. 5 5
      toolchain/check/testdata/impl/no_prelude/basic.carbon
  45. 21 19
      toolchain/check/testdata/impl/no_prelude/import_self.carbon
  46. 10 8
      toolchain/check/testdata/impl/no_prelude/self_in_class.carbon
  47. 70 63
      toolchain/check/testdata/impl/no_prelude/self_in_signature.carbon
  48. 5 5
      toolchain/check/testdata/index/fail_negative_indexing.carbon
  49. 12 11
      toolchain/check/testdata/interface/fail_todo_define_default_fn_inline.carbon
  50. 10 10
      toolchain/check/testdata/interface/fail_todo_define_default_fn_out_of_line.carbon
  51. 17 13
      toolchain/check/testdata/interface/no_prelude/as_type_of_type.carbon
  52. 4 4
      toolchain/check/testdata/interface/no_prelude/basic.carbon
  53. 20 19
      toolchain/check/testdata/interface/no_prelude/default_fn.carbon
  54. 24 22
      toolchain/check/testdata/interface/no_prelude/fail_add_member_outside_definition.carbon
  55. 54 40
      toolchain/check/testdata/interface/no_prelude/fail_generic_redeclaration.carbon
  56. 9 9
      toolchain/check/testdata/interface/no_prelude/fail_lookup_undefined.carbon
  57. 5 5
      toolchain/check/testdata/interface/no_prelude/fail_member_lookup.carbon
  58. 9 9
      toolchain/check/testdata/interface/no_prelude/fail_redeclare_member.carbon
  59. 36 28
      toolchain/check/testdata/interface/no_prelude/fail_todo_facet_lookup.carbon
  60. 82 63
      toolchain/check/testdata/interface/no_prelude/fail_todo_generic_default_fn.carbon
  61. 16 14
      toolchain/check/testdata/interface/no_prelude/fail_todo_modifiers.carbon
  62. 138 112
      toolchain/check/testdata/interface/no_prelude/generic.carbon
  63. 16 12
      toolchain/check/testdata/interface/no_prelude/generic_binding_after_assoc_const.carbon
  64. 33 28
      toolchain/check/testdata/interface/no_prelude/generic_import.carbon
  65. 9 9
      toolchain/check/testdata/interface/no_prelude/import.carbon
  66. 15 13
      toolchain/check/testdata/interface/no_prelude/self.carbon
  67. 12 11
      toolchain/check/testdata/interface/todo_define_not_default.carbon
  68. 12 8
      toolchain/check/testdata/namespace/fail_params.carbon
  69. 1 1
      toolchain/check/testdata/operators/builtin/fail_type_mismatch_once.carbon
  70. 1 1
      toolchain/check/testdata/operators/builtin/fail_unimplemented_op.carbon
  71. 7 7
      toolchain/check/testdata/operators/overloaded/add.carbon
  72. 12 12
      toolchain/check/testdata/operators/overloaded/bit_and.carbon
  73. 1 1
      toolchain/check/testdata/operators/overloaded/bit_complement.carbon
  74. 12 12
      toolchain/check/testdata/operators/overloaded/bit_or.carbon
  75. 12 12
      toolchain/check/testdata/operators/overloaded/bit_xor.carbon
  76. 6 6
      toolchain/check/testdata/operators/overloaded/dec.carbon
  77. 12 12
      toolchain/check/testdata/operators/overloaded/div.carbon
  78. 12 12
      toolchain/check/testdata/operators/overloaded/eq.carbon
  79. 12 12
      toolchain/check/testdata/operators/overloaded/fail_assign_non_ref.carbon
  80. 16 16
      toolchain/check/testdata/operators/overloaded/fail_no_impl.carbon
  81. 7 7
      toolchain/check/testdata/operators/overloaded/fail_no_impl_for_arg.carbon
  82. 6 6
      toolchain/check/testdata/operators/overloaded/inc.carbon
  83. 12 12
      toolchain/check/testdata/operators/overloaded/left_shift.carbon
  84. 12 12
      toolchain/check/testdata/operators/overloaded/mod.carbon
  85. 12 12
      toolchain/check/testdata/operators/overloaded/mul.carbon
  86. 6 6
      toolchain/check/testdata/operators/overloaded/negate.carbon
  87. 35 35
      toolchain/check/testdata/operators/overloaded/ordered.carbon
  88. 12 12
      toolchain/check/testdata/operators/overloaded/right_shift.carbon
  89. 12 12
      toolchain/check/testdata/operators/overloaded/sub.carbon
  90. 22 18
      toolchain/check/testdata/packages/no_prelude/fail_export_name_params.carbon
  91. 12 8
      toolchain/check/testdata/return/fail_let_in_type.carbon
  92. 36 33
      toolchain/check/testdata/struct/import.carbon
  93. 36 33
      toolchain/check/testdata/tuples/import.carbon
  94. 111 97
      toolchain/sem_ir/formatter.cpp
  95. 32 16
      toolchain/sem_ir/inst_namer.cpp
  96. 25 6
      toolchain/sem_ir/inst_namer.h

+ 71 - 36
toolchain/check/generic.cpp

@@ -33,7 +33,7 @@ auto StartGenericDefinition(Context& context) -> void {
 // each instance of the generic. Forms and returns a corresponding symbolic
 // constant ID that refers to the substituted value of that instruction in each
 // instance of the generic.
-static auto AddGenericConstantToEvalBlock(
+static auto AddGenericConstantInstToEvalBlock(
     Context& context, SemIR::GenericId generic_id,
     SemIR::GenericInstIndex::Region region, SemIR::InstId const_inst_id,
     SemIR::InstId generic_inst_id) -> SemIR::ConstantId {
@@ -45,11 +45,12 @@ static auto AddGenericConstantToEvalBlock(
 }
 
 namespace {
-// Substitution callbacks to rebuild a generic type in the eval block for a
+// Substitution callbacks to rebuild a generic constant in the eval block for a
 // generic region.
-class RebuildGenericTypeInEvalBlockCallbacks final : public SubstInstCallbacks {
+class RebuildGenericConstantInEvalBlockCallbacks final
+    : public SubstInstCallbacks {
  public:
-  RebuildGenericTypeInEvalBlockCallbacks(
+  RebuildGenericConstantInEvalBlockCallbacks(
       Context& context, SemIR::GenericId generic_id,
       SemIR::GenericInstIndex::Region region,
       Map<SemIR::InstId, SemIR::InstId>& constants_in_generic)
@@ -59,22 +60,36 @@ class RebuildGenericTypeInEvalBlockCallbacks final : public SubstInstCallbacks {
         constants_in_generic_(constants_in_generic) {}
 
   // Check for instructions for which we already have a mapping into the eval
-  // block, and substitute them for the instructions in the eval block. Note
-  // that this will at least include mappings for the `BindSymbolicName`
-  // instructions that introduce our parameters.
+  // block, and substitute them for the instructions in the eval block.
   auto Subst(SemIR::InstId& inst_id) const -> bool override {
-    if (context_.constant_values().Get(inst_id).is_template()) {
-      // This instruction is a template constant, so can't contain any
-      // bindings that need to be substituted.
+    auto const_id = context_.constant_values().Get(inst_id);
+    if (!const_id.is_symbolic()) {
+      // This instruction doesn't have a symbolic constant value, so can't
+      // contain any bindings that need to be substituted.
       return true;
     }
 
     // If this instruction is in the map, return the known result.
-    if (auto result = constants_in_generic_.Lookup(inst_id)) {
-      inst_id = result.value();
+    if (auto result = constants_in_generic_.Lookup(
+            context_.constant_values().GetInstId(const_id))) {
+      // In order to reuse instructions from the generic as often as possible,
+      // keep this instruction as-is if it already has the desired symbolic
+      // constant value.
+      if (const_id != context_.constant_values().Get(result.value())) {
+        inst_id = result.value();
+      }
       CARBON_CHECK(inst_id.is_valid());
       return true;
     }
+
+    // If the instruction is a symbolic binding, build a version in the eval
+    // block.
+    if (auto binding =
+            context_.insts().TryGetAs<SemIR::BindSymbolicName>(inst_id)) {
+      inst_id = Rebuild(inst_id, *binding);
+      return true;
+    }
+
     return false;
   }
 
@@ -82,18 +97,22 @@ class RebuildGenericTypeInEvalBlockCallbacks final : public SubstInstCallbacks {
   // constant.
   auto Rebuild(SemIR::InstId orig_inst_id, SemIR::Inst new_inst) const
       -> SemIR::InstId override {
-    // TODO: Add a function on `Context` to add the instruction without
-    // inserting it into the dependent instructions list or computing a constant
-    // value for it.
-    auto inst_id = context_.sem_ir().insts().AddInNoBlock(
-        SemIR::LocIdAndInst::NoLoc(new_inst));
-    auto result = constants_in_generic_.Insert(orig_inst_id, inst_id);
-    CARBON_CHECK(result.is_inserted())
-        << "Substituted into an instruction that was already in the map.";
-    auto const_id = AddGenericConstantToEvalBlock(
-        context_, generic_id_, region_, orig_inst_id, inst_id);
-    context_.constant_values().Set(inst_id, const_id);
-    return inst_id;
+    auto const_inst_id =
+        context_.constant_values().GetConstantInstId(orig_inst_id);
+    // We might already have an instruction in the eval block if a transitive
+    // operand of this instruction has the same constant value.
+    auto result = constants_in_generic_.Insert(const_inst_id, [&] {
+      // TODO: Add a function on `Context` to add the instruction without
+      // inserting it into the dependent instructions list or computing a
+      // constant value for it.
+      auto inst_id = context_.sem_ir().insts().AddInNoBlock(
+          SemIR::LocIdAndInst::NoLoc(new_inst));
+      auto const_id = AddGenericConstantInstToEvalBlock(
+          context_, generic_id_, region_, const_inst_id, inst_id);
+      context_.constant_values().Set(inst_id, const_id);
+      return inst_id;
+    });
+    return result.value();
   }
 
  private:
@@ -117,11 +136,33 @@ static auto AddGenericTypeToEvalBlock(
   // block.
   auto type_inst_id =
       SubstInst(context, context.types().GetInstId(type_id),
-                RebuildGenericTypeInEvalBlockCallbacks(
+                RebuildGenericConstantInEvalBlockCallbacks(
                     context, generic_id, region, constants_in_generic));
   return context.GetTypeIdForTypeInst(type_inst_id);
 }
 
+// Adds instructions to compute the substituted value of `inst_id` in each
+// instance of a generic into the eval block for the generic, which is the
+// current instruction block. Returns a symbolic constant instruction ID that
+// refers to the substituted constant value in each instance of the generic.
+static auto AddGenericConstantToEvalBlock(
+    Context& context, SemIR::GenericId generic_id,
+    SemIR::GenericInstIndex::Region region,
+    Map<SemIR::InstId, SemIR::InstId>& constants_in_generic,
+    SemIR::InstId inst_id) -> SemIR::ConstantId {
+  // Substitute into the constant value and rebuild it in the eval block if
+  // we've not encountered it before.
+  auto const_inst_id = context.constant_values().GetConstantInstId(inst_id);
+  auto new_inst_id =
+      SubstInst(context, const_inst_id,
+                RebuildGenericConstantInEvalBlockCallbacks(
+                    context, generic_id, region, constants_in_generic));
+  CARBON_CHECK(new_inst_id != const_inst_id)
+      << "Did not apply any substitutions to symbolic constant "
+      << context.insts().Get(const_inst_id);
+  return context.constant_values().Get(new_inst_id);
+}
+
 // Builds and returns a block of instructions whose constant values need to be
 // evaluated in order to resolve a generic instance.
 static auto MakeGenericEvalBlock(Context& context, SemIR::GenericId generic_id,
@@ -173,17 +214,11 @@ static auto MakeGenericEvalBlock(Context& context, SemIR::GenericId generic_id,
     // eventual evaluation.
     if ((dep_kind & GenericRegionStack::DependencyKind::SymbolicConstant) !=
         GenericRegionStack::DependencyKind::None) {
-      auto const_inst_id = context.constant_values().GetConstantInstId(inst_id);
-
-      // Create a new symbolic constant representing this instruction in this
-      // generic, if it doesn't already exist.
-      auto result = constants_in_generic.Insert(const_inst_id, inst_id);
-      auto const_id =
-          result.is_inserted()
-              ? AddGenericConstantToEvalBlock(context, generic_id, region,
-                                              const_inst_id, inst_id)
-              : context.constant_values().Get(result.value());
-      context.constant_values().Set(inst_id, const_id);
+      // Update the constant value to refer to this generic.
+      context.constant_values().Set(
+          inst_id,
+          AddGenericConstantToEvalBlock(context, generic_id, region,
+                                        constants_in_generic, inst_id));
     }
   }
 

+ 23 - 17
toolchain/check/testdata/array/generic_empty.carbon

@@ -43,27 +43,33 @@ fn G(T:! type) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [template = constants.%G] {
 // CHECK:STDOUT:     %T.loc11_6.1: type = param T
-// CHECK:STDOUT:     @G.%T: type = bind_symbolic_name T 0, %T.loc11_6.1 [symbolic = @G.%T (constants.%T)]
+// CHECK:STDOUT:     @G.%T.loc11: type = bind_symbolic_name T 0, %T.loc11_6.1 [symbolic = @G.%T.1 (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @G(%T: type)
-// CHECK:STDOUT:     generic [%T: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %T.ref: type = name_ref T, %T [symbolic = %T (constants.%T)]
-// CHECK:STDOUT:   %.loc13_16: i32 = int_literal 0 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc13_17: type = array_type %.loc13_16, %T [symbolic = %.loc13_17 (constants.%.3)]
-// CHECK:STDOUT:   %arr.var: ref @G.%.loc13_17 (%.3) = var arr
-// CHECK:STDOUT:   %arr: ref @G.%.loc13_17 (%.3) = bind_name arr, %arr.var
-// CHECK:STDOUT:   %.loc13_22.1: %.1 = tuple_literal ()
-// CHECK:STDOUT:   %.loc13_22.2: init @G.%.loc13_17 (%.3) = array_init () to %arr.var [symbolic = %.loc13_22.2 (constants.%array)]
-// CHECK:STDOUT:   %.loc13_23: init @G.%.loc13_17 (%.3) = converted %.loc13_22.1, %.loc13_22.2 [symbolic = %.loc13_22.2 (constants.%array)]
-// CHECK:STDOUT:   assign %arr.var, %.loc13_23
-// CHECK:STDOUT:   return
+// CHECK:STDOUT: generic fn @G(%T.loc11: type) {
+// CHECK:STDOUT:   %T.1: type = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1: type = array_type constants.%.2, @G.%T.1 (%T) [symbolic = %.1 (constants.%.3)]
+// CHECK:STDOUT:   %array: @G.%.1 (%.3) = tuple_value () [symbolic = %array (constants.%array)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%T.loc11: type) {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %T.ref: type = name_ref T, %T.loc11 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:     %.loc13_16: i32 = int_literal 0 [template = constants.%.2]
+// CHECK:STDOUT:     %.loc13_17: type = array_type %.loc13_16, %T [symbolic = %.1 (constants.%.3)]
+// CHECK:STDOUT:     %arr.var: ref @G.%.1 (%.3) = var arr
+// CHECK:STDOUT:     %arr: ref @G.%.1 (%.3) = bind_name arr, %arr.var
+// CHECK:STDOUT:     %.loc13_22.1: %.1 = tuple_literal ()
+// CHECK:STDOUT:     %.loc13_22.2: init @G.%.1 (%.3) = array_init () to %arr.var [symbolic = %array (constants.%array)]
+// CHECK:STDOUT:     %.loc13_23: init @G.%.1 (%.3) = converted %.loc13_22.1, %.loc13_22.2 [symbolic = %array (constants.%array)]
+// CHECK:STDOUT:     assign %arr.var, %.loc13_23
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%G.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @G.%T => constants.%T
+// CHECK:STDOUT: specific @G(constants.%T) {
+// CHECK:STDOUT:   %T.1 => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 54 - 44
toolchain/check/testdata/basics/no_prelude/raw_ir.carbon

@@ -38,13 +38,13 @@ fn Foo[T:! type](n: T) -> (T, ()) {
 // CHECK:STDOUT:     typeTypeType:    {kind: copy, type: typeTypeType}
 // CHECK:STDOUT:     typeError:       {kind: copy, type: typeError}
 // CHECK:STDOUT:     'type(instNamespaceType)': {kind: copy, type: type(instNamespaceType)}
-// CHECK:STDOUT:     'type(inst+17)':   {kind: none, type: type(inst+8)}
+// CHECK:STDOUT:     'type(inst+20)':   {kind: none, type: type(inst+8)}
 // CHECK:STDOUT:     'type(inst+8)':    {kind: none, type: type(inst+8)}
 // CHECK:STDOUT:     'type(symbolicConstant0)': {kind: copy, type: type(symbolicConstant0)}
-// CHECK:STDOUT:     'type(symbolicConstant1)': {kind: pointer, type: type(symbolicConstant4)}
-// CHECK:STDOUT:     'type(symbolicConstant4)': {kind: copy, type: type(symbolicConstant4)}
+// CHECK:STDOUT:     'type(symbolicConstant1)': {kind: pointer, type: type(symbolicConstant5)}
+// CHECK:STDOUT:     'type(symbolicConstant5)': {kind: copy, type: type(symbolicConstant5)}
 // CHECK:STDOUT:     'type(symbolicConstant2)': {kind: copy, type: type(symbolicConstant2)}
-// CHECK:STDOUT:     'type(symbolicConstant3)': {kind: pointer, type: type(symbolicConstant4)}
+// CHECK:STDOUT:     'type(symbolicConstant3)': {kind: pointer, type: type(symbolicConstant5)}
 // CHECK:STDOUT:   type_blocks:
 // CHECK:STDOUT:     type_block0:     {}
 // CHECK:STDOUT:     type_block1:
@@ -53,6 +53,9 @@ fn Foo[T:! type](n: T) -> (T, ()) {
 // CHECK:STDOUT:     type_block2:
 // CHECK:STDOUT:       0:               type(symbolicConstant0)
 // CHECK:STDOUT:       1:               type(inst+8)
+// CHECK:STDOUT:     type_block3:
+// CHECK:STDOUT:       0:               type(symbolicConstant2)
+// CHECK:STDOUT:       1:               type(inst+8)
 // CHECK:STDOUT:   insts:
 // CHECK:STDOUT:     'inst+0':          {kind: Namespace, arg0: name_scope0, arg1: inst<invalid>, type: type(instNamespaceType)}
 // CHECK:STDOUT:     'inst+1':          {kind: Param, arg0: name1, type: typeTypeType}
@@ -70,22 +73,25 @@ fn Foo[T:! type](n: T) -> (T, ()) {
 // CHECK:STDOUT:     'inst+13':         {kind: TupleType, arg0: type_block2, type: typeTypeType}
 // CHECK:STDOUT:     'inst+14':         {kind: Converted, arg0: inst+11, arg1: inst+13, type: typeTypeType}
 // CHECK:STDOUT:     'inst+15':         {kind: VarStorage, arg0: nameReturnSlot, type: type(symbolicConstant1)}
-// CHECK:STDOUT:     'inst+16':         {kind: FunctionDecl, arg0: function0, arg1: block7, type: type(inst+17)}
-// CHECK:STDOUT:     'inst+17':         {kind: FunctionType, arg0: function0, type: typeTypeType}
-// CHECK:STDOUT:     'inst+18':         {kind: StructValue, arg0: empty, type: type(inst+17)}
-// CHECK:STDOUT:     'inst+19':         {kind: PointerType, arg0: type(symbolicConstant1), type: typeTypeType}
-// CHECK:STDOUT:     'inst+20':         {kind: NameRef, arg0: name2, arg1: inst+6, type: type(symbolicConstant2)}
-// CHECK:STDOUT:     'inst+21':         {kind: TupleLiteral, arg0: empty, type: type(inst+8)}
-// CHECK:STDOUT:     'inst+22':         {kind: TupleLiteral, arg0: block13, type: type(symbolicConstant3)}
-// CHECK:STDOUT:     'inst+23':         {kind: TupleAccess, arg0: inst+15, arg1: element0, type: type(symbolicConstant2)}
-// CHECK:STDOUT:     'inst+24':         {kind: InitializeFrom, arg0: inst+20, arg1: inst+23, type: type(symbolicConstant2)}
-// CHECK:STDOUT:     'inst+25':         {kind: TupleAccess, arg0: inst+15, arg1: element1, type: type(inst+8)}
-// CHECK:STDOUT:     'inst+26':         {kind: TupleInit, arg0: empty, arg1: inst+25, type: type(inst+8)}
-// CHECK:STDOUT:     'inst+27':         {kind: TupleValue, arg0: block15, type: type(inst+8)}
-// CHECK:STDOUT:     'inst+28':         {kind: Converted, arg0: inst+21, arg1: inst+26, type: type(inst+8)}
-// CHECK:STDOUT:     'inst+29':         {kind: TupleInit, arg0: block14, arg1: inst+15, type: type(symbolicConstant3)}
-// CHECK:STDOUT:     'inst+30':         {kind: Converted, arg0: inst+22, arg1: inst+29, type: type(symbolicConstant3)}
-// CHECK:STDOUT:     'inst+31':         {kind: ReturnExpr, arg0: inst+30, arg1: inst+15}
+// CHECK:STDOUT:     'inst+16':         {kind: FunctionDecl, arg0: function0, arg1: block7, type: type(inst+20)}
+// CHECK:STDOUT:     'inst+17':         {kind: BindSymbolicName, arg0: entity_name0, arg1: inst<invalid>, type: typeTypeType}
+// CHECK:STDOUT:     'inst+18':         {kind: TupleType, arg0: type_block3, type: typeTypeType}
+// CHECK:STDOUT:     'inst+19':         {kind: TupleType, arg0: type_block3, type: typeTypeType}
+// CHECK:STDOUT:     'inst+20':         {kind: FunctionType, arg0: function0, type: typeTypeType}
+// CHECK:STDOUT:     'inst+21':         {kind: StructValue, arg0: empty, type: type(inst+20)}
+// CHECK:STDOUT:     'inst+22':         {kind: PointerType, arg0: type(symbolicConstant1), type: typeTypeType}
+// CHECK:STDOUT:     'inst+23':         {kind: NameRef, arg0: name2, arg1: inst+6, type: type(symbolicConstant2)}
+// CHECK:STDOUT:     'inst+24':         {kind: TupleLiteral, arg0: empty, type: type(inst+8)}
+// CHECK:STDOUT:     'inst+25':         {kind: TupleLiteral, arg0: block13, type: type(symbolicConstant3)}
+// CHECK:STDOUT:     'inst+26':         {kind: TupleAccess, arg0: inst+15, arg1: element0, type: type(symbolicConstant2)}
+// CHECK:STDOUT:     'inst+27':         {kind: InitializeFrom, arg0: inst+23, arg1: inst+26, type: type(symbolicConstant2)}
+// CHECK:STDOUT:     'inst+28':         {kind: TupleAccess, arg0: inst+15, arg1: element1, type: type(inst+8)}
+// CHECK:STDOUT:     'inst+29':         {kind: TupleInit, arg0: empty, arg1: inst+28, type: type(inst+8)}
+// CHECK:STDOUT:     'inst+30':         {kind: TupleValue, arg0: block15, type: type(inst+8)}
+// CHECK:STDOUT:     'inst+31':         {kind: Converted, arg0: inst+24, arg1: inst+29, type: type(inst+8)}
+// CHECK:STDOUT:     'inst+32':         {kind: TupleInit, arg0: block14, arg1: inst+15, type: type(symbolicConstant3)}
+// CHECK:STDOUT:     'inst+33':         {kind: Converted, arg0: inst+25, arg1: inst+32, type: type(symbolicConstant3)}
+// CHECK:STDOUT:     'inst+34':         {kind: ReturnExpr, arg0: inst+33, arg1: inst+15}
 // CHECK:STDOUT:   constant_values:
 // CHECK:STDOUT:     'inst+0':          templateConstant(inst+0)
 // CHECK:STDOUT:     'inst+2':          symbolicConstant2
@@ -97,19 +103,23 @@ fn Foo[T:! type](n: T) -> (T, ()) {
 // CHECK:STDOUT:     'inst+12':         templateConstant(inst+8)
 // CHECK:STDOUT:     'inst+13':         symbolicConstant1
 // CHECK:STDOUT:     'inst+14':         symbolicConstant3
-// CHECK:STDOUT:     'inst+16':         templateConstant(inst+18)
-// CHECK:STDOUT:     'inst+17':         templateConstant(inst+17)
-// CHECK:STDOUT:     'inst+18':         templateConstant(inst+18)
+// CHECK:STDOUT:     'inst+16':         templateConstant(inst+21)
+// CHECK:STDOUT:     'inst+17':         symbolicConstant2
+// CHECK:STDOUT:     'inst+18':         symbolicConstant3
 // CHECK:STDOUT:     'inst+19':         symbolicConstant4
-// CHECK:STDOUT:     'inst+26':         templateConstant(inst+27)
-// CHECK:STDOUT:     'inst+27':         templateConstant(inst+27)
-// CHECK:STDOUT:     'inst+28':         templateConstant(inst+27)
+// CHECK:STDOUT:     'inst+20':         templateConstant(inst+20)
+// CHECK:STDOUT:     'inst+21':         templateConstant(inst+21)
+// CHECK:STDOUT:     'inst+22':         symbolicConstant5
+// CHECK:STDOUT:     'inst+29':         templateConstant(inst+30)
+// CHECK:STDOUT:     'inst+30':         templateConstant(inst+30)
+// CHECK:STDOUT:     'inst+31':         templateConstant(inst+30)
 // CHECK:STDOUT:   symbolic_constants:
 // CHECK:STDOUT:     symbolicConstant0: {inst: inst+3, generic: generic<invalid>, index: genericInst<invalid>}
 // CHECK:STDOUT:     symbolicConstant1: {inst: inst+13, generic: generic<invalid>, index: genericInst<invalid>}
 // CHECK:STDOUT:     symbolicConstant2: {inst: inst+3, generic: generic0, index: genericInstInDecl0}
 // CHECK:STDOUT:     symbolicConstant3: {inst: inst+13, generic: generic0, index: genericInstInDecl1}
 // CHECK:STDOUT:     symbolicConstant4: {inst: inst+19, generic: generic<invalid>, index: genericInst<invalid>}
+// CHECK:STDOUT:     symbolicConstant5: {inst: inst+22, generic: generic<invalid>, index: genericInst<invalid>}
 // CHECK:STDOUT:   inst_blocks:
 // CHECK:STDOUT:     empty:           {}
 // CHECK:STDOUT:     exports:
@@ -138,31 +148,31 @@ fn Foo[T:! type](n: T) -> (T, ()) {
 // CHECK:STDOUT:     block8:
 // CHECK:STDOUT:       0:               inst+2
 // CHECK:STDOUT:     block9:
-// CHECK:STDOUT:       0:               inst+2
-// CHECK:STDOUT:       1:               inst+14
+// CHECK:STDOUT:       0:               inst+17
+// CHECK:STDOUT:       1:               inst+18
 // CHECK:STDOUT:     block10:
 // CHECK:STDOUT:       0:               inst+3
 // CHECK:STDOUT:     block11:
 // CHECK:STDOUT:       0:               inst+3
-// CHECK:STDOUT:       1:               inst+13
+// CHECK:STDOUT:       1:               inst+19
 // CHECK:STDOUT:     block12:
-// CHECK:STDOUT:       0:               inst+20
-// CHECK:STDOUT:       1:               inst+21
-// CHECK:STDOUT:       2:               inst+22
-// CHECK:STDOUT:       3:               inst+23
-// CHECK:STDOUT:       4:               inst+24
-// CHECK:STDOUT:       5:               inst+25
-// CHECK:STDOUT:       6:               inst+26
-// CHECK:STDOUT:       7:               inst+28
-// CHECK:STDOUT:       8:               inst+29
-// CHECK:STDOUT:       9:               inst+30
-// CHECK:STDOUT:       10:              inst+31
+// CHECK:STDOUT:       0:               inst+23
+// CHECK:STDOUT:       1:               inst+24
+// CHECK:STDOUT:       2:               inst+25
+// CHECK:STDOUT:       3:               inst+26
+// CHECK:STDOUT:       4:               inst+27
+// CHECK:STDOUT:       5:               inst+28
+// CHECK:STDOUT:       6:               inst+29
+// CHECK:STDOUT:       7:               inst+31
+// CHECK:STDOUT:       8:               inst+32
+// CHECK:STDOUT:       9:               inst+33
+// CHECK:STDOUT:       10:              inst+34
 // CHECK:STDOUT:     block13:
-// CHECK:STDOUT:       0:               inst+20
-// CHECK:STDOUT:       1:               inst+21
+// CHECK:STDOUT:       0:               inst+23
+// CHECK:STDOUT:       1:               inst+24
 // CHECK:STDOUT:     block14:
-// CHECK:STDOUT:       0:               inst+24
-// CHECK:STDOUT:       1:               inst+28
+// CHECK:STDOUT:       0:               inst+27
+// CHECK:STDOUT:       1:               inst+31
 // CHECK:STDOUT:     block15:         {}
 // CHECK:STDOUT:     block16:
 // CHECK:STDOUT:       0:               inst+0

+ 25 - 20
toolchain/check/testdata/builtins/int/make_type_signed.carbon

@@ -193,19 +193,19 @@ var m: Int(1000000000);
 // CHECK:STDOUT:     %.loc14_17.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:     %.loc14_17.2: type = converted %int.make_type_32, %.loc14_17.1 [template = i32]
 // CHECK:STDOUT:     %N.loc14_13.1: i32 = param N
-// CHECK:STDOUT:     @Symbolic.%N: i32 = bind_symbolic_name N 0, %N.loc14_13.1 [symbolic = @Symbolic.%N (constants.%N)]
+// CHECK:STDOUT:     @Symbolic.%N.loc14: i32 = bind_symbolic_name N 0, %N.loc14_13.1 [symbolic = @Symbolic.%N.1 (constants.%N)]
 // CHECK:STDOUT:     %Int.ref.loc14_25: %Int.type = name_ref Int, imports.%import_ref.1 [template = constants.%Int]
-// CHECK:STDOUT:     %N.ref.loc14_29: i32 = name_ref N, @Symbolic.%N [symbolic = @Symbolic.%N (constants.%N)]
-// CHECK:STDOUT:     %int.make_type_signed.loc14_28: init type = call %Int.ref.loc14_25(%N.ref.loc14_29) [symbolic = %int.make_type_signed.loc14_28 (constants.%.6)]
-// CHECK:STDOUT:     %.loc14_30.1: type = value_of_initializer %int.make_type_signed.loc14_28 [symbolic = %int.make_type_signed.loc14_28 (constants.%.6)]
-// CHECK:STDOUT:     %.loc14_30.2: type = converted %int.make_type_signed.loc14_28, %.loc14_30.1 [symbolic = %int.make_type_signed.loc14_28 (constants.%.6)]
-// CHECK:STDOUT:     %x.loc14_22.1: file.%int.make_type_signed.loc14_28 (%.6) = param x
-// CHECK:STDOUT:     @Symbolic.%x: file.%int.make_type_signed.loc14_28 (%.6) = bind_name x, %x.loc14_22.1
+// CHECK:STDOUT:     %N.ref.loc14_29: i32 = name_ref N, @Symbolic.%N.loc14 [symbolic = @Symbolic.%N.1 (constants.%N)]
+// CHECK:STDOUT:     %int.make_type_signed.loc14_28: init type = call %Int.ref.loc14_25(%N.ref.loc14_29) [symbolic = @Symbolic.%.1 (constants.%.6)]
+// CHECK:STDOUT:     %.loc14_30.1: type = value_of_initializer %int.make_type_signed.loc14_28 [symbolic = @Symbolic.%.1 (constants.%.6)]
+// CHECK:STDOUT:     %.loc14_30.2: type = converted %int.make_type_signed.loc14_28, %.loc14_30.1 [symbolic = @Symbolic.%.1 (constants.%.6)]
+// CHECK:STDOUT:     %x.loc14_22.1: @Symbolic.%.1 (%.6) = param x
+// CHECK:STDOUT:     @Symbolic.%x: @Symbolic.%.1 (%.6) = bind_name x, %x.loc14_22.1
 // CHECK:STDOUT:     %Int.ref.loc14_36: %Int.type = name_ref Int, imports.%import_ref.1 [template = constants.%Int]
-// CHECK:STDOUT:     %N.ref.loc14_40: i32 = name_ref N, @Symbolic.%N [symbolic = @Symbolic.%N (constants.%N)]
-// CHECK:STDOUT:     %int.make_type_signed.loc14_39: init type = call %Int.ref.loc14_36(%N.ref.loc14_40) [symbolic = %int.make_type_signed.loc14_28 (constants.%.6)]
-// CHECK:STDOUT:     %.loc14_41.1: type = value_of_initializer %int.make_type_signed.loc14_39 [symbolic = %int.make_type_signed.loc14_28 (constants.%.6)]
-// CHECK:STDOUT:     %.loc14_41.2: type = converted %int.make_type_signed.loc14_39, %.loc14_41.1 [symbolic = %int.make_type_signed.loc14_28 (constants.%.6)]
+// CHECK:STDOUT:     %N.ref.loc14_40: i32 = name_ref N, @Symbolic.%N.loc14 [symbolic = @Symbolic.%N.1 (constants.%N)]
+// CHECK:STDOUT:     %int.make_type_signed.loc14_39: init type = call %Int.ref.loc14_36(%N.ref.loc14_40) [symbolic = @Symbolic.%.1 (constants.%.6)]
+// CHECK:STDOUT:     %.loc14_41.1: type = value_of_initializer %int.make_type_signed.loc14_39 [symbolic = @Symbolic.%.1 (constants.%.6)]
+// CHECK:STDOUT:     %.loc14_41.2: type = converted %int.make_type_signed.loc14_39, %.loc14_41.1 [symbolic = @Symbolic.%.1 (constants.%.6)]
 // CHECK:STDOUT:     @Symbolic.%return: ref %.6 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -226,17 +226,22 @@ var m: Int(1000000000);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @Symbolic(%N: i32, %x: file.%int.make_type_signed.loc14_28 (%.6)) -> %.6
-// CHECK:STDOUT:     generic [%N: i32] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %x.ref: file.%int.make_type_signed.loc14_28 (%.6) = name_ref x, %x
-// CHECK:STDOUT:   return %x.ref
+// CHECK:STDOUT: generic fn @Symbolic(%N.loc14: i32) {
+// CHECK:STDOUT:   %N.1: i32 = bind_symbolic_name N 0 [symbolic = %N.1 (constants.%N)]
+// CHECK:STDOUT:   %.1: type = int_type signed, %N.1 [symbolic = %.1 (constants.%.6)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%N.loc14: i32, %x: @Symbolic.%.1 (%.6)) -> %.6 {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %x.ref: @Symbolic.%.1 (%.6) = name_ref x, %x
+// CHECK:STDOUT:     return %x.ref
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Symbolic.decl(constants.%N) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @Symbolic.%N => constants.%N
-// CHECK:STDOUT:   file.%int.make_type_signed.loc14_28 => constants.%.6
+// CHECK:STDOUT: specific @Symbolic(constants.%N) {
+// CHECK:STDOUT:   %N.1 => constants.%N
+// CHECK:STDOUT:   %.1 => constants.%.6
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_zero_size.carbon

+ 25 - 20
toolchain/check/testdata/builtins/int/make_type_unsigned.carbon

@@ -193,19 +193,19 @@ var m: UInt(1000000000);
 // CHECK:STDOUT:     %.loc14_17.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:     %.loc14_17.2: type = converted %int.make_type_32, %.loc14_17.1 [template = i32]
 // CHECK:STDOUT:     %N.loc14_13.1: i32 = param N
-// CHECK:STDOUT:     @Symbolic.%N: i32 = bind_symbolic_name N 0, %N.loc14_13.1 [symbolic = @Symbolic.%N (constants.%N)]
+// CHECK:STDOUT:     @Symbolic.%N.loc14: i32 = bind_symbolic_name N 0, %N.loc14_13.1 [symbolic = @Symbolic.%N.1 (constants.%N)]
 // CHECK:STDOUT:     %UInt.ref.loc14_25: %UInt.type = name_ref UInt, imports.%import_ref.1 [template = constants.%UInt]
-// CHECK:STDOUT:     %N.ref.loc14_30: i32 = name_ref N, @Symbolic.%N [symbolic = @Symbolic.%N (constants.%N)]
-// CHECK:STDOUT:     %int.make_type_unsigned.loc14_29: init type = call %UInt.ref.loc14_25(%N.ref.loc14_30) [symbolic = %int.make_type_unsigned.loc14_29 (constants.%.6)]
-// CHECK:STDOUT:     %.loc14_31.1: type = value_of_initializer %int.make_type_unsigned.loc14_29 [symbolic = %int.make_type_unsigned.loc14_29 (constants.%.6)]
-// CHECK:STDOUT:     %.loc14_31.2: type = converted %int.make_type_unsigned.loc14_29, %.loc14_31.1 [symbolic = %int.make_type_unsigned.loc14_29 (constants.%.6)]
-// CHECK:STDOUT:     %x.loc14_22.1: file.%int.make_type_unsigned.loc14_29 (%.6) = param x
-// CHECK:STDOUT:     @Symbolic.%x: file.%int.make_type_unsigned.loc14_29 (%.6) = bind_name x, %x.loc14_22.1
+// CHECK:STDOUT:     %N.ref.loc14_30: i32 = name_ref N, @Symbolic.%N.loc14 [symbolic = @Symbolic.%N.1 (constants.%N)]
+// CHECK:STDOUT:     %int.make_type_unsigned.loc14_29: init type = call %UInt.ref.loc14_25(%N.ref.loc14_30) [symbolic = @Symbolic.%.1 (constants.%.6)]
+// CHECK:STDOUT:     %.loc14_31.1: type = value_of_initializer %int.make_type_unsigned.loc14_29 [symbolic = @Symbolic.%.1 (constants.%.6)]
+// CHECK:STDOUT:     %.loc14_31.2: type = converted %int.make_type_unsigned.loc14_29, %.loc14_31.1 [symbolic = @Symbolic.%.1 (constants.%.6)]
+// CHECK:STDOUT:     %x.loc14_22.1: @Symbolic.%.1 (%.6) = param x
+// CHECK:STDOUT:     @Symbolic.%x: @Symbolic.%.1 (%.6) = bind_name x, %x.loc14_22.1
 // CHECK:STDOUT:     %UInt.ref.loc14_37: %UInt.type = name_ref UInt, imports.%import_ref.1 [template = constants.%UInt]
-// CHECK:STDOUT:     %N.ref.loc14_42: i32 = name_ref N, @Symbolic.%N [symbolic = @Symbolic.%N (constants.%N)]
-// CHECK:STDOUT:     %int.make_type_unsigned.loc14_41: init type = call %UInt.ref.loc14_37(%N.ref.loc14_42) [symbolic = %int.make_type_unsigned.loc14_29 (constants.%.6)]
-// CHECK:STDOUT:     %.loc14_43.1: type = value_of_initializer %int.make_type_unsigned.loc14_41 [symbolic = %int.make_type_unsigned.loc14_29 (constants.%.6)]
-// CHECK:STDOUT:     %.loc14_43.2: type = converted %int.make_type_unsigned.loc14_41, %.loc14_43.1 [symbolic = %int.make_type_unsigned.loc14_29 (constants.%.6)]
+// CHECK:STDOUT:     %N.ref.loc14_42: i32 = name_ref N, @Symbolic.%N.loc14 [symbolic = @Symbolic.%N.1 (constants.%N)]
+// CHECK:STDOUT:     %int.make_type_unsigned.loc14_41: init type = call %UInt.ref.loc14_37(%N.ref.loc14_42) [symbolic = @Symbolic.%.1 (constants.%.6)]
+// CHECK:STDOUT:     %.loc14_43.1: type = value_of_initializer %int.make_type_unsigned.loc14_41 [symbolic = @Symbolic.%.1 (constants.%.6)]
+// CHECK:STDOUT:     %.loc14_43.2: type = converted %int.make_type_unsigned.loc14_41, %.loc14_43.1 [symbolic = @Symbolic.%.1 (constants.%.6)]
 // CHECK:STDOUT:     @Symbolic.%return: ref %.6 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -226,17 +226,22 @@ var m: UInt(1000000000);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @Symbolic(%N: i32, %x: file.%int.make_type_unsigned.loc14_29 (%.6)) -> %.6
-// CHECK:STDOUT:     generic [%N: i32] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %x.ref: file.%int.make_type_unsigned.loc14_29 (%.6) = name_ref x, %x
-// CHECK:STDOUT:   return %x.ref
+// CHECK:STDOUT: generic fn @Symbolic(%N.loc14: i32) {
+// CHECK:STDOUT:   %N.1: i32 = bind_symbolic_name N 0 [symbolic = %N.1 (constants.%N)]
+// CHECK:STDOUT:   %.1: type = int_type unsigned, %N.1 [symbolic = %.1 (constants.%.6)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%N.loc14: i32, %x: @Symbolic.%.1 (%.6)) -> %.6 {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %x.ref: @Symbolic.%.1 (%.6) = name_ref x, %x
+// CHECK:STDOUT:     return %x.ref
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Symbolic.decl(constants.%N) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @Symbolic.%N => constants.%N
-// CHECK:STDOUT:   file.%int.make_type_unsigned.loc14_29 => constants.%.6
+// CHECK:STDOUT: specific @Symbolic(constants.%N) {
+// CHECK:STDOUT:   %N.1 => constants.%N
+// CHECK:STDOUT:   %.1 => constants.%.6
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_zero_size.carbon

+ 55 - 39
toolchain/check/testdata/class/fail_generic_method.carbon

@@ -38,7 +38,7 @@ fn Class(N:! i32).F[self: Self](n: T) {}
 // CHECK:STDOUT:   %Class.type: type = generic_class_type @Class [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %Class.1: %Class.type = struct_value () [template]
-// CHECK:STDOUT:   %Class.2: type = class_type @Class, file.%Class.decl(%T) [symbolic]
+// CHECK:STDOUT:   %Class.2: type = class_type @Class, @Class(%T) [symbolic]
 // CHECK:STDOUT:   %.2: type = unbound_element_type %Class.2, %T [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
@@ -71,14 +71,14 @@ fn Class(N:! i32).F[self: Self](n: T) {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Class.decl: %Class.type = class_decl @Class [template = constants.%Class.1] {
 // CHECK:STDOUT:     %T.loc11_13.1: type = param T
-// CHECK:STDOUT:     %T.loc11_13.2: type = bind_symbolic_name T 0, %T.loc11_13.1 [symbolic = %T.loc11_13.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc11_13.2: type = bind_symbolic_name T 0, %T.loc11_13.1 [symbolic = @Class.%T (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.decl: %.type = fn_decl @.1 [template = constants.%.4] {
 // CHECK:STDOUT:     %int.make_type_32: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:     %.loc32_14.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:     %.loc32_14.2: type = converted %int.make_type_32, %.loc32_14.1 [template = i32]
 // CHECK:STDOUT:     %N.loc32_10.1: i32 = param N
-// CHECK:STDOUT:     %N.loc32_10.2: i32 = bind_symbolic_name N 0, %N.loc32_10.1 [symbolic = %N.loc32_10.2 (constants.%N)]
+// CHECK:STDOUT:     %N.loc32_10.2: i32 = bind_symbolic_name N 0, %N.loc32_10.1 [symbolic = @.1.%N (constants.%N)]
 // CHECK:STDOUT:     %Self.ref: <error> = name_ref Self, <error> [template = <error>]
 // CHECK:STDOUT:     %self.loc32_21.1: <error> = param self
 // CHECK:STDOUT:     @.1.%self: <error> = bind_name self, %self.loc32_21.1
@@ -88,55 +88,71 @@ fn Class(N:! i32).F[self: Self](n: T) {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @Class
-// CHECK:STDOUT:     generic [file.%T.loc11_13.2: type] {
-// CHECK:STDOUT:   %T.ref.loc12: type = name_ref T, file.%T.loc11_13.2 [symbolic = file.%T.loc11_13.2 (constants.%T)]
-// CHECK:STDOUT:   %.loc12: <unexpected>.inst+28 (%.2) = field_decl a, element0 [template]
-// CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
-// CHECK:STDOUT:     %.loc13: type = specific_constant constants.%Class.2, file.%Class.decl(constants.%T) [symbolic = %.loc13 (constants.%Class.2)]
-// CHECK:STDOUT:     %Self.ref: type = name_ref Self, %.loc13 [symbolic = %.loc13 (constants.%Class.2)]
-// CHECK:STDOUT:     %self.loc13_8.1: @Class.%.loc13 (%Class.2) = param self
-// CHECK:STDOUT:     %self.loc13_8.2: @Class.%.loc13 (%Class.2) = bind_name self, %self.loc13_8.1
-// CHECK:STDOUT:     %T.ref.loc13: type = name_ref T, file.%T.loc11_13.2 [symbolic = %T.ref.loc13 (constants.%T)]
-// CHECK:STDOUT:     %n.loc13_20.1: @Class.%T.ref.loc13 (%T) = param n
-// CHECK:STDOUT:     %n.loc13_20.2: @Class.%T.ref.loc13 (%T) = bind_name n, %n.loc13_20.1
-// CHECK:STDOUT:   }
+// CHECK:STDOUT: generic class @Class(file.%T.loc11_13.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class.2)]
+// CHECK:STDOUT:   %.1: type = unbound_element_type @Class.%Class (%Class.2), @Class.%T (%T) [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:     %T.ref.loc12: type = name_ref T, file.%T.loc11_13.2 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:     %.loc12: @Class.%.1 (%.2) = field_decl a, element0 [template]
+// CHECK:STDOUT:     %F.decl: %F.type = fn_decl @F [template = constants.%F] {
+// CHECK:STDOUT:       %.loc13: type = specific_constant constants.%Class.2, @Class(constants.%T) [symbolic = @F.%Class (constants.%Class.2)]
+// CHECK:STDOUT:       %Self.ref: type = name_ref Self, %.loc13 [symbolic = @F.%Class (constants.%Class.2)]
+// CHECK:STDOUT:       %self.loc13_8.1: @F.%Class (%Class.2) = param self
+// CHECK:STDOUT:       %self.loc13_8.2: @F.%Class (%Class.2) = bind_name self, %self.loc13_8.1
+// CHECK:STDOUT:       %T.ref.loc13: type = name_ref T, file.%T.loc11_13.2 [symbolic = @F.%T (constants.%T)]
+// CHECK:STDOUT:       %n.loc13_20.1: @F.%T (%T) = param n
+// CHECK:STDOUT:       %n.loc13_20.2: @F.%T (%T) = bind_name n, %n.loc13_20.1
+// CHECK:STDOUT:     }
 // CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%Class.2
-// CHECK:STDOUT:   .a = %.loc12
-// CHECK:STDOUT:   .F = %F.decl
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%Class.2
+// CHECK:STDOUT:     .a = %.loc12
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F[@Class.%self.loc13_8.2: @Class.%.loc13 (%Class.2)](@Class.%n.loc13_20.2: @Class.%T.ref.loc13 (%T))
-// CHECK:STDOUT:     generic [file.%T.loc11_13.2: type];
+// CHECK:STDOUT: generic fn @F(file.%T.loc11_13.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn[@Class.%self.loc13_8.2: @F.%Class (%Class.2)](@Class.%n.loc13_20.2: @F.%T (%T));
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @.1[%self: <error>](%n: <error>)
-// CHECK:STDOUT:     generic [file.%N.loc32_10.2: i32] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   return
+// CHECK:STDOUT: generic fn @.1(file.%N.loc32_10.2: i32) {
+// CHECK:STDOUT:   %N: i32 = bind_symbolic_name N 0 [symbolic = %N (constants.%N)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn[%self: <error>](%n: <error>) {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Class(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc11_13.2 => constants.%T
+// CHECK:STDOUT: specific @Class(@F.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Class.%F.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @Class.%.loc13 => constants.%Class.2
-// CHECK:STDOUT:   @Class.%T.ref.loc13 => constants.%T
+// CHECK:STDOUT: specific @F(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %Class => constants.%Class.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(file.%T.loc11_13.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc11_13.2 => constants.%T
+// CHECK:STDOUT: specific @Class(@Class.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%.decl(constants.%N) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%N.loc32_10.2 => constants.%N
+// CHECK:STDOUT: specific @.1(constants.%N) {
+// CHECK:STDOUT:   %N => constants.%N
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 111 - 66
toolchain/check/testdata/class/generic/basic.carbon

@@ -21,6 +21,7 @@ class Class(T:! type) {
   var k: T;
 }
 
+class Declaration(T:! type);
 
 // CHECK:STDOUT: --- basic.carbon
 // CHECK:STDOUT:
@@ -29,7 +30,7 @@ class Class(T:! type) {
 // CHECK:STDOUT:   %Class.type: type = generic_class_type @Class [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %Class.1: %Class.type = struct_value () [template]
-// CHECK:STDOUT:   %Class.2: type = class_type @Class, file.%Class.decl(%T) [symbolic]
+// CHECK:STDOUT:   %Class.2: type = class_type @Class, @Class(%T) [symbolic]
 // CHECK:STDOUT:   %.2: type = ptr_type %Class.2 [symbolic]
 // CHECK:STDOUT:   %.3: type = ptr_type %T [symbolic]
 // CHECK:STDOUT:   %GetAddr.type: type = fn_type @GetAddr [template]
@@ -39,12 +40,16 @@ class Class(T:! type) {
 // CHECK:STDOUT:   %.4: type = unbound_element_type %Class.2, %T [symbolic]
 // CHECK:STDOUT:   %.5: type = struct_type {.k: %T} [symbolic]
 // CHECK:STDOUT:   %.6: type = ptr_type %.5 [symbolic]
+// CHECK:STDOUT:   %Declaration.type: type = generic_class_type @Declaration [template]
+// CHECK:STDOUT:   %Declaration.1: %Declaration.type = struct_value () [template]
+// CHECK:STDOUT:   %Declaration.2: type = class_type @Declaration, @Declaration(%T) [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .Class = %Class.decl
+// CHECK:STDOUT:     .Declaration = %Declaration.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %Core: <namespace> = namespace %Core.import, [template] {
@@ -58,88 +63,128 @@ class Class(T:! type) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Class.decl: %Class.type = class_decl @Class [template = constants.%Class.1] {
 // CHECK:STDOUT:     %T.loc11_13.1: type = param T
-// CHECK:STDOUT:     %T.loc11_13.2: type = bind_symbolic_name T 0, %T.loc11_13.1 [symbolic = %T.loc11_13.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc11_13.2: type = bind_symbolic_name T 0, %T.loc11_13.1 [symbolic = @Class.%T (constants.%T)]
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Declaration.decl: %Declaration.type = class_decl @Declaration [template = constants.%Declaration.1] {
+// CHECK:STDOUT:     %T.loc24_19.1: type = param T
+// CHECK:STDOUT:     %T.loc24_19.2: type = bind_symbolic_name T 0, %T.loc24_19.1 [symbolic = @Declaration.%T (constants.%T)]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic class @Class(file.%T.loc11_13.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class.2)]
+// CHECK:STDOUT:   %.1: type = unbound_element_type @Class.%Class (%Class.2), @Class.%T (%T) [symbolic = %.1 (constants.%.4)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:     %GetAddr.decl: %GetAddr.type = fn_decl @GetAddr [template = constants.%GetAddr] {
+// CHECK:STDOUT:       %.loc12_25: type = specific_constant constants.%Class.2, @Class(constants.%T) [symbolic = @GetAddr.%Class (constants.%Class.2)]
+// CHECK:STDOUT:       %Self.ref.loc12: type = name_ref Self, %.loc12_25 [symbolic = @GetAddr.%Class (constants.%Class.2)]
+// CHECK:STDOUT:       %.loc12_29: type = ptr_type %Class.2 [symbolic = @GetAddr.%.1 (constants.%.2)]
+// CHECK:STDOUT:       %self.loc12_19.1: @GetAddr.%.1 (%.2) = param self
+// CHECK:STDOUT:       %self.loc12_19.3: @GetAddr.%.1 (%.2) = bind_name self, %self.loc12_19.1
+// CHECK:STDOUT:       %.loc12_14: @GetAddr.%.1 (%.2) = addr_pattern %self.loc12_19.3
+// CHECK:STDOUT:       %T.ref.loc12: type = name_ref T, file.%T.loc11_13.2 [symbolic = @GetAddr.%T (constants.%T)]
+// CHECK:STDOUT:       %.loc12_38: type = ptr_type %T [symbolic = @GetAddr.%.2 (constants.%.3)]
+// CHECK:STDOUT:       %return.var.loc12: ref %.3 = var <return slot>
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %GetValue.decl: %GetValue.type = fn_decl @GetValue [template = constants.%GetValue] {
+// CHECK:STDOUT:       %.loc17: type = specific_constant constants.%Class.2, @Class(constants.%T) [symbolic = @GetValue.%Class (constants.%Class.2)]
+// CHECK:STDOUT:       %Self.ref.loc17: type = name_ref Self, %.loc17 [symbolic = @GetValue.%Class (constants.%Class.2)]
+// CHECK:STDOUT:       %self.loc17_15.1: @GetValue.%Class (%Class.2) = param self
+// CHECK:STDOUT:       %self.loc17_15.2: @GetValue.%Class (%Class.2) = bind_name self, %self.loc17_15.1
+// CHECK:STDOUT:       %T.ref.loc17: type = name_ref T, file.%T.loc11_13.2 [symbolic = @GetValue.%T (constants.%T)]
+// CHECK:STDOUT:       %return.var.loc17: ref %T = var <return slot>
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %T.ref.loc21: type = name_ref T, file.%T.loc11_13.2 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:     %.loc21: @Class.%.1 (%.4) = field_decl k, element0 [template]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%Class.2
+// CHECK:STDOUT:     .GetAddr = %GetAddr.decl
+// CHECK:STDOUT:     .GetValue = %GetValue.decl
+// CHECK:STDOUT:     .k = %.loc21
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic class @Declaration(file.%T.loc24_19.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class;
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @Class
-// CHECK:STDOUT:     generic [file.%T.loc11_13.2: type] {
-// CHECK:STDOUT:   %GetAddr.decl: %GetAddr.type = fn_decl @GetAddr [template = constants.%GetAddr] {
-// CHECK:STDOUT:     %.loc12_25: type = specific_constant constants.%Class.2, file.%Class.decl(constants.%T) [symbolic = %.loc12_25 (constants.%Class.2)]
-// CHECK:STDOUT:     %Self.ref.loc12: type = name_ref Self, %.loc12_25 [symbolic = %.loc12_25 (constants.%Class.2)]
-// CHECK:STDOUT:     %.loc12_29: type = ptr_type %Class.2 [symbolic = %.loc12_29 (constants.%.2)]
-// CHECK:STDOUT:     %self.loc12_19.1: @Class.%.loc12_29 (%.2) = param self
-// CHECK:STDOUT:     %self.loc12_19.3: @Class.%.loc12_29 (%.2) = bind_name self, %self.loc12_19.1
-// CHECK:STDOUT:     %.loc12_14: @Class.%.loc12_29 (%.2) = addr_pattern %self.loc12_19.3
-// CHECK:STDOUT:     %T.ref.loc12: type = name_ref T, file.%T.loc11_13.2 [symbolic = %T.ref.loc12 (constants.%T)]
-// CHECK:STDOUT:     %.loc12_38: type = ptr_type %T [symbolic = %.loc12_38 (constants.%.3)]
-// CHECK:STDOUT:     %return.var.loc12: ref %.3 = var <return slot>
+// CHECK:STDOUT: generic fn @GetAddr(file.%T.loc11_13.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class.2)]
+// CHECK:STDOUT:   %.1: type = ptr_type @GetAddr.%Class (%Class.2) [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:   %.2: type = ptr_type @GetAddr.%T (%T) [symbolic = %.2 (constants.%.3)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.3: type = unbound_element_type @GetAddr.%Class (%Class.2), @GetAddr.%T (%T) [symbolic = %.3 (constants.%.4)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn[addr @Class.%self.loc12_19.3: @GetAddr.%.1 (%.2)]() -> %.3 {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %self.ref: @GetAddr.%.1 (%.2) = name_ref self, @Class.%self.loc12_19.3
+// CHECK:STDOUT:     %.loc13_17.1: ref @GetAddr.%Class (%Class.2) = deref %self.ref
+// CHECK:STDOUT:     %k.ref: @GetAddr.%.3 (%.4) = name_ref k, @Class.%.loc21 [template = @Class.%.loc21]
+// CHECK:STDOUT:     %.loc13_17.2: ref @GetAddr.%T (%T) = class_element_access %.loc13_17.1, element0
+// CHECK:STDOUT:     %.loc13_12: @GetAddr.%.2 (%.3) = addr_of %.loc13_17.2
+// CHECK:STDOUT:     return %.loc13_12
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %GetValue.decl: %GetValue.type = fn_decl @GetValue [template = constants.%GetValue] {
-// CHECK:STDOUT:     %.loc17: type = specific_constant constants.%Class.2, file.%Class.decl(constants.%T) [symbolic = %.loc17 (constants.%Class.2)]
-// CHECK:STDOUT:     %Self.ref.loc17: type = name_ref Self, %.loc17 [symbolic = %.loc17 (constants.%Class.2)]
-// CHECK:STDOUT:     %self.loc17_15.1: @Class.%.loc17 (%Class.2) = param self
-// CHECK:STDOUT:     %self.loc17_15.2: @Class.%.loc17 (%Class.2) = bind_name self, %self.loc17_15.1
-// CHECK:STDOUT:     %T.ref.loc17: type = name_ref T, file.%T.loc11_13.2 [symbolic = %T.ref.loc17 (constants.%T)]
-// CHECK:STDOUT:     %return.var.loc17: ref %T = var <return slot>
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @GetValue(file.%T.loc11_13.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1: type = unbound_element_type @GetValue.%Class (%Class.2), @GetValue.%T (%T) [symbolic = %.1 (constants.%.4)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn[@Class.%self.loc17_15.2: @GetValue.%Class (%Class.2)]() -> %T {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %self.ref: @GetValue.%Class (%Class.2) = name_ref self, @Class.%self.loc17_15.2
+// CHECK:STDOUT:     %k.ref: @GetValue.%.1 (%.4) = name_ref k, @Class.%.loc21 [template = @Class.%.loc21]
+// CHECK:STDOUT:     %.loc18_16.1: ref @GetValue.%T (%T) = class_element_access %self.ref, element0
+// CHECK:STDOUT:     %.loc18_16.2: @GetValue.%T (%T) = bind_value %.loc18_16.1
+// CHECK:STDOUT:     return %.loc18_16.2
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %T.ref.loc21: type = name_ref T, file.%T.loc11_13.2 [symbolic = file.%T.loc11_13.2 (constants.%T)]
-// CHECK:STDOUT:   %.loc21: <unexpected>.inst+41 (%.4) = field_decl k, element0 [template]
-// CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%Class.2
-// CHECK:STDOUT:   .GetAddr = %GetAddr.decl
-// CHECK:STDOUT:   .GetValue = %GetValue.decl
-// CHECK:STDOUT:   .k = %.loc21
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @GetAddr[addr @Class.%self.loc12_19.3: @Class.%.loc12_29 (%.2)]() -> %.3
-// CHECK:STDOUT:     generic [file.%T.loc11_13.2: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %self.ref: @Class.%.loc12_29 (%.2) = name_ref self, @Class.%self.loc12_19.3
-// CHECK:STDOUT:   %.loc13_17.1: ref @Class.%.loc12_25 (%Class.2) = deref %self.ref
-// CHECK:STDOUT:   %k.ref: <unexpected>.inst+49 (%.4) = name_ref k, @Class.%.loc21 [template = @Class.%.loc21]
-// CHECK:STDOUT:   %.loc13_17.2: ref @Class.%T.ref.loc12 (%T) = class_element_access %.loc13_17.1, element0
-// CHECK:STDOUT:   %.loc13_12: @Class.%.loc12_38 (%.3) = addr_of %.loc13_17.2
-// CHECK:STDOUT:   return %.loc13_12
+// CHECK:STDOUT: specific @Class(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Class => constants.%Class.2
+// CHECK:STDOUT:   %.1 => constants.%.4
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @GetValue[@Class.%self.loc17_15.2: @Class.%.loc17 (%Class.2)]() -> %T
-// CHECK:STDOUT:     generic [file.%T.loc11_13.2: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %self.ref: @Class.%.loc17 (%Class.2) = name_ref self, @Class.%self.loc17_15.2
-// CHECK:STDOUT:   %k.ref: <unexpected>.inst+55 (%.4) = name_ref k, @Class.%.loc21 [template = @Class.%.loc21]
-// CHECK:STDOUT:   %.loc18_16.1: ref @Class.%T.ref.loc17 (%T) = class_element_access %self.ref, element0
-// CHECK:STDOUT:   %.loc18_16.2: @Class.%T.ref.loc17 (%T) = bind_value %.loc18_16.1
-// CHECK:STDOUT:   return %.loc18_16.2
+// CHECK:STDOUT: specific @Class(@GetAddr.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc11_13.2 => constants.%T
+// CHECK:STDOUT: specific @GetAddr(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %Class => constants.%Class.2
+// CHECK:STDOUT:   %.1 => constants.%.2
+// CHECK:STDOUT:   %.2 => constants.%.3
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: definition:
-// CHECK:STDOUT:   <unexpected>.inst+40 => constants.%Class.2
-// CHECK:STDOUT:   <unexpected>.inst+41 => constants.%.4
-// CHECK:STDOUT:   <unexpected>.inst+37.loc21_8 => <unexpected>.inst+38
+// CHECK:STDOUT: specific @Class(@GetValue.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Class.%GetAddr.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @Class.%.loc12_25 => constants.%Class.2
-// CHECK:STDOUT:   @Class.%.loc12_29 => constants.%.2
-// CHECK:STDOUT:   @Class.%T.ref.loc12 => constants.%T
-// CHECK:STDOUT:   @Class.%.loc12_38 => constants.%.3
+// CHECK:STDOUT: specific @GetValue(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %Class => constants.%Class.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Class.%GetValue.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @Class.%.loc17 => constants.%Class.2
-// CHECK:STDOUT:   @Class.%T.ref.loc17 => constants.%T
+// CHECK:STDOUT: specific @Class(@Class.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(file.%T.loc11_13.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc11_13.2 => constants.%T
+// CHECK:STDOUT: specific @Declaration(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 74 - 56
toolchain/check/testdata/class/generic/call.carbon

@@ -73,14 +73,14 @@ var a: Class(5, i32*);
 // CHECK:STDOUT:   %N: i32 = bind_symbolic_name N 1 [symbolic]
 // CHECK:STDOUT:   %Class.type: type = generic_class_type @Class [template]
 // CHECK:STDOUT:   %Class.1: %Class.type = struct_value () [template]
-// CHECK:STDOUT:   %Class.2: type = class_type @Class, file.%Class.decl(%T, %N) [symbolic]
+// CHECK:STDOUT:   %Class.2: type = class_type @Class, @Class(%T, %N) [symbolic]
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %.3: type = ptr_type i32 [template]
 // CHECK:STDOUT:   %.4: i32 = int_literal 5 [template]
-// CHECK:STDOUT:   %Class.3: type = class_type @Class, file.%Class.decl(%.3, %.4) [template]
+// CHECK:STDOUT:   %Class.3: type = class_type @Class, @Class(%.3, %.4) [template]
 // CHECK:STDOUT:   %.5: type = ptr_type %.2 [template]
 // CHECK:STDOUT:   %.6: i32 = int_literal 0 [template]
-// CHECK:STDOUT:   %Class.4: type = class_type @Class, file.%Class.decl(%.1, %.6) [template]
+// CHECK:STDOUT:   %Class.4: type = class_type @Class, @Class(%.1, %.6) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -107,12 +107,12 @@ var a: Class(5, i32*);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Class.decl: %Class.type = class_decl @Class [template = constants.%Class.1] {
 // CHECK:STDOUT:     %T.loc4_13.1: type = param T
-// CHECK:STDOUT:     %T.loc4_13.2: type = bind_symbolic_name T 0, %T.loc4_13.1 [symbolic = %T.loc4_13.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc4_13.2: type = bind_symbolic_name T 0, %T.loc4_13.1 [symbolic = @Class.%T (constants.%T)]
 // CHECK:STDOUT:     %int.make_type_32.loc4: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:     %.loc4_27.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
 // CHECK:STDOUT:     %.loc4_27.2: type = converted %int.make_type_32.loc4, %.loc4_27.1 [template = i32]
 // CHECK:STDOUT:     %N.loc4_23.1: i32 = param N
-// CHECK:STDOUT:     %N.loc4_23.2: i32 = bind_symbolic_name N 1, %N.loc4_23.1 [symbolic = %N.loc4_23.2 (constants.%N)]
+// CHECK:STDOUT:     %N.loc4_23.2: i32 = bind_symbolic_name N 1, %N.loc4_23.1 [symbolic = @Class.%N (constants.%N)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Class.ref.loc6: %Class.type = name_ref Class, %Class.decl [template = constants.%Class.1]
 // CHECK:STDOUT:   %int.make_type_32.loc6: init type = call constants.%Int32() [template = i32]
@@ -136,34 +136,37 @@ var a: Class(5, i32*);
 // CHECK:STDOUT:   %b: ref %Class.4 = bind_name b, %b.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @Class
-// CHECK:STDOUT:     generic [file.%T.loc4_13.2: type, file.%N.loc4_23.2: i32] {
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%Class.2
+// CHECK:STDOUT: generic class @Class(file.%T.loc4_13.2: type, file.%N.loc4_23.2: i32) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %N: i32 = bind_symbolic_name N 1 [symbolic = %N (constants.%N)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%Class.2
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(constants.%T, constants.%N) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_13.2 => constants.%T
-// CHECK:STDOUT:   file.%N.loc4_23.2 => constants.%N
+// CHECK:STDOUT: specific @Class(constants.%T, constants.%N) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %N => constants.%N
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(constants.%.3, constants.%.4) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_13.2 => constants.%.3
-// CHECK:STDOUT:   file.%N.loc4_23.2 => constants.%.4
+// CHECK:STDOUT: specific @Class(constants.%.3, constants.%.4) {
+// CHECK:STDOUT:   %T => constants.%.3
+// CHECK:STDOUT:   %N => constants.%.4
 // CHECK:STDOUT:
-// CHECK:STDOUT: definition:
+// CHECK:STDOUT: !definition:
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(constants.%.1, constants.%.6) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_13.2 => constants.%.1
-// CHECK:STDOUT:   file.%N.loc4_23.2 => constants.%.6
+// CHECK:STDOUT: specific @Class(constants.%.1, constants.%.6) {
+// CHECK:STDOUT:   %T => constants.%.1
+// CHECK:STDOUT:   %N => constants.%.6
 // CHECK:STDOUT:
-// CHECK:STDOUT: definition:
+// CHECK:STDOUT: !definition:
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_too_few.carbon
@@ -176,7 +179,7 @@ var a: Class(5, i32*);
 // CHECK:STDOUT:   %N: i32 = bind_symbolic_name N 1 [symbolic]
 // CHECK:STDOUT:   %Class.type: type = generic_class_type @Class [template]
 // CHECK:STDOUT:   %Class.1: %Class.type = struct_value () [template]
-// CHECK:STDOUT:   %Class.2: type = class_type @Class, file.%Class.decl(%T, %N) [symbolic]
+// CHECK:STDOUT:   %Class.2: type = class_type @Class, @Class(%T, %N) [symbolic]
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %.3: type = ptr_type i32 [template]
 // CHECK:STDOUT: }
@@ -204,12 +207,12 @@ var a: Class(5, i32*);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Class.decl: %Class.type = class_decl @Class [template = constants.%Class.1] {
 // CHECK:STDOUT:     %T.loc4_13.1: type = param T
-// CHECK:STDOUT:     %T.loc4_13.2: type = bind_symbolic_name T 0, %T.loc4_13.1 [symbolic = %T.loc4_13.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc4_13.2: type = bind_symbolic_name T 0, %T.loc4_13.1 [symbolic = @Class.%T (constants.%T)]
 // CHECK:STDOUT:     %int.make_type_32.loc4: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:     %.loc4_27.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
 // CHECK:STDOUT:     %.loc4_27.2: type = converted %int.make_type_32.loc4, %.loc4_27.1 [template = i32]
 // CHECK:STDOUT:     %N.loc4_23.1: i32 = param N
-// CHECK:STDOUT:     %N.loc4_23.2: i32 = bind_symbolic_name N 1, %N.loc4_23.1 [symbolic = %N.loc4_23.2 (constants.%N)]
+// CHECK:STDOUT:     %N.loc4_23.2: i32 = bind_symbolic_name N 1, %N.loc4_23.1 [symbolic = @Class.%N (constants.%N)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Class.ref: %Class.type = name_ref Class, %Class.decl [template = constants.%Class.1]
 // CHECK:STDOUT:   %int.make_type_32.loc13: init type = call constants.%Int32() [template = i32]
@@ -223,18 +226,23 @@ var a: Class(5, i32*);
 // CHECK:STDOUT:   %a: ref <error> = bind_name a, %a.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @Class
-// CHECK:STDOUT:     generic [file.%T.loc4_13.2: type, file.%N.loc4_23.2: i32] {
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%Class.2
+// CHECK:STDOUT: generic class @Class(file.%T.loc4_13.2: type, file.%N.loc4_23.2: i32) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %N: i32 = bind_symbolic_name N 1 [symbolic = %N (constants.%N)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%Class.2
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(constants.%T, constants.%N) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_13.2 => constants.%T
-// CHECK:STDOUT:   file.%N.loc4_23.2 => constants.%N
+// CHECK:STDOUT: specific @Class(constants.%T, constants.%N) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %N => constants.%N
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_too_many.carbon
@@ -247,7 +255,7 @@ var a: Class(5, i32*);
 // CHECK:STDOUT:   %N: i32 = bind_symbolic_name N 1 [symbolic]
 // CHECK:STDOUT:   %Class.type: type = generic_class_type @Class [template]
 // CHECK:STDOUT:   %Class.1: %Class.type = struct_value () [template]
-// CHECK:STDOUT:   %Class.2: type = class_type @Class, file.%Class.decl(%T, %N) [symbolic]
+// CHECK:STDOUT:   %Class.2: type = class_type @Class, @Class(%T, %N) [symbolic]
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %.3: type = ptr_type i32 [template]
 // CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
@@ -277,12 +285,12 @@ var a: Class(5, i32*);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Class.decl: %Class.type = class_decl @Class [template = constants.%Class.1] {
 // CHECK:STDOUT:     %T.loc4_13.1: type = param T
-// CHECK:STDOUT:     %T.loc4_13.2: type = bind_symbolic_name T 0, %T.loc4_13.1 [symbolic = %T.loc4_13.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc4_13.2: type = bind_symbolic_name T 0, %T.loc4_13.1 [symbolic = @Class.%T (constants.%T)]
 // CHECK:STDOUT:     %int.make_type_32.loc4: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:     %.loc4_27.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
 // CHECK:STDOUT:     %.loc4_27.2: type = converted %int.make_type_32.loc4, %.loc4_27.1 [template = i32]
 // CHECK:STDOUT:     %N.loc4_23.1: i32 = param N
-// CHECK:STDOUT:     %N.loc4_23.2: i32 = bind_symbolic_name N 1, %N.loc4_23.1 [symbolic = %N.loc4_23.2 (constants.%N)]
+// CHECK:STDOUT:     %N.loc4_23.2: i32 = bind_symbolic_name N 1, %N.loc4_23.1 [symbolic = @Class.%N (constants.%N)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Class.ref: %Class.type = name_ref Class, %Class.decl [template = constants.%Class.1]
 // CHECK:STDOUT:   %int.make_type_32.loc13: init type = call constants.%Int32() [template = i32]
@@ -298,18 +306,23 @@ var a: Class(5, i32*);
 // CHECK:STDOUT:   %a: ref <error> = bind_name a, %a.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @Class
-// CHECK:STDOUT:     generic [file.%T.loc4_13.2: type, file.%N.loc4_23.2: i32] {
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%Class.2
+// CHECK:STDOUT: generic class @Class(file.%T.loc4_13.2: type, file.%N.loc4_23.2: i32) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %N: i32 = bind_symbolic_name N 1 [symbolic = %N (constants.%N)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%Class.2
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(constants.%T, constants.%N) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_13.2 => constants.%T
-// CHECK:STDOUT:   file.%N.loc4_23.2 => constants.%N
+// CHECK:STDOUT: specific @Class(constants.%T, constants.%N) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %N => constants.%N
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_no_conversion.carbon
@@ -322,7 +335,7 @@ var a: Class(5, i32*);
 // CHECK:STDOUT:   %N: i32 = bind_symbolic_name N 1 [symbolic]
 // CHECK:STDOUT:   %Class.type: type = generic_class_type @Class [template]
 // CHECK:STDOUT:   %Class.1: %Class.type = struct_value () [template]
-// CHECK:STDOUT:   %Class.2: type = class_type @Class, file.%Class.decl(%T, %N) [symbolic]
+// CHECK:STDOUT:   %Class.2: type = class_type @Class, @Class(%T, %N) [symbolic]
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %.3: i32 = int_literal 5 [template]
 // CHECK:STDOUT:   %.4: type = ptr_type i32 [template]
@@ -351,12 +364,12 @@ var a: Class(5, i32*);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Class.decl: %Class.type = class_decl @Class [template = constants.%Class.1] {
 // CHECK:STDOUT:     %T.loc4_13.1: type = param T
-// CHECK:STDOUT:     %T.loc4_13.2: type = bind_symbolic_name T 0, %T.loc4_13.1 [symbolic = %T.loc4_13.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc4_13.2: type = bind_symbolic_name T 0, %T.loc4_13.1 [symbolic = @Class.%T (constants.%T)]
 // CHECK:STDOUT:     %int.make_type_32.loc4: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:     %.loc4_27.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
 // CHECK:STDOUT:     %.loc4_27.2: type = converted %int.make_type_32.loc4, %.loc4_27.1 [template = i32]
 // CHECK:STDOUT:     %N.loc4_23.1: i32 = param N
-// CHECK:STDOUT:     %N.loc4_23.2: i32 = bind_symbolic_name N 1, %N.loc4_23.1 [symbolic = %N.loc4_23.2 (constants.%N)]
+// CHECK:STDOUT:     %N.loc4_23.2: i32 = bind_symbolic_name N 1, %N.loc4_23.1 [symbolic = @Class.%N (constants.%N)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Class.ref: %Class.type = name_ref Class, %Class.decl [template = constants.%Class.1]
 // CHECK:STDOUT:   %.loc12_14: i32 = int_literal 5 [template = constants.%.3]
@@ -371,17 +384,22 @@ var a: Class(5, i32*);
 // CHECK:STDOUT:   %a: ref <error> = bind_name a, %a.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @Class
-// CHECK:STDOUT:     generic [file.%T.loc4_13.2: type, file.%N.loc4_23.2: i32] {
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%Class.2
+// CHECK:STDOUT: generic class @Class(file.%T.loc4_13.2: type, file.%N.loc4_23.2: i32) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %N: i32 = bind_symbolic_name N 1 [symbolic = %N (constants.%N)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%Class.2
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(constants.%T, constants.%N) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_13.2 => constants.%T
-// CHECK:STDOUT:   file.%N.loc4_23.2 => constants.%N
+// CHECK:STDOUT: specific @Class(constants.%T, constants.%N) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %N => constants.%N
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 68 - 54
toolchain/check/testdata/class/generic/fail_todo_use.carbon

@@ -43,7 +43,7 @@ fn Run() -> i32 {
 // CHECK:STDOUT:   %Class.type: type = generic_class_type @Class [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %Class.1: %Class.type = struct_value () [template]
-// CHECK:STDOUT:   %Class.2: type = class_type @Class, file.%Class.decl(%T) [symbolic]
+// CHECK:STDOUT:   %Class.2: type = class_type @Class, @Class(%T) [symbolic]
 // CHECK:STDOUT:   %.2: type = ptr_type %Class.2 [symbolic]
 // CHECK:STDOUT:   %.3: type = ptr_type %T [symbolic]
 // CHECK:STDOUT:   %Get.type: type = fn_type @Get [template]
@@ -55,7 +55,7 @@ fn Run() -> i32 {
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %Run.type: type = fn_type @Run [template]
 // CHECK:STDOUT:   %Run: %Run.type = struct_value () [template]
-// CHECK:STDOUT:   %Class.3: type = class_type @Class, file.%Class.decl(i32) [template]
+// CHECK:STDOUT:   %Class.3: type = class_type @Class, @Class(i32) [template]
 // CHECK:STDOUT:   %.7: type = unbound_element_type %Class.3, i32 [template]
 // CHECK:STDOUT:   %.8: i32 = int_literal 0 [template]
 // CHECK:STDOUT:   %.9: type = struct_type {.k: i32} [template]
@@ -85,7 +85,7 @@ fn Run() -> i32 {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Class.decl: %Class.type = class_decl @Class [template = constants.%Class.1] {
 // CHECK:STDOUT:     %T.loc11_13.1: type = param T
-// CHECK:STDOUT:     %T.loc11_13.2: type = bind_symbolic_name T 0, %T.loc11_13.1 [symbolic = %T.loc11_13.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc11_13.2: type = bind_symbolic_name T 0, %T.loc11_13.1 [symbolic = @Class.%T (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Run.decl: %Run.type = fn_decl @Run [template = constants.%Run] {
 // CHECK:STDOUT:     %int.make_type_32: init type = call constants.%Int32() [template = i32]
@@ -95,37 +95,53 @@ fn Run() -> i32 {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @Class
-// CHECK:STDOUT:     generic [file.%T.loc11_13.2: type] {
-// CHECK:STDOUT:   %Get.decl: %Get.type = fn_decl @Get [template = constants.%Get] {
-// CHECK:STDOUT:     %.loc12_21: type = specific_constant constants.%Class.2, file.%Class.decl(constants.%T) [symbolic = %.loc12_21 (constants.%Class.2)]
-// CHECK:STDOUT:     %Self.ref: type = name_ref Self, %.loc12_21 [symbolic = %.loc12_21 (constants.%Class.2)]
-// CHECK:STDOUT:     %.loc12_25: type = ptr_type %Class.2 [symbolic = %.loc12_25 (constants.%.2)]
-// CHECK:STDOUT:     %self.loc12_15.1: @Class.%.loc12_25 (%.2) = param self
-// CHECK:STDOUT:     %self.loc12_15.3: @Class.%.loc12_25 (%.2) = bind_name self, %self.loc12_15.1
-// CHECK:STDOUT:     %.loc12_10: @Class.%.loc12_25 (%.2) = addr_pattern %self.loc12_15.3
-// CHECK:STDOUT:     %T.ref.loc12: type = name_ref T, file.%T.loc11_13.2 [symbolic = %T.ref.loc12 (constants.%T)]
-// CHECK:STDOUT:     %.loc12_34: type = ptr_type %T [symbolic = %.loc12_34 (constants.%.3)]
-// CHECK:STDOUT:     %return.var: ref %.3 = var <return slot>
-// CHECK:STDOUT:   }
-// CHECK:STDOUT:   %T.ref.loc16: type = name_ref T, file.%T.loc11_13.2 [symbolic = file.%T.loc11_13.2 (constants.%T)]
-// CHECK:STDOUT:   %.loc16: <unexpected>.inst+32 (%.4) = field_decl k, element0 [template]
+// CHECK:STDOUT: generic class @Class(file.%T.loc11_13.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class.2)]
+// CHECK:STDOUT:   %.1: type = unbound_element_type @Class.%Class (%Class.2), @Class.%T (%T) [symbolic = %.1 (constants.%.4)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:     %Get.decl: %Get.type = fn_decl @Get [template = constants.%Get] {
+// CHECK:STDOUT:       %.loc12_21: type = specific_constant constants.%Class.2, @Class(constants.%T) [symbolic = @Get.%Class (constants.%Class.2)]
+// CHECK:STDOUT:       %Self.ref: type = name_ref Self, %.loc12_21 [symbolic = @Get.%Class (constants.%Class.2)]
+// CHECK:STDOUT:       %.loc12_25: type = ptr_type %Class.2 [symbolic = @Get.%.1 (constants.%.2)]
+// CHECK:STDOUT:       %self.loc12_15.1: @Get.%.1 (%.2) = param self
+// CHECK:STDOUT:       %self.loc12_15.3: @Get.%.1 (%.2) = bind_name self, %self.loc12_15.1
+// CHECK:STDOUT:       %.loc12_10: @Get.%.1 (%.2) = addr_pattern %self.loc12_15.3
+// CHECK:STDOUT:       %T.ref.loc12: type = name_ref T, file.%T.loc11_13.2 [symbolic = @Get.%T (constants.%T)]
+// CHECK:STDOUT:       %.loc12_34: type = ptr_type %T [symbolic = @Get.%.2 (constants.%.3)]
+// CHECK:STDOUT:       %return.var: ref %.3 = var <return slot>
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %T.ref.loc16: type = name_ref T, file.%T.loc11_13.2 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:     %.loc16: @Class.%.1 (%.4) = field_decl k, element0 [template]
 // CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%Class.2
-// CHECK:STDOUT:   .Get = %Get.decl
-// CHECK:STDOUT:   .k = %.loc16
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%Class.2
+// CHECK:STDOUT:     .Get = %Get.decl
+// CHECK:STDOUT:     .k = %.loc16
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @Get[addr @Class.%self.loc12_15.3: @Class.%.loc12_25 (%.2)]() -> %.3
-// CHECK:STDOUT:     generic [file.%T.loc11_13.2: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %self.ref: @Class.%.loc12_25 (%.2) = name_ref self, @Class.%self.loc12_15.3
-// CHECK:STDOUT:   %.loc13_17.1: ref @Class.%.loc12_21 (%Class.2) = deref %self.ref
-// CHECK:STDOUT:   %k.ref: <unexpected>.inst+40 (%.4) = name_ref k, @Class.%.loc16 [template = @Class.%.loc16]
-// CHECK:STDOUT:   %.loc13_17.2: ref @Class.%T.ref.loc12 (%T) = class_element_access %.loc13_17.1, element0
-// CHECK:STDOUT:   %.loc13_12: @Class.%.loc12_34 (%.3) = addr_of %.loc13_17.2
-// CHECK:STDOUT:   return %.loc13_12
+// CHECK:STDOUT: generic fn @Get(file.%T.loc11_13.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class.2)]
+// CHECK:STDOUT:   %.1: type = ptr_type @Get.%Class (%Class.2) [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:   %.2: type = ptr_type @Get.%T (%T) [symbolic = %.2 (constants.%.3)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.3: type = unbound_element_type @Get.%Class (%Class.2), @Get.%T (%T) [symbolic = %.3 (constants.%.4)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn[addr @Class.%self.loc12_15.3: @Get.%.1 (%.2)]() -> %.3 {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %self.ref: @Get.%.1 (%.2) = name_ref self, @Class.%self.loc12_15.3
+// CHECK:STDOUT:     %.loc13_17.1: ref @Get.%Class (%Class.2) = deref %self.ref
+// CHECK:STDOUT:     %k.ref: @Get.%.3 (%.4) = name_ref k, @Class.%.loc16 [template = @Class.%.loc16]
+// CHECK:STDOUT:     %.loc13_17.2: ref @Get.%T (%T) = class_element_access %.loc13_17.1, element0
+// CHECK:STDOUT:     %.loc13_12: @Get.%.2 (%.3) = addr_of %.loc13_17.2
+// CHECK:STDOUT:     return %.loc13_12
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
@@ -152,36 +168,34 @@ fn Run() -> i32 {
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc11_13.2 => constants.%T
+// CHECK:STDOUT: specific @Class(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Class => constants.%Class.2
+// CHECK:STDOUT:   %.1 => constants.%.4
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: definition:
-// CHECK:STDOUT:   <unexpected>.inst+31 => constants.%Class.2
-// CHECK:STDOUT:   <unexpected>.inst+32 => constants.%.4
-// CHECK:STDOUT:   <unexpected>.inst+28.loc16_8 => <unexpected>.inst+29
+// CHECK:STDOUT: specific @Class(@Get.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Class.%Get.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @Class.%.loc12_21 => constants.%Class.2
-// CHECK:STDOUT:   @Class.%.loc12_25 => constants.%.2
-// CHECK:STDOUT:   @Class.%T.ref.loc12 => constants.%T
-// CHECK:STDOUT:   @Class.%.loc12_34 => constants.%.3
+// CHECK:STDOUT: specific @Get(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %Class => constants.%Class.2
+// CHECK:STDOUT:   %.1 => constants.%.2
+// CHECK:STDOUT:   %.2 => constants.%.3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(file.%T.loc11_13.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc11_13.2 => constants.%T
+// CHECK:STDOUT: specific @Class(@Class.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(i32) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc11_13.2 => i32
+// CHECK:STDOUT: specific @Class(i32) {
+// CHECK:STDOUT:   %T => i32
 // CHECK:STDOUT:
-// CHECK:STDOUT: definition:
-// CHECK:STDOUT:   <unexpected>.inst+31 => constants.%Class.3
-// CHECK:STDOUT:   <unexpected>.inst+32 => constants.%.7
-// CHECK:STDOUT:   <unexpected>.inst+28.loc16_8 => <unexpected>.inst+29
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Class => constants.%Class.3
+// CHECK:STDOUT:   %.1 => constants.%.7
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 95 - 75
toolchain/check/testdata/class/generic/field.carbon

@@ -31,12 +31,12 @@ fn H(U:! type, c: Class(U)) -> U {
 // CHECK:STDOUT:   %Class.type: type = generic_class_type @Class [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %Class.1: %Class.type = struct_value () [template]
-// CHECK:STDOUT:   %Class.2: type = class_type @Class, file.%Class.decl(%T) [symbolic]
+// CHECK:STDOUT:   %Class.2: type = class_type @Class, @Class(%T) [symbolic]
 // CHECK:STDOUT:   %.2: type = unbound_element_type %Class.2, %T [symbolic]
 // CHECK:STDOUT:   %.3: type = struct_type {.x: %T} [symbolic]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %Class.3: type = class_type @Class, file.%Class.decl(i32) [template]
+// CHECK:STDOUT:   %Class.3: type = class_type @Class, @Class(i32) [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT:   %.4: type = unbound_element_type %Class.3, i32 [template]
@@ -44,7 +44,7 @@ fn H(U:! type, c: Class(U)) -> U {
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
 // CHECK:STDOUT:   %U: type = bind_symbolic_name U 0 [symbolic]
-// CHECK:STDOUT:   %Class.4: type = class_type @Class, file.%Class.decl(%U) [symbolic]
+// CHECK:STDOUT:   %Class.4: type = class_type @Class, @Class(%U) [symbolic]
 // CHECK:STDOUT:   %H.type: type = fn_type @H [template]
 // CHECK:STDOUT:   %H: %H.type = struct_value () [template]
 // CHECK:STDOUT:   %.6: type = unbound_element_type %Class.4, %U [symbolic]
@@ -75,7 +75,7 @@ fn H(U:! type, c: Class(U)) -> U {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Class.decl: %Class.type = class_decl @Class [template = constants.%Class.1] {
 // CHECK:STDOUT:     %T.loc11_13.1: type = param T
-// CHECK:STDOUT:     %T.loc11_13.2: type = bind_symbolic_name T 0, %T.loc11_13.1 [symbolic = %T.loc11_13.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc11_13.2: type = bind_symbolic_name T 0, %T.loc11_13.1 [symbolic = @Class.%T (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
 // CHECK:STDOUT:     %Class.ref.loc15: %Class.type = name_ref Class, %Class.decl [template = constants.%Class.1]
@@ -94,40 +94,47 @@ fn H(U:! type, c: Class(U)) -> U {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [template = constants.%G] {
 // CHECK:STDOUT:     %T.loc19_6.1: type = param T
-// CHECK:STDOUT:     @G.%T: type = bind_symbolic_name T 0, %T.loc19_6.1 [symbolic = @G.%T (constants.%T)]
+// CHECK:STDOUT:     @G.%T.loc19: type = bind_symbolic_name T 0, %T.loc19_6.1 [symbolic = @G.%T.1 (constants.%T)]
 // CHECK:STDOUT:     %Class.ref.loc19: %Class.type = name_ref Class, %Class.decl [template = constants.%Class.1]
-// CHECK:STDOUT:     %T.ref.loc19_25: type = name_ref T, @G.%T [symbolic = @G.%T (constants.%T)]
-// CHECK:STDOUT:     %.loc19_24: init type = call %Class.ref.loc19(%T.ref.loc19_25) [symbolic = %.loc19_24 (constants.%Class.2)]
-// CHECK:STDOUT:     %.loc19_26.1: type = value_of_initializer %.loc19_24 [symbolic = %.loc19_24 (constants.%Class.2)]
-// CHECK:STDOUT:     %.loc19_26.2: type = converted %.loc19_24, %.loc19_26.1 [symbolic = %.loc19_24 (constants.%Class.2)]
-// CHECK:STDOUT:     %c.loc19_16.1: file.%.loc19_24 (%Class.2) = param c
-// CHECK:STDOUT:     @G.%c: file.%.loc19_24 (%Class.2) = bind_name c, %c.loc19_16.1
-// CHECK:STDOUT:     %T.ref.loc19_32: type = name_ref T, @G.%T [symbolic = @G.%T (constants.%T)]
+// CHECK:STDOUT:     %T.ref.loc19_25: type = name_ref T, @G.%T.loc19 [symbolic = @G.%T.1 (constants.%T)]
+// CHECK:STDOUT:     %.loc19_24: init type = call %Class.ref.loc19(%T.ref.loc19_25) [symbolic = @G.%Class (constants.%Class.2)]
+// CHECK:STDOUT:     %.loc19_26.1: type = value_of_initializer %.loc19_24 [symbolic = @G.%Class (constants.%Class.2)]
+// CHECK:STDOUT:     %.loc19_26.2: type = converted %.loc19_24, %.loc19_26.1 [symbolic = @G.%Class (constants.%Class.2)]
+// CHECK:STDOUT:     %c.loc19_16.1: @G.%Class (%Class.2) = param c
+// CHECK:STDOUT:     @G.%c: @G.%Class (%Class.2) = bind_name c, %c.loc19_16.1
+// CHECK:STDOUT:     %T.ref.loc19_32: type = name_ref T, @G.%T.loc19 [symbolic = @G.%T.1 (constants.%T)]
 // CHECK:STDOUT:     @G.%return: ref %T = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %H.decl: %H.type = fn_decl @H [template = constants.%H] {
 // CHECK:STDOUT:     %U.loc23_6.1: type = param U
-// CHECK:STDOUT:     @H.%U: type = bind_symbolic_name U 0, %U.loc23_6.1 [symbolic = @H.%U (constants.%U)]
+// CHECK:STDOUT:     @H.%U.loc23: type = bind_symbolic_name U 0, %U.loc23_6.1 [symbolic = @H.%U.1 (constants.%U)]
 // CHECK:STDOUT:     %Class.ref.loc23: %Class.type = name_ref Class, %Class.decl [template = constants.%Class.1]
-// CHECK:STDOUT:     %U.ref.loc23_25: type = name_ref U, @H.%U [symbolic = @H.%U (constants.%U)]
-// CHECK:STDOUT:     %.loc23_24: init type = call %Class.ref.loc23(%U.ref.loc23_25) [symbolic = %.loc23_24 (constants.%Class.4)]
-// CHECK:STDOUT:     %.loc23_26.1: type = value_of_initializer %.loc23_24 [symbolic = %.loc23_24 (constants.%Class.4)]
-// CHECK:STDOUT:     %.loc23_26.2: type = converted %.loc23_24, %.loc23_26.1 [symbolic = %.loc23_24 (constants.%Class.4)]
-// CHECK:STDOUT:     %c.loc23_16.1: file.%.loc23_24 (%Class.4) = param c
-// CHECK:STDOUT:     @H.%c: file.%.loc23_24 (%Class.4) = bind_name c, %c.loc23_16.1
-// CHECK:STDOUT:     %U.ref.loc23_32: type = name_ref U, @H.%U [symbolic = @H.%U (constants.%U)]
+// CHECK:STDOUT:     %U.ref.loc23_25: type = name_ref U, @H.%U.loc23 [symbolic = @H.%U.1 (constants.%U)]
+// CHECK:STDOUT:     %.loc23_24: init type = call %Class.ref.loc23(%U.ref.loc23_25) [symbolic = @H.%Class (constants.%Class.4)]
+// CHECK:STDOUT:     %.loc23_26.1: type = value_of_initializer %.loc23_24 [symbolic = @H.%Class (constants.%Class.4)]
+// CHECK:STDOUT:     %.loc23_26.2: type = converted %.loc23_24, %.loc23_26.1 [symbolic = @H.%Class (constants.%Class.4)]
+// CHECK:STDOUT:     %c.loc23_16.1: @H.%Class (%Class.4) = param c
+// CHECK:STDOUT:     @H.%c: @H.%Class (%Class.4) = bind_name c, %c.loc23_16.1
+// CHECK:STDOUT:     %U.ref.loc23_32: type = name_ref U, @H.%U.loc23 [symbolic = @H.%U.1 (constants.%U)]
 // CHECK:STDOUT:     @H.%return: ref %U = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @Class
-// CHECK:STDOUT:     generic [file.%T.loc11_13.2: type] {
-// CHECK:STDOUT:   %T.ref: type = name_ref T, file.%T.loc11_13.2 [symbolic = file.%T.loc11_13.2 (constants.%T)]
-// CHECK:STDOUT:   %.loc12: <unexpected>.inst+18 (%.2) = field_decl x, element0 [template]
+// CHECK:STDOUT: generic class @Class(file.%T.loc11_13.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%Class.2
-// CHECK:STDOUT:   .x = %.loc12
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class.2)]
+// CHECK:STDOUT:   %.1: type = unbound_element_type @Class.%Class (%Class.2), @Class.%T (%T) [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:     %T.ref: type = name_ref T, file.%T.loc11_13.2 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:     %.loc12: @Class.%.1 (%.2) = field_decl x, element0 [template]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%Class.2
+// CHECK:STDOUT:     .x = %.loc12
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
@@ -141,70 +148,83 @@ fn H(U:! type, c: Class(U)) -> U {
 // CHECK:STDOUT:   return %.loc16_11.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @G(%T: type, %c: file.%.loc19_24 (%Class.2)) -> %T
-// CHECK:STDOUT:     generic [%T: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %c.ref: file.%.loc19_24 (%Class.2) = name_ref c, %c
-// CHECK:STDOUT:   %x.ref: <unexpected>.inst+68 (%.2) = name_ref x, @Class.%.loc12 [template = @Class.%.loc12]
-// CHECK:STDOUT:   %.loc20_11.1: ref @G.%T (%T) = class_element_access %c.ref, element0
-// CHECK:STDOUT:   %.loc20_11.2: @G.%T (%T) = bind_value %.loc20_11.1
-// CHECK:STDOUT:   return %.loc20_11.2
+// CHECK:STDOUT: generic fn @G(%T.loc19: type) {
+// CHECK:STDOUT:   %T.1: type = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:   %Class: type = class_type @Class, @Class(%T.1) [symbolic = %Class (constants.%Class.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1: type = unbound_element_type @G.%Class (%Class.2), @G.%T.1 (%T) [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%T.loc19: type, %c: @G.%Class (%Class.2)) -> %T {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %c.ref: @G.%Class (%Class.2) = name_ref c, %c
+// CHECK:STDOUT:     %x.ref: @G.%.1 (%.2) = name_ref x, @Class.%.loc12 [template = @Class.%.loc12]
+// CHECK:STDOUT:     %.loc20_11.1: ref @G.%T.1 (%T) = class_element_access %c.ref, element0
+// CHECK:STDOUT:     %.loc20_11.2: @G.%T.1 (%T) = bind_value %.loc20_11.1
+// CHECK:STDOUT:     return %.loc20_11.2
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @H(%U: type, %c: file.%.loc23_24 (%Class.4)) -> %U
-// CHECK:STDOUT:     generic [%U: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %c.ref: file.%.loc23_24 (%Class.4) = name_ref c, %c
-// CHECK:STDOUT:   %x.ref: <unexpected>.inst+91 (%.6) = name_ref x, @Class.%.loc12 [template = @Class.%.loc12]
-// CHECK:STDOUT:   %.loc24_11.1: ref @H.%U (%U) = class_element_access %c.ref, element0
-// CHECK:STDOUT:   %.loc24_11.2: @H.%U (%U) = bind_value %.loc24_11.1
-// CHECK:STDOUT:   return %.loc24_11.2
+// CHECK:STDOUT: generic fn @H(%U.loc23: type) {
+// CHECK:STDOUT:   %U.1: type = bind_symbolic_name U 0 [symbolic = %U.1 (constants.%U)]
+// CHECK:STDOUT:   %Class: type = class_type @Class, @Class(%U.1) [symbolic = %Class (constants.%Class.4)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1: type = unbound_element_type @H.%Class (%Class.4), @H.%U.1 (%U) [symbolic = %.1 (constants.%.6)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%U.loc23: type, %c: @H.%Class (%Class.4)) -> %U {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %c.ref: @H.%Class (%Class.4) = name_ref c, %c
+// CHECK:STDOUT:     %x.ref: @H.%.1 (%.6) = name_ref x, @Class.%.loc12 [template = @Class.%.loc12]
+// CHECK:STDOUT:     %.loc24_11.1: ref @H.%U.1 (%U) = class_element_access %c.ref, element0
+// CHECK:STDOUT:     %.loc24_11.2: @H.%U.1 (%U) = bind_value %.loc24_11.1
+// CHECK:STDOUT:     return %.loc24_11.2
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc11_13.2 => constants.%T
+// CHECK:STDOUT: specific @Class(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT:
-// CHECK:STDOUT: definition:
-// CHECK:STDOUT:   <unexpected>.inst+17 => constants.%Class.2
-// CHECK:STDOUT:   <unexpected>.inst+18 => constants.%.2
-// CHECK:STDOUT:   <unexpected>.inst+14.loc12_8 => <unexpected>.inst+15
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Class => constants.%Class.2
+// CHECK:STDOUT:   %.1 => constants.%.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(file.%T.loc11_13.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc11_13.2 => constants.%T
+// CHECK:STDOUT: specific @Class(@Class.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(i32) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc11_13.2 => i32
+// CHECK:STDOUT: specific @Class(i32) {
+// CHECK:STDOUT:   %T => i32
 // CHECK:STDOUT:
-// CHECK:STDOUT: definition:
-// CHECK:STDOUT:   <unexpected>.inst+17 => constants.%Class.3
-// CHECK:STDOUT:   <unexpected>.inst+18 => constants.%.4
-// CHECK:STDOUT:   <unexpected>.inst+14.loc12_8 => <unexpected>.inst+15
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Class => constants.%Class.3
+// CHECK:STDOUT:   %.1 => constants.%.4
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%G.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @G.%T => constants.%T
-// CHECK:STDOUT:   file.%.loc19_24 => constants.%Class.2
+// CHECK:STDOUT: specific @Class(@G.%T.1) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(constants.%U) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc11_13.2 => constants.%U
+// CHECK:STDOUT: specific @G(constants.%T) {
+// CHECK:STDOUT:   %T.1 => constants.%T
+// CHECK:STDOUT:   %Class => constants.%Class.2
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Class(constants.%U) {
+// CHECK:STDOUT:   %T => constants.%U
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Class => constants.%Class.4
+// CHECK:STDOUT:   %.1 => constants.%.6
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: definition:
-// CHECK:STDOUT:   <unexpected>.inst+17 => constants.%Class.4
-// CHECK:STDOUT:   <unexpected>.inst+18 => constants.%.6
-// CHECK:STDOUT:   <unexpected>.inst+14.loc12_8 => <unexpected>.inst+15
+// CHECK:STDOUT: specific @Class(@H.%U.1) {
+// CHECK:STDOUT:   %T => constants.%U
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%H.decl(constants.%U) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @H.%U => constants.%U
-// CHECK:STDOUT:   file.%.loc23_24 => constants.%Class.4
+// CHECK:STDOUT: specific @H(constants.%U) {
+// CHECK:STDOUT:   %U.1 => constants.%U
+// CHECK:STDOUT:   %Class => constants.%Class.4
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 110 - 99
toolchain/check/testdata/class/generic/import.carbon

@@ -95,10 +95,10 @@ class Class(U:! type) {
 // CHECK:STDOUT:   %Class.type: type = generic_class_type @Class [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %Class.1: %Class.type = struct_value () [template]
-// CHECK:STDOUT:   %Class.2: type = class_type @Class, file.%Class.decl(%T) [symbolic]
+// CHECK:STDOUT:   %Class.2: type = class_type @Class, @Class(%T) [symbolic]
 // CHECK:STDOUT:   %CompleteClass.type: type = generic_class_type @CompleteClass [template]
 // CHECK:STDOUT:   %CompleteClass.1: %CompleteClass.type = struct_value () [template]
-// CHECK:STDOUT:   %CompleteClass.2: type = class_type @CompleteClass, file.%CompleteClass.decl(%T) [symbolic]
+// CHECK:STDOUT:   %CompleteClass.2: type = class_type @CompleteClass, @CompleteClass(%T) [symbolic]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %.2: type = unbound_element_type %CompleteClass.2, i32 [symbolic]
@@ -106,7 +106,7 @@ class Class(U:! type) {
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
 // CHECK:STDOUT:   %.3: type = struct_type {.n: i32} [template]
 // CHECK:STDOUT:   %.4: i32 = int_literal 0 [template]
-// CHECK:STDOUT:   %CompleteClass.3: type = class_type @CompleteClass, file.%CompleteClass.decl(i32) [template]
+// CHECK:STDOUT:   %CompleteClass.3: type = class_type @CompleteClass, @CompleteClass(i32) [template]
 // CHECK:STDOUT:   %F.type.2: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.2: %F.type.2 = struct_value () [template]
 // CHECK:STDOUT: }
@@ -136,11 +136,11 @@ class Class(U:! type) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Class.decl: %Class.type = class_decl @Class [template = constants.%Class.1] {
 // CHECK:STDOUT:     %T.loc4_13.1: type = param T
-// CHECK:STDOUT:     %T.loc4_13.2: type = bind_symbolic_name T 0, %T.loc4_13.1 [symbolic = %T.loc4_13.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc4_13.2: type = bind_symbolic_name T 0, %T.loc4_13.1 [symbolic = @Class.%T (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %CompleteClass.decl: %CompleteClass.type = class_decl @CompleteClass [template = constants.%CompleteClass.1] {
 // CHECK:STDOUT:     %T.loc6_21.1: type = param T
-// CHECK:STDOUT:     %T.loc6_21.2: type = bind_symbolic_name T 0, %T.loc6_21.1 [symbolic = %T.loc6_21.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc6_21.2: type = bind_symbolic_name T 0, %T.loc6_21.1 [symbolic = @CompleteClass.%T (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type.2 = fn_decl @F.2 [template = constants.%F.2] {
 // CHECK:STDOUT:     %CompleteClass.ref: %CompleteClass.type = name_ref CompleteClass, %CompleteClass.decl [template = constants.%CompleteClass.1]
@@ -154,61 +154,68 @@ class Class(U:! type) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @Class
-// CHECK:STDOUT:     generic [file.%T.loc4_13.2: type];
-// CHECK:STDOUT:
-// CHECK:STDOUT: class @CompleteClass
-// CHECK:STDOUT:     generic [file.%T.loc6_21.2: type] {
-// CHECK:STDOUT:   %int.make_type_32.loc7: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %.loc7_10.1: type = value_of_initializer %int.make_type_32.loc7 [template = i32]
-// CHECK:STDOUT:   %.loc7_10.2: type = converted %int.make_type_32.loc7, %.loc7_10.1 [template = i32]
-// CHECK:STDOUT:   %.loc7_8: <unexpected>.inst+39 (%.2) = field_decl n, element0 [template]
-// CHECK:STDOUT:   %F.decl: %F.type.1 = fn_decl @F.1 [template = constants.%F.1] {
-// CHECK:STDOUT:     %int.make_type_32.loc8: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:     %.loc8_13.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
-// CHECK:STDOUT:     %.loc8_13.2: type = converted %int.make_type_32.loc8, %.loc8_13.1 [template = i32]
-// CHECK:STDOUT:     %return.var: ref i32 = var <return slot>
-// CHECK:STDOUT:   }
+// CHECK:STDOUT: generic class @Class(file.%T.loc4_13.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%CompleteClass.2
-// CHECK:STDOUT:   .n = %.loc7_8
-// CHECK:STDOUT:   .F = %F.decl
+// CHECK:STDOUT:   class;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic class @CompleteClass(file.%T.loc6_21.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %CompleteClass: type = class_type @CompleteClass, @CompleteClass(%T) [symbolic = %CompleteClass (constants.%CompleteClass.2)]
+// CHECK:STDOUT:   %.1: type = unbound_element_type @CompleteClass.%CompleteClass (%CompleteClass.2), i32 [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:     %int.make_type_32.loc7: init type = call constants.%Int32() [template = i32]
+// CHECK:STDOUT:     %.loc7_10.1: type = value_of_initializer %int.make_type_32.loc7 [template = i32]
+// CHECK:STDOUT:     %.loc7_10.2: type = converted %int.make_type_32.loc7, %.loc7_10.1 [template = i32]
+// CHECK:STDOUT:     %.loc7_8: @CompleteClass.%.1 (%.2) = field_decl n, element0 [template]
+// CHECK:STDOUT:     %F.decl: %F.type.1 = fn_decl @F.1 [template = constants.%F.1] {
+// CHECK:STDOUT:       %int.make_type_32.loc8: init type = call constants.%Int32() [template = i32]
+// CHECK:STDOUT:       %.loc8_13.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
+// CHECK:STDOUT:       %.loc8_13.2: type = converted %int.make_type_32.loc8, %.loc8_13.1 [template = i32]
+// CHECK:STDOUT:       %return.var: ref i32 = var <return slot>
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%CompleteClass.2
+// CHECK:STDOUT:     .n = %.loc7_8
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.1() -> i32
-// CHECK:STDOUT:     generic [file.%T.loc6_21.2: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc8: i32 = int_literal 0 [template = constants.%.4]
-// CHECK:STDOUT:   return %.loc8
+// CHECK:STDOUT: generic fn @F.1(file.%T.loc6_21.2: type) {
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn() -> i32 {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %.loc8: i32 = int_literal 0 [template = constants.%.4]
+// CHECK:STDOUT:     return %.loc8
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.2() -> %CompleteClass.3;
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_13.2 => constants.%T
+// CHECK:STDOUT: specific @Class(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%CompleteClass.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc6_21.2 => constants.%T
+// CHECK:STDOUT: specific @CompleteClass(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @CompleteClass.%F.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT: }
+// CHECK:STDOUT: specific @F.1(constants.%T) {}
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%CompleteClass.decl(file.%T.loc6_21.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc6_21.2 => constants.%T
+// CHECK:STDOUT: specific @CompleteClass(@CompleteClass.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%CompleteClass.decl(i32) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc6_21.2 => i32
+// CHECK:STDOUT: specific @CompleteClass(i32) {
+// CHECK:STDOUT:   %T => i32
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- foo.impl.carbon
@@ -218,16 +225,16 @@ class Class(U:! type) {
 // CHECK:STDOUT:   %Class.type: type = generic_class_type @Class [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %Class.1: %Class.type = struct_value () [template]
-// CHECK:STDOUT:   %Class.2: type = class_type @Class, <invalid>(%T) [symbolic]
+// CHECK:STDOUT:   %Class.2: type = class_type @Class, invalid(%T) [symbolic]
 // CHECK:STDOUT:   %.2: type = unbound_element_type %Class.2, %T [symbolic]
 // CHECK:STDOUT:   %.3: type = struct_type {.x: %T} [symbolic]
 // CHECK:STDOUT:   %CompleteClass.type: type = generic_class_type @CompleteClass [template]
 // CHECK:STDOUT:   %CompleteClass.1: %CompleteClass.type = struct_value () [template]
 // CHECK:STDOUT:   %.4: type = struct_type {.n: i32} [template]
-// CHECK:STDOUT:   %CompleteClass.2: type = class_type @CompleteClass, <invalid>(%T) [symbolic]
+// CHECK:STDOUT:   %CompleteClass.2: type = class_type @CompleteClass, invalid(%T) [symbolic]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT:   %CompleteClass.3: type = class_type @CompleteClass, <invalid>(i32) [template]
+// CHECK:STDOUT:   %CompleteClass.3: type = class_type @CompleteClass, invalid(i32) [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT:   %.5: type = ptr_type %.4 [template]
@@ -237,11 +244,11 @@ class Class(U:! type) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %import_ref.1: %Class.type = import_ref Main//foo, inst+6, loaded [template = constants.%Class.1]
-// CHECK:STDOUT:   %import_ref.2: %CompleteClass.type = import_ref Main//foo, inst+13, loaded [template = constants.%CompleteClass.1]
-// CHECK:STDOUT:   %import_ref.3: %F.type = import_ref Main//foo, inst+53, loaded [template = constants.%F]
-// CHECK:STDOUT:   %import_ref.4 = import_ref Main//foo, inst+16, unloaded
-// CHECK:STDOUT:   %import_ref.5 = import_ref Main//foo, inst+26, unloaded
-// CHECK:STDOUT:   %import_ref.6 = import_ref Main//foo, inst+34, unloaded
+// CHECK:STDOUT:   %import_ref.2: %CompleteClass.type = import_ref Main//foo, inst+14, loaded [template = constants.%CompleteClass.1]
+// CHECK:STDOUT:   %import_ref.3: %F.type = import_ref Main//foo, inst+55, loaded [template = constants.%F]
+// CHECK:STDOUT:   %import_ref.4 = import_ref Main//foo, inst+18, unloaded
+// CHECK:STDOUT:   %import_ref.5 = import_ref Main//foo, inst+28, unloaded
+// CHECK:STDOUT:   %import_ref.6 = import_ref Main//foo, inst+36, unloaded
 // CHECK:STDOUT:   %import_ref.7: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -309,9 +316,9 @@ class Class(U:! type) {
 // CHECK:STDOUT:   return %.loc9_18 to %return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%T);
+// CHECK:STDOUT: specific invalid(constants.%T);
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(i32);
+// CHECK:STDOUT: specific invalid(i32);
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- use_foo.carbon
 // CHECK:STDOUT:
@@ -325,8 +332,8 @@ class Class(U:! type) {
 // CHECK:STDOUT:   %CompleteClass.1: %CompleteClass.type = struct_value () [template]
 // CHECK:STDOUT:   %.2: type = struct_type {.n: i32} [template]
 // CHECK:STDOUT:   %T: type = bind_symbolic_name T 0, <unexpected>.inst+28 [symbolic]
-// CHECK:STDOUT:   %CompleteClass.2: type = class_type @CompleteClass, <invalid>(%T) [symbolic]
-// CHECK:STDOUT:   %CompleteClass.3: type = class_type @CompleteClass, <invalid>(i32) [template]
+// CHECK:STDOUT:   %CompleteClass.2: type = class_type @CompleteClass, invalid(%T) [symbolic]
+// CHECK:STDOUT:   %CompleteClass.3: type = class_type @CompleteClass, invalid(i32) [template]
 // CHECK:STDOUT:   %.3: type = ptr_type %.2 [template]
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
@@ -336,12 +343,12 @@ class Class(U:! type) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %import_ref.1 = import_ref Main//foo, inst+6, unloaded
-// CHECK:STDOUT:   %import_ref.2: %CompleteClass.type = import_ref Main//foo, inst+13, loaded [template = constants.%CompleteClass.1]
-// CHECK:STDOUT:   %import_ref.3: %F.type.1 = import_ref Main//foo, inst+53, loaded [template = constants.%F.1]
+// CHECK:STDOUT:   %import_ref.2: %CompleteClass.type = import_ref Main//foo, inst+14, loaded [template = constants.%CompleteClass.1]
+// CHECK:STDOUT:   %import_ref.3: %F.type.1 = import_ref Main//foo, inst+55, loaded [template = constants.%F.1]
 // CHECK:STDOUT:   %import_ref.4: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
-// CHECK:STDOUT:   %import_ref.5 = import_ref Main//foo, inst+16, unloaded
-// CHECK:STDOUT:   %import_ref.6 = import_ref Main//foo, inst+26, unloaded
-// CHECK:STDOUT:   %import_ref.7: %F.type.2 = import_ref Main//foo, inst+34, loaded [template = constants.%F.2]
+// CHECK:STDOUT:   %import_ref.5 = import_ref Main//foo, inst+18, unloaded
+// CHECK:STDOUT:   %import_ref.6 = import_ref Main//foo, inst+28, unloaded
+// CHECK:STDOUT:   %import_ref.7: %F.type.2 = import_ref Main//foo, inst+36, loaded [template = constants.%F.2]
 // CHECK:STDOUT:   %import_ref.8: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -408,9 +415,9 @@ class Class(U:! type) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.2() -> i32;
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%T);
+// CHECK:STDOUT: specific invalid(constants.%T);
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(i32);
+// CHECK:STDOUT: specific invalid(i32);
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_todo_use_foo.carbon
 // CHECK:STDOUT:
@@ -424,8 +431,8 @@ class Class(U:! type) {
 // CHECK:STDOUT:   %CompleteClass.1: %CompleteClass.type = struct_value () [template]
 // CHECK:STDOUT:   %.2: type = struct_type {.n: i32} [template]
 // CHECK:STDOUT:   %T: type = bind_symbolic_name T 0, <unexpected>.inst+28 [symbolic]
-// CHECK:STDOUT:   %CompleteClass.2: type = class_type @CompleteClass, <invalid>(%T) [symbolic]
-// CHECK:STDOUT:   %CompleteClass.3: type = class_type @CompleteClass, <invalid>(i32) [template]
+// CHECK:STDOUT:   %CompleteClass.2: type = class_type @CompleteClass, invalid(%T) [symbolic]
+// CHECK:STDOUT:   %CompleteClass.3: type = class_type @CompleteClass, invalid(i32) [template]
 // CHECK:STDOUT:   %.3: type = ptr_type %.2 [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
@@ -434,12 +441,12 @@ class Class(U:! type) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %import_ref.1 = import_ref Main//foo, inst+6, unloaded
-// CHECK:STDOUT:   %import_ref.2: %CompleteClass.type = import_ref Main//foo, inst+13, loaded [template = constants.%CompleteClass.1]
-// CHECK:STDOUT:   %import_ref.3: %F.type = import_ref Main//foo, inst+53, loaded [template = constants.%F]
+// CHECK:STDOUT:   %import_ref.2: %CompleteClass.type = import_ref Main//foo, inst+14, loaded [template = constants.%CompleteClass.1]
+// CHECK:STDOUT:   %import_ref.3: %F.type = import_ref Main//foo, inst+55, loaded [template = constants.%F]
 // CHECK:STDOUT:   %import_ref.4: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
-// CHECK:STDOUT:   %import_ref.5 = import_ref Main//foo, inst+16, unloaded
-// CHECK:STDOUT:   %import_ref.6: %.4 = import_ref Main//foo, inst+26, loaded [template = %.1]
-// CHECK:STDOUT:   %import_ref.7 = import_ref Main//foo, inst+34, unloaded
+// CHECK:STDOUT:   %import_ref.5 = import_ref Main//foo, inst+18, unloaded
+// CHECK:STDOUT:   %import_ref.6: %.4 = import_ref Main//foo, inst+28, loaded [template = %.1]
+// CHECK:STDOUT:   %import_ref.7 = import_ref Main//foo, inst+36, unloaded
 // CHECK:STDOUT:   %import_ref.8: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -502,9 +509,9 @@ class Class(U:! type) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() -> %CompleteClass.3;
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%T);
+// CHECK:STDOUT: specific invalid(constants.%T);
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(i32);
+// CHECK:STDOUT: specific invalid(i32);
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_generic_arg_mismatch.carbon
 // CHECK:STDOUT:
@@ -516,24 +523,24 @@ class Class(U:! type) {
 // CHECK:STDOUT:   %CompleteClass.1: %CompleteClass.type = struct_value () [template]
 // CHECK:STDOUT:   %.2: type = struct_type {.n: i32} [template]
 // CHECK:STDOUT:   %T: type = bind_symbolic_name T 0, <unexpected>.inst+19 [symbolic]
-// CHECK:STDOUT:   %CompleteClass.2: type = class_type @CompleteClass, <invalid>(%T) [symbolic]
+// CHECK:STDOUT:   %CompleteClass.2: type = class_type @CompleteClass, invalid(%T) [symbolic]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %.3: type = ptr_type i32 [template]
-// CHECK:STDOUT:   %CompleteClass.3: type = class_type @CompleteClass, <invalid>(%.3) [template]
+// CHECK:STDOUT:   %CompleteClass.3: type = class_type @CompleteClass, invalid(%.3) [template]
 // CHECK:STDOUT:   %.4: type = ptr_type %.2 [template]
-// CHECK:STDOUT:   %CompleteClass.4: type = class_type @CompleteClass, <invalid>(i32) [template]
+// CHECK:STDOUT:   %CompleteClass.4: type = class_type @CompleteClass, invalid(i32) [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %import_ref.1 = import_ref Main//foo, inst+6, unloaded
-// CHECK:STDOUT:   %import_ref.2: %CompleteClass.type = import_ref Main//foo, inst+13, loaded [template = constants.%CompleteClass.1]
-// CHECK:STDOUT:   %import_ref.3: %F.type = import_ref Main//foo, inst+53, loaded [template = constants.%F]
-// CHECK:STDOUT:   %import_ref.4 = import_ref Main//foo, inst+16, unloaded
-// CHECK:STDOUT:   %import_ref.5 = import_ref Main//foo, inst+26, unloaded
-// CHECK:STDOUT:   %import_ref.6 = import_ref Main//foo, inst+34, unloaded
+// CHECK:STDOUT:   %import_ref.2: %CompleteClass.type = import_ref Main//foo, inst+14, loaded [template = constants.%CompleteClass.1]
+// CHECK:STDOUT:   %import_ref.3: %F.type = import_ref Main//foo, inst+55, loaded [template = constants.%F]
+// CHECK:STDOUT:   %import_ref.4 = import_ref Main//foo, inst+18, unloaded
+// CHECK:STDOUT:   %import_ref.5 = import_ref Main//foo, inst+28, unloaded
+// CHECK:STDOUT:   %import_ref.6 = import_ref Main//foo, inst+36, unloaded
 // CHECK:STDOUT:   %import_ref.7: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -589,11 +596,11 @@ class Class(U:! type) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() -> %CompleteClass.4;
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%T);
+// CHECK:STDOUT: specific invalid(constants.%T);
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%.3);
+// CHECK:STDOUT: specific invalid(constants.%.3);
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(i32);
+// CHECK:STDOUT: specific invalid(i32);
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_bad_foo.impl.carbon
 // CHECK:STDOUT:
@@ -603,16 +610,16 @@ class Class(U:! type) {
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %Class.1: %Class.type = struct_value () [template]
 // CHECK:STDOUT:   %T: type = bind_symbolic_name T 0, <unexpected>.inst+17 [symbolic]
-// CHECK:STDOUT:   %Class.2: type = class_type @Class, <invalid>(%T) [symbolic]
+// CHECK:STDOUT:   %Class.2: type = class_type @Class, invalid(%T) [symbolic]
 // CHECK:STDOUT:   %.type: type = generic_class_type @.1 [template]
 // CHECK:STDOUT:   %.2: %.type = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = class_type @.1, file.%.decl(%U) [symbolic]
+// CHECK:STDOUT:   %.3: type = class_type @.1, @.1(%U) [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %import_ref.1: %Class.type = import_ref Main//foo, inst+6, loaded [template = constants.%Class.1]
-// CHECK:STDOUT:   %import_ref.2 = import_ref Main//foo, inst+13, unloaded
-// CHECK:STDOUT:   %import_ref.3 = import_ref Main//foo, inst+53, unloaded
+// CHECK:STDOUT:   %import_ref.2 = import_ref Main//foo, inst+14, unloaded
+// CHECK:STDOUT:   %import_ref.3 = import_ref Main//foo, inst+55, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -636,26 +643,30 @@ class Class(U:! type) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.decl: %.type = class_decl @.1 [template = constants.%.2] {
 // CHECK:STDOUT:     %U.loc9_13.1: type = param U
-// CHECK:STDOUT:     %U.loc9_13.2: type = bind_symbolic_name U 0, %U.loc9_13.1 [symbolic = %U.loc9_13.2 (constants.%U)]
+// CHECK:STDOUT:     %U.loc9_13.2: type = bind_symbolic_name U 0, %U.loc9_13.1 [symbolic = @.1.%U (constants.%U)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class;
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @.1
-// CHECK:STDOUT:     generic [file.%U.loc9_13.2: type] {
-// CHECK:STDOUT:   %T.ref: <error> = name_ref T, <error> [template = <error>]
-// CHECK:STDOUT:   %.loc13: <error> = field_decl x, element0 [template]
+// CHECK:STDOUT: generic class @.1(file.%U.loc9_13.2: type) {
+// CHECK:STDOUT:   %U: type = bind_symbolic_name U 0 [symbolic = %U (constants.%U)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%.3
-// CHECK:STDOUT:   .x = %.loc13
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:     %T.ref: <error> = name_ref T, <error> [template = <error>]
+// CHECK:STDOUT:     %.loc13: <error> = field_decl x, element0 [template]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%.3
+// CHECK:STDOUT:     .x = %.loc13
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%T);
+// CHECK:STDOUT: specific invalid(constants.%T);
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%.decl(constants.%U) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%U.loc9_13.2 => constants.%U
+// CHECK:STDOUT: specific @.1(constants.%U) {
+// CHECK:STDOUT:   %U => constants.%U
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 74 - 56
toolchain/check/testdata/class/generic/member_inline.carbon

@@ -27,7 +27,7 @@ class Class(T:! type) {
 // CHECK:STDOUT:   %Class.type: type = generic_class_type @Class [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %Class.1: %Class.type = struct_value () [template]
-// CHECK:STDOUT:   %Class.2: type = class_type @Class, file.%Class.decl(%T) [symbolic]
+// CHECK:STDOUT:   %Class.2: type = class_type @Class, @Class(%T) [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
@@ -54,77 +54,95 @@ class Class(T:! type) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Class.decl: %Class.type = class_decl @Class [template = constants.%Class.1] {
 // CHECK:STDOUT:     %T.loc11_13.1: type = param T
-// CHECK:STDOUT:     %T.loc11_13.2: type = bind_symbolic_name T 0, %T.loc11_13.1 [symbolic = %T.loc11_13.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc11_13.2: type = bind_symbolic_name T 0, %T.loc11_13.1 [symbolic = @Class.%T (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @Class
-// CHECK:STDOUT:     generic [file.%T.loc11_13.2: type] {
-// CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
-// CHECK:STDOUT:     %T.ref.loc12_11: type = name_ref T, file.%T.loc11_13.2 [symbolic = %T.ref.loc12_11 (constants.%T)]
-// CHECK:STDOUT:     %n.loc12_8.1: @Class.%T.ref.loc12_11 (%T) = param n
-// CHECK:STDOUT:     %n.loc12_8.2: @Class.%T.ref.loc12_11 (%T) = bind_name n, %n.loc12_8.1
-// CHECK:STDOUT:     %T.ref.loc12_17: type = name_ref T, file.%T.loc11_13.2 [symbolic = %T.ref.loc12_11 (constants.%T)]
-// CHECK:STDOUT:     %return.var.loc12: ref %T = var <return slot>
-// CHECK:STDOUT:   }
-// CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [template = constants.%G] {
-// CHECK:STDOUT:     %.loc16: type = specific_constant constants.%Class.2, file.%Class.decl(constants.%T) [symbolic = %.loc16 (constants.%Class.2)]
-// CHECK:STDOUT:     %Self.ref: type = name_ref Self, %.loc16 [symbolic = %.loc16 (constants.%Class.2)]
-// CHECK:STDOUT:     %self.loc16_8.1: @Class.%.loc16 (%Class.2) = param self
-// CHECK:STDOUT:     %self.loc16_8.2: @Class.%.loc16 (%Class.2) = bind_name self, %self.loc16_8.1
-// CHECK:STDOUT:     %T.ref.loc16: type = name_ref T, file.%T.loc11_13.2 [symbolic = %T.ref.loc16 (constants.%T)]
-// CHECK:STDOUT:     %return.var.loc16: ref %T = var <return slot>
+// CHECK:STDOUT: generic class @Class(file.%T.loc11_13.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class.2)]
+// CHECK:STDOUT:   %.1: type = unbound_element_type @Class.%Class (%Class.2), @Class.%T (%T) [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:     %F.decl: %F.type = fn_decl @F [template = constants.%F] {
+// CHECK:STDOUT:       %T.ref.loc12_11: type = name_ref T, file.%T.loc11_13.2 [symbolic = @F.%T (constants.%T)]
+// CHECK:STDOUT:       %n.loc12_8.1: @F.%T (%T) = param n
+// CHECK:STDOUT:       %n.loc12_8.2: @F.%T (%T) = bind_name n, %n.loc12_8.1
+// CHECK:STDOUT:       %T.ref.loc12_17: type = name_ref T, file.%T.loc11_13.2 [symbolic = @F.%T (constants.%T)]
+// CHECK:STDOUT:       %return.var.loc12: ref %T = var <return slot>
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %G.decl: %G.type = fn_decl @G [template = constants.%G] {
+// CHECK:STDOUT:       %.loc16: type = specific_constant constants.%Class.2, @Class(constants.%T) [symbolic = @G.%Class (constants.%Class.2)]
+// CHECK:STDOUT:       %Self.ref: type = name_ref Self, %.loc16 [symbolic = @G.%Class (constants.%Class.2)]
+// CHECK:STDOUT:       %self.loc16_8.1: @G.%Class (%Class.2) = param self
+// CHECK:STDOUT:       %self.loc16_8.2: @G.%Class (%Class.2) = bind_name self, %self.loc16_8.1
+// CHECK:STDOUT:       %T.ref.loc16: type = name_ref T, file.%T.loc11_13.2 [symbolic = @G.%T (constants.%T)]
+// CHECK:STDOUT:       %return.var.loc16: ref %T = var <return slot>
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %T.ref.loc20: type = name_ref T, file.%T.loc11_13.2 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:     %.loc20: @Class.%.1 (%.2) = field_decl n, element0 [template]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%Class.2
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:     .G = %G.decl
+// CHECK:STDOUT:     .n = %.loc20
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %T.ref.loc20: type = name_ref T, file.%T.loc11_13.2 [symbolic = file.%T.loc11_13.2 (constants.%T)]
-// CHECK:STDOUT:   %.loc20: <unexpected>.inst+35 (%.2) = field_decl n, element0 [template]
-// CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%Class.2
-// CHECK:STDOUT:   .F = %F.decl
-// CHECK:STDOUT:   .G = %G.decl
-// CHECK:STDOUT:   .n = %.loc20
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F(@Class.%n.loc12_8.2: @Class.%T.ref.loc12_11 (%T)) -> %T
-// CHECK:STDOUT:     generic [file.%T.loc11_13.2: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %n.ref: @Class.%T.ref.loc12_11 (%T) = name_ref n, @Class.%n.loc12_8.2
-// CHECK:STDOUT:   return %n.ref
+// CHECK:STDOUT: generic fn @F(file.%T.loc11_13.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(@Class.%n.loc12_8.2: @F.%T (%T)) -> %T {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %n.ref: @F.%T (%T) = name_ref n, @Class.%n.loc12_8.2
+// CHECK:STDOUT:     return %n.ref
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @G[@Class.%self.loc16_8.2: @Class.%.loc16 (%Class.2)]() -> %T
-// CHECK:STDOUT:     generic [file.%T.loc11_13.2: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %self.ref: @Class.%.loc16 (%Class.2) = name_ref self, @Class.%self.loc16_8.2
-// CHECK:STDOUT:   %n.ref: <unexpected>.inst+44 (%.2) = name_ref n, @Class.%.loc20 [template = @Class.%.loc20]
-// CHECK:STDOUT:   %.loc17_16.1: ref @Class.%T.ref.loc16 (%T) = class_element_access %self.ref, element0
-// CHECK:STDOUT:   %.loc17_16.2: @Class.%T.ref.loc16 (%T) = bind_value %.loc17_16.1
-// CHECK:STDOUT:   return %.loc17_16.2
+// CHECK:STDOUT: generic fn @G(file.%T.loc11_13.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1: type = unbound_element_type @G.%Class (%Class.2), @G.%T (%T) [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn[@Class.%self.loc16_8.2: @G.%Class (%Class.2)]() -> %T {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %self.ref: @G.%Class (%Class.2) = name_ref self, @Class.%self.loc16_8.2
+// CHECK:STDOUT:     %n.ref: @G.%.1 (%.2) = name_ref n, @Class.%.loc20 [template = @Class.%.loc20]
+// CHECK:STDOUT:     %.loc17_16.1: ref @G.%T (%T) = class_element_access %self.ref, element0
+// CHECK:STDOUT:     %.loc17_16.2: @G.%T (%T) = bind_value %.loc17_16.1
+// CHECK:STDOUT:     return %.loc17_16.2
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc11_13.2 => constants.%T
+// CHECK:STDOUT: specific @Class(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Class => constants.%Class.2
+// CHECK:STDOUT:   %.1 => constants.%.2
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: definition:
-// CHECK:STDOUT:   <unexpected>.inst+34 => constants.%Class.2
-// CHECK:STDOUT:   <unexpected>.inst+35 => constants.%.2
-// CHECK:STDOUT:   <unexpected>.inst+31.loc20_8 => <unexpected>.inst+32
+// CHECK:STDOUT: specific @F(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Class.%F.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @Class.%T.ref.loc12_11 => constants.%T
+// CHECK:STDOUT: specific @Class(@G.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Class.%G.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @Class.%.loc16 => constants.%Class.2
-// CHECK:STDOUT:   @Class.%T.ref.loc16 => constants.%T
+// CHECK:STDOUT: specific @G(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %Class => constants.%Class.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(file.%T.loc11_13.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc11_13.2 => constants.%T
+// CHECK:STDOUT: specific @Class(@Class.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 238 - 174
toolchain/check/testdata/class/generic/member_out_of_line.carbon

@@ -112,7 +112,7 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:   %Class.type: type = generic_class_type @Class [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %Class.1: %Class.type = struct_value () [template]
-// CHECK:STDOUT:   %Class.2: type = class_type @Class, file.%Class.decl(%T) [symbolic]
+// CHECK:STDOUT:   %Class.2: type = class_type @Class, @Class(%T) [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
@@ -139,7 +139,7 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Class.decl: %Class.type = class_decl @Class [template = constants.%Class.1] {
 // CHECK:STDOUT:     %T.loc4_13.1: type = param T
-// CHECK:STDOUT:     %T.loc4_13.2: type = bind_symbolic_name T 0, %T.loc4_13.1 [symbolic = %T.loc4_13.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc4_13.2: type = bind_symbolic_name T 0, %T.loc4_13.1 [symbolic = @Class.%T (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
 // CHECK:STDOUT:     %T.loc10_10.1: type = param T
@@ -153,7 +153,7 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [template = constants.%G] {
 // CHECK:STDOUT:     %T.loc14_10.1: type = param T
 // CHECK:STDOUT:     %T.loc14_10.2: type = bind_symbolic_name T 0, %T.loc14_10.1 [symbolic = constants.%T]
-// CHECK:STDOUT:     %.loc14: type = specific_constant constants.%Class.2, %Class.decl(constants.%T) [symbolic = constants.%Class.2]
+// CHECK:STDOUT:     %.loc14: type = specific_constant constants.%Class.2, @Class(constants.%T) [symbolic = constants.%Class.2]
 // CHECK:STDOUT:     %Self.ref: type = name_ref Self, %.loc14 [symbolic = constants.%Class.2]
 // CHECK:STDOUT:     %self.loc14_22.1: %Class.2 = param self
 // CHECK:STDOUT:     @G.%self: %Class.2 = bind_name self, %self.loc14_22.1
@@ -162,74 +162,92 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @Class
-// CHECK:STDOUT:     generic [file.%T.loc4_13.2: type] {
-// CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
-// CHECK:STDOUT:     %T.ref.loc5_11: type = name_ref T, file.%T.loc4_13.2 [symbolic = %T.ref.loc5_11 (constants.%T)]
-// CHECK:STDOUT:     %n.loc5_8.1: @Class.%T.ref.loc5_11 (%T) = param n
-// CHECK:STDOUT:     %n.loc5_8.2: @Class.%T.ref.loc5_11 (%T) = bind_name n, %n.loc5_8.1
-// CHECK:STDOUT:     %T.ref.loc5_17: type = name_ref T, file.%T.loc4_13.2 [symbolic = %T.ref.loc5_11 (constants.%T)]
-// CHECK:STDOUT:     %return.var.loc5: ref %T = var <return slot>
-// CHECK:STDOUT:   }
-// CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [template = constants.%G] {
-// CHECK:STDOUT:     %.loc6: type = specific_constant constants.%Class.2, file.%Class.decl(constants.%T) [symbolic = %.loc6 (constants.%Class.2)]
-// CHECK:STDOUT:     %Self.ref: type = name_ref Self, %.loc6 [symbolic = %.loc6 (constants.%Class.2)]
-// CHECK:STDOUT:     %self.loc6_8.1: @Class.%.loc6 (%Class.2) = param self
-// CHECK:STDOUT:     %self.loc6_8.2: @Class.%.loc6 (%Class.2) = bind_name self, %self.loc6_8.1
-// CHECK:STDOUT:     %T.ref.loc6: type = name_ref T, file.%T.loc4_13.2 [symbolic = %T.ref.loc6 (constants.%T)]
-// CHECK:STDOUT:     %return.var.loc6: ref %T = var <return slot>
+// CHECK:STDOUT: generic class @Class(file.%T.loc4_13.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class.2)]
+// CHECK:STDOUT:   %.1: type = unbound_element_type @Class.%Class (%Class.2), @Class.%T (%T) [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:     %F.decl: %F.type = fn_decl @F [template = constants.%F] {
+// CHECK:STDOUT:       %T.ref.loc5_11: type = name_ref T, file.%T.loc4_13.2 [symbolic = @F.%T (constants.%T)]
+// CHECK:STDOUT:       %n.loc5_8.1: @F.%T (%T) = param n
+// CHECK:STDOUT:       %n.loc5_8.2: @F.%T (%T) = bind_name n, %n.loc5_8.1
+// CHECK:STDOUT:       %T.ref.loc5_17: type = name_ref T, file.%T.loc4_13.2 [symbolic = @F.%T (constants.%T)]
+// CHECK:STDOUT:       %return.var.loc5: ref %T = var <return slot>
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %G.decl: %G.type = fn_decl @G [template = constants.%G] {
+// CHECK:STDOUT:       %.loc6: type = specific_constant constants.%Class.2, @Class(constants.%T) [symbolic = @G.%Class (constants.%Class.2)]
+// CHECK:STDOUT:       %Self.ref: type = name_ref Self, %.loc6 [symbolic = @G.%Class (constants.%Class.2)]
+// CHECK:STDOUT:       %self.loc6_8.1: @G.%Class (%Class.2) = param self
+// CHECK:STDOUT:       %self.loc6_8.2: @G.%Class (%Class.2) = bind_name self, %self.loc6_8.1
+// CHECK:STDOUT:       %T.ref.loc6: type = name_ref T, file.%T.loc4_13.2 [symbolic = @G.%T (constants.%T)]
+// CHECK:STDOUT:       %return.var.loc6: ref %T = var <return slot>
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %T.ref.loc7: type = name_ref T, file.%T.loc4_13.2 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:     %.loc7: @Class.%.1 (%.2) = field_decl n, element0 [template]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%Class.2
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:     .G = %G.decl
+// CHECK:STDOUT:     .n = %.loc7
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %T.ref.loc7: type = name_ref T, file.%T.loc4_13.2 [symbolic = file.%T.loc4_13.2 (constants.%T)]
-// CHECK:STDOUT:   %.loc7: <unexpected>.inst+35 (%.2) = field_decl n, element0 [template]
-// CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%Class.2
-// CHECK:STDOUT:   .F = %F.decl
-// CHECK:STDOUT:   .G = %G.decl
-// CHECK:STDOUT:   .n = %.loc7
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F(%n: %T) -> %T
-// CHECK:STDOUT:     generic [file.%T.loc4_13.2: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %n.ref: @Class.%T.ref.loc5_11 (%T) = name_ref n, %n
-// CHECK:STDOUT:   return %n.ref
+// CHECK:STDOUT: generic fn @F(file.%T.loc4_13.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%n: %T) -> %T {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %n.ref: @F.%T (%T) = name_ref n, %n
+// CHECK:STDOUT:     return %n.ref
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @G[%self: %Class.2]() -> %T
-// CHECK:STDOUT:     generic [file.%T.loc4_13.2: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %self.ref: @Class.%.loc6 (%Class.2) = name_ref self, %self
-// CHECK:STDOUT:   %n.ref: <unexpected>.inst+61 (%.2) = name_ref n, @Class.%.loc7 [template = @Class.%.loc7]
-// CHECK:STDOUT:   %.loc15_14.1: ref @Class.%T.ref.loc6 (%T) = class_element_access %self.ref, element0
-// CHECK:STDOUT:   %.loc15_14.2: @Class.%T.ref.loc6 (%T) = bind_value %.loc15_14.1
-// CHECK:STDOUT:   return %.loc15_14.2
+// CHECK:STDOUT: generic fn @G(file.%T.loc4_13.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1: type = unbound_element_type @G.%Class (%Class.2), @G.%T (%T) [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn[%self: %Class.2]() -> %T {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %self.ref: @G.%Class (%Class.2) = name_ref self, %self
+// CHECK:STDOUT:     %n.ref: @G.%.1 (%.2) = name_ref n, @Class.%.loc7 [template = @Class.%.loc7]
+// CHECK:STDOUT:     %.loc15_14.1: ref @G.%T (%T) = class_element_access %self.ref, element0
+// CHECK:STDOUT:     %.loc15_14.2: @G.%T (%T) = bind_value %.loc15_14.1
+// CHECK:STDOUT:     return %.loc15_14.2
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_13.2 => constants.%T
+// CHECK:STDOUT: specific @Class(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Class => constants.%Class.2
+// CHECK:STDOUT:   %.1 => constants.%.2
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: definition:
-// CHECK:STDOUT:   <unexpected>.inst+34 => constants.%Class.2
-// CHECK:STDOUT:   <unexpected>.inst+35 => constants.%.2
-// CHECK:STDOUT:   <unexpected>.inst+31.loc7_8 => <unexpected>.inst+32
+// CHECK:STDOUT: specific @F(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Class.%F.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @Class.%T.ref.loc5_11 => constants.%T
+// CHECK:STDOUT: specific @Class(@G.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Class.%G.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @Class.%.loc6 => constants.%Class.2
-// CHECK:STDOUT:   @Class.%T.ref.loc6 => constants.%T
+// CHECK:STDOUT: specific @G(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %Class => constants.%Class.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(file.%T.loc4_13.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_13.2 => constants.%T
+// CHECK:STDOUT: specific @Class(@Class.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- nested.carbon
@@ -239,11 +257,11 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:   %A.type: type = generic_class_type @A [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %A.1: %A.type = struct_value () [template]
-// CHECK:STDOUT:   %A.2: type = class_type @A, file.%A.decl(%T) [symbolic]
+// CHECK:STDOUT:   %A.2: type = class_type @A, @A(%T) [symbolic]
 // CHECK:STDOUT:   %N: %T = bind_symbolic_name N 1 [symbolic]
 // CHECK:STDOUT:   %B.type: type = generic_class_type @B [template]
 // CHECK:STDOUT:   %B.1: %B.type = struct_value () [template]
-// CHECK:STDOUT:   %B.2: type = class_type @B, @A.%B.decl(%T, %N) [symbolic]
+// CHECK:STDOUT:   %B.2: type = class_type @B, @B(%T, %N) [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
@@ -267,7 +285,7 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %A.decl: %A.type = class_decl @A [template = constants.%A.1] {
 // CHECK:STDOUT:     %T.loc4_9.1: type = param T
-// CHECK:STDOUT:     %T.loc4_9.2: type = bind_symbolic_name T 0, %T.loc4_9.1 [symbolic = %T.loc4_9.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc4_9.2: type = bind_symbolic_name T 0, %T.loc4_9.1 [symbolic = @A.%T (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
 // CHECK:STDOUT:     %T.loc10_6.1: type = param T
@@ -275,7 +293,7 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:     %T.ref.loc10_22: type = name_ref T, %T.loc10_6.2 [symbolic = constants.%T]
 // CHECK:STDOUT:     %N.loc10_18.1: %T = param N
 // CHECK:STDOUT:     %N.loc10_18.2: %T = bind_symbolic_name N 1, %N.loc10_18.1 [symbolic = constants.%N]
-// CHECK:STDOUT:     %.loc10: type = specific_constant constants.%B.2, @A.%B.decl(constants.%T, constants.%N) [symbolic = constants.%B.2]
+// CHECK:STDOUT:     %.loc10: type = specific_constant constants.%B.2, @B(constants.%T, constants.%N) [symbolic = constants.%B.2]
 // CHECK:STDOUT:     %Self.ref: type = name_ref Self, %.loc10 [symbolic = constants.%B.2]
 // CHECK:STDOUT:     %self.loc10_27.1: %B.2 = param self
 // CHECK:STDOUT:     @F.%self: %B.2 = bind_name self, %self.loc10_27.1
@@ -285,61 +303,82 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @A
-// CHECK:STDOUT:     generic [file.%T.loc4_9.2: type] {
-// CHECK:STDOUT:   %B.decl: %B.type = class_decl @B [template = constants.%B.1] {
-// CHECK:STDOUT:     %T.ref: type = name_ref T, file.%T.loc4_9.2 [symbolic = %T.ref (constants.%T)]
-// CHECK:STDOUT:     %N.loc5_11.1: @A.%T.ref (%T) = param N
-// CHECK:STDOUT:     %N.loc5_11.2: @A.%T.ref (%T) = bind_symbolic_name N 1, %N.loc5_11.1 [symbolic = %N.loc5_11.2 (constants.%N)]
-// CHECK:STDOUT:   }
+// CHECK:STDOUT: generic class @A(file.%T.loc4_9.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%A.2
-// CHECK:STDOUT:   .B = %B.decl
-// CHECK:STDOUT: }
+// CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @B
-// CHECK:STDOUT:     generic [file.%T.loc4_9.2: type, @A.%N.loc5_11.2: @A.%T.ref (%T)] {
-// CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
-// CHECK:STDOUT:     %.loc6: type = specific_constant constants.%B.2, @A.%B.decl(constants.%T, constants.%N) [symbolic = %.loc6 (constants.%B.2)]
-// CHECK:STDOUT:     %Self.ref: type = name_ref Self, %.loc6 [symbolic = %.loc6 (constants.%B.2)]
-// CHECK:STDOUT:     %self.loc6_10.1: @B.%.loc6 (%B.2) = param self
-// CHECK:STDOUT:     %self.loc6_10.2: @B.%.loc6 (%B.2) = bind_name self, %self.loc6_10.1
-// CHECK:STDOUT:     %T.ref: type = name_ref T, file.%T.loc4_9.2 [symbolic = %T.ref (constants.%T)]
-// CHECK:STDOUT:     %a.loc6_22.1: @B.%T.ref (%T) = param a
-// CHECK:STDOUT:     %a.loc6_22.2: @B.%T.ref (%T) = bind_name a, %a.loc6_22.1
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:     %B.decl: %B.type = class_decl @B [template = constants.%B.1] {
+// CHECK:STDOUT:       %T.ref: type = name_ref T, file.%T.loc4_9.2 [symbolic = @B.%T (constants.%T)]
+// CHECK:STDOUT:       %N.loc5_11.1: @B.%T (%T) = param N
+// CHECK:STDOUT:       %N.loc5_11.2: @B.%T (%T) = bind_symbolic_name N 1, %N.loc5_11.1 [symbolic = @B.%N (constants.%N)]
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%A.2
+// CHECK:STDOUT:     .B = %B.decl
 // CHECK:STDOUT:   }
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%B.2
-// CHECK:STDOUT:   .F = %F.decl
+// CHECK:STDOUT: generic class @B(file.%T.loc4_9.2: type, @A.%N.loc5_11.2: @B.%T (%T)) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %N: %T = bind_symbolic_name N 1 [symbolic = %N (constants.%N)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:     %F.decl: %F.type = fn_decl @F [template = constants.%F] {
+// CHECK:STDOUT:       %.loc6: type = specific_constant constants.%B.2, @B(constants.%T, constants.%N) [symbolic = @F.%B (constants.%B.2)]
+// CHECK:STDOUT:       %Self.ref: type = name_ref Self, %.loc6 [symbolic = @F.%B (constants.%B.2)]
+// CHECK:STDOUT:       %self.loc6_10.1: @F.%B (%B.2) = param self
+// CHECK:STDOUT:       %self.loc6_10.2: @F.%B (%B.2) = bind_name self, %self.loc6_10.1
+// CHECK:STDOUT:       %T.ref: type = name_ref T, file.%T.loc4_9.2 [symbolic = @F.%T (constants.%T)]
+// CHECK:STDOUT:       %a.loc6_22.1: @F.%T (%T) = param a
+// CHECK:STDOUT:       %a.loc6_22.2: @F.%T (%T) = bind_name a, %a.loc6_22.1
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%B.2
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F[%self: %B.2](%a: %T)
-// CHECK:STDOUT:     generic [file.%T.loc4_9.2: type, @A.%N.loc5_11.2: @A.%T.ref (%T)] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   return
+// CHECK:STDOUT: generic fn @F(file.%T.loc4_9.2: type, @A.%N.loc5_11.2: @B.%T (%T)) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %N: %T = bind_symbolic_name N 1 [symbolic = %N (constants.%N)]
+// CHECK:STDOUT:   %B: type = class_type @B, @B(%T, %N) [symbolic = %B (constants.%B.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn[%self: %B.2](%a: %T) {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%A.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_9.2 => constants.%T
+// CHECK:STDOUT: specific @A(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT:
-// CHECK:STDOUT: definition:
+// CHECK:STDOUT: !definition:
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @A.%B.decl(constants.%T, constants.%N) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @A.%T.ref => constants.%T
-// CHECK:STDOUT:   @A.%N.loc5_11.2 => constants.%N
+// CHECK:STDOUT: specific @B(constants.%T, constants.%N) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %N => constants.%N
 // CHECK:STDOUT:
-// CHECK:STDOUT: definition:
+// CHECK:STDOUT: !definition:
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @B.%F.decl(constants.%T, constants.%N) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @B.%.loc6 => constants.%B.2
-// CHECK:STDOUT:   @B.%T.ref => constants.%T
+// CHECK:STDOUT: specific @B(@F.%T, @F.%N) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %N => constants.%N
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F(constants.%T, constants.%N) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %N => constants.%N
+// CHECK:STDOUT:   %B => constants.%B.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_mismatched_not_generic_vs_generic.carbon
@@ -373,7 +412,7 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:   %NotGeneric.decl: type = class_decl @NotGeneric [template = constants.%NotGeneric] {}
 // CHECK:STDOUT:   %.decl: %.type = fn_decl @.1 [template = constants.%.3] {
 // CHECK:STDOUT:     %T.loc15_15.1: type = param T
-// CHECK:STDOUT:     %T.loc15_15.2: type = bind_symbolic_name T 0, %T.loc15_15.1 [symbolic = %T.loc15_15.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc15_15.2: type = bind_symbolic_name T 0, %T.loc15_15.1 [symbolic = @.1.%T (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -387,15 +426,19 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F();
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @.1()
-// CHECK:STDOUT:     generic [file.%T.loc15_15.2: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   return
+// CHECK:STDOUT: generic fn @.1(file.%T.loc15_15.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn() {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc15_15.2 => constants.%T
+// CHECK:STDOUT: specific @.1(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_mismatched_too_few_args.carbon
@@ -405,7 +448,7 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:   %Generic.type: type = generic_class_type @Generic [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %Generic.1: %Generic.type = struct_value () [template]
-// CHECK:STDOUT:   %Generic.2: type = class_type @Generic, file.%Generic.decl(%T) [symbolic]
+// CHECK:STDOUT:   %Generic.2: type = class_type @Generic, @Generic(%T) [symbolic]
 // CHECK:STDOUT:   %TooFew.type: type = fn_type @TooFew [template]
 // CHECK:STDOUT:   %TooFew: %TooFew.type = struct_value () [template]
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
@@ -430,36 +473,40 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Generic.decl: %Generic.type = class_decl @Generic [template = constants.%Generic.1] {
 // CHECK:STDOUT:     %T.loc4_15.1: type = param T
-// CHECK:STDOUT:     %T.loc4_15.2: type = bind_symbolic_name T 0, %T.loc4_15.1 [symbolic = %T.loc4_15.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc4_15.2: type = bind_symbolic_name T 0, %T.loc4_15.1 [symbolic = @Generic.%T (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.decl: %.type = fn_decl @.1 [template = constants.%.3] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @Generic
-// CHECK:STDOUT:     generic [file.%T.loc4_15.2: type] {
-// CHECK:STDOUT:   %TooFew.decl: %TooFew.type = fn_decl @TooFew [template = constants.%TooFew] {}
+// CHECK:STDOUT: generic class @Generic(file.%T.loc4_15.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%Generic.2
-// CHECK:STDOUT:   .TooFew = %TooFew.decl
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:     %TooFew.decl: %TooFew.type = fn_decl @TooFew [template = constants.%TooFew] {}
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%Generic.2
+// CHECK:STDOUT:     .TooFew = %TooFew.decl
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @TooFew()
-// CHECK:STDOUT:     generic [file.%T.loc4_15.2: type];
+// CHECK:STDOUT: generic fn @TooFew(file.%T.loc4_15.2: type) {
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn();
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @.1() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Generic.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_15.2 => constants.%T
+// CHECK:STDOUT: specific @Generic(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Generic.%TooFew.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT: }
+// CHECK:STDOUT: specific @TooFew(constants.%T) {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_mismatched_too_many_args.carbon
 // CHECK:STDOUT:
@@ -468,7 +515,7 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:   %Generic.type: type = generic_class_type @Generic [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %Generic.1: %Generic.type = struct_value () [template]
-// CHECK:STDOUT:   %Generic.2: type = class_type @Generic, file.%Generic.decl(%T) [symbolic]
+// CHECK:STDOUT:   %Generic.2: type = class_type @Generic, @Generic(%T) [symbolic]
 // CHECK:STDOUT:   %TooMany.type: type = fn_type @TooMany [template]
 // CHECK:STDOUT:   %TooMany: %TooMany.type = struct_value () [template]
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
@@ -494,47 +541,56 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Generic.decl: %Generic.type = class_decl @Generic [template = constants.%Generic.1] {
 // CHECK:STDOUT:     %T.loc4_15.1: type = param T
-// CHECK:STDOUT:     %T.loc4_15.2: type = bind_symbolic_name T 0, %T.loc4_15.1 [symbolic = %T.loc4_15.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc4_15.2: type = bind_symbolic_name T 0, %T.loc4_15.1 [symbolic = @Generic.%T (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.decl: %.type = fn_decl @.1 [template = constants.%.3] {
 // CHECK:STDOUT:     %T.loc15_12.1: type = param T
-// CHECK:STDOUT:     %T.loc15_12.2: type = bind_symbolic_name T 0, %T.loc15_12.1 [symbolic = %T.loc15_12.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc15_12.2: type = bind_symbolic_name T 0, %T.loc15_12.1 [symbolic = @.1.%T (constants.%T)]
 // CHECK:STDOUT:     %U.loc15_22.1: type = param U
-// CHECK:STDOUT:     %U.loc15_22.2: type = bind_symbolic_name U 1, %U.loc15_22.1 [symbolic = %U.loc15_22.2 (constants.%U)]
+// CHECK:STDOUT:     %U.loc15_22.2: type = bind_symbolic_name U 1, %U.loc15_22.1 [symbolic = @.1.%U (constants.%U)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @Generic
-// CHECK:STDOUT:     generic [file.%T.loc4_15.2: type] {
-// CHECK:STDOUT:   %TooMany.decl: %TooMany.type = fn_decl @TooMany [template = constants.%TooMany] {}
+// CHECK:STDOUT: generic class @Generic(file.%T.loc4_15.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%Generic.2
-// CHECK:STDOUT:   .TooMany = %TooMany.decl
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:     %TooMany.decl: %TooMany.type = fn_decl @TooMany [template = constants.%TooMany] {}
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%Generic.2
+// CHECK:STDOUT:     .TooMany = %TooMany.decl
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @TooMany()
-// CHECK:STDOUT:     generic [file.%T.loc4_15.2: type];
+// CHECK:STDOUT: generic fn @TooMany(file.%T.loc4_15.2: type) {
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @.1()
-// CHECK:STDOUT:     generic [file.%T.loc15_12.2: type, file.%U.loc15_22.2: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   return
+// CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Generic.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_15.2 => constants.%T
+// CHECK:STDOUT: generic fn @.1(file.%T.loc15_12.2: type, file.%U.loc15_22.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %U: type = bind_symbolic_name U 1 [symbolic = %U (constants.%U)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn() {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Generic.%TooMany.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
+// CHECK:STDOUT: specific @Generic(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%.decl(constants.%T, constants.%U) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc15_12.2 => constants.%T
-// CHECK:STDOUT:   file.%U.loc15_22.2 => constants.%U
+// CHECK:STDOUT: specific @TooMany(constants.%T) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @.1(constants.%T, constants.%U) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %U => constants.%U
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_mismatched_wrong_arg_type.carbon
@@ -544,7 +600,7 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:   %Generic.type: type = generic_class_type @Generic [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %Generic.1: %Generic.type = struct_value () [template]
-// CHECK:STDOUT:   %Generic.2: type = class_type @Generic, file.%Generic.decl(%T.1) [symbolic]
+// CHECK:STDOUT:   %Generic.2: type = class_type @Generic, @Generic(%T.1) [symbolic]
 // CHECK:STDOUT:   %WrongType.type: type = fn_type @WrongType [template]
 // CHECK:STDOUT:   %WrongType: %WrongType.type = struct_value () [template]
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
@@ -570,45 +626,53 @@ fn Generic(T:! ()).WrongType() {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Generic.decl: %Generic.type = class_decl @Generic [template = constants.%Generic.1] {
 // CHECK:STDOUT:     %T.loc4_15.1: type = param T
-// CHECK:STDOUT:     %T.loc4_15.2: type = bind_symbolic_name T 0, %T.loc4_15.1 [symbolic = %T.loc4_15.2 (constants.%T.1)]
+// CHECK:STDOUT:     %T.loc4_15.2: type = bind_symbolic_name T 0, %T.loc4_15.1 [symbolic = @Generic.%T (constants.%T.1)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.decl: %.type = fn_decl @.1 [template = constants.%.3] {
 // CHECK:STDOUT:     %.loc14_17.1: %.1 = tuple_literal ()
 // CHECK:STDOUT:     %.loc14_17.2: type = converted %.loc14_17.1, constants.%.1 [template = constants.%.1]
 // CHECK:STDOUT:     %T.loc14_12.1: %.1 = param T
-// CHECK:STDOUT:     %T.loc14_12.2: %.1 = bind_symbolic_name T 0, %T.loc14_12.1 [symbolic = %T.loc14_12.2 (constants.%T.2)]
+// CHECK:STDOUT:     %T.loc14_12.2: %.1 = bind_symbolic_name T 0, %T.loc14_12.1 [symbolic = @.1.%T (constants.%T.2)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @Generic
-// CHECK:STDOUT:     generic [file.%T.loc4_15.2: type] {
-// CHECK:STDOUT:   %WrongType.decl: %WrongType.type = fn_decl @WrongType [template = constants.%WrongType] {}
+// CHECK:STDOUT: generic class @Generic(file.%T.loc4_15.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T.1)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%Generic.2
-// CHECK:STDOUT:   .WrongType = %WrongType.decl
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:     %WrongType.decl: %WrongType.type = fn_decl @WrongType [template = constants.%WrongType] {}
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%Generic.2
+// CHECK:STDOUT:     .WrongType = %WrongType.decl
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @WrongType()
-// CHECK:STDOUT:     generic [file.%T.loc4_15.2: type];
+// CHECK:STDOUT: generic fn @WrongType(file.%T.loc4_15.2: type) {
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @.1()
-// CHECK:STDOUT:     generic [file.%T.loc14_12.2: %.1] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   return
+// CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Generic.decl(constants.%T.1) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_15.2 => constants.%T.1
+// CHECK:STDOUT: generic fn @.1(file.%T.loc14_12.2: %.1) {
+// CHECK:STDOUT:   %T: %.1 = bind_symbolic_name T 0 [symbolic = %T (constants.%T.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn() {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Generic.%WrongType.decl(constants.%T.1) {
-// CHECK:STDOUT: declaration:
+// CHECK:STDOUT: specific @Generic(constants.%T.1) {
+// CHECK:STDOUT:   %T => constants.%T.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%.decl(constants.%T.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc14_12.2 => constants.%T.2
+// CHECK:STDOUT: specific @WrongType(constants.%T.1) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @.1(constants.%T.2) {
+// CHECK:STDOUT:   %T => constants.%T.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 122 - 88
toolchain/check/testdata/class/generic/redeclare.carbon

@@ -93,7 +93,7 @@ class E(U:! type) {}
 // CHECK:STDOUT:   %Generic.type: type = generic_class_type @Generic [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %Generic.1: %Generic.type = struct_value () [template]
-// CHECK:STDOUT:   %Generic.2: type = class_type @Generic, file.%Generic.decl.loc4(%T) [symbolic]
+// CHECK:STDOUT:   %Generic.2: type = class_type @Generic, @Generic(%T) [symbolic]
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -114,7 +114,7 @@ class E(U:! type) {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Generic.decl.loc4: %Generic.type = class_decl @Generic [template = constants.%Generic.1] {
 // CHECK:STDOUT:     %T.loc4_15.1: type = param T
-// CHECK:STDOUT:     %T.loc4_15.2: type = bind_symbolic_name T 0, %T.loc4_15.1 [symbolic = %T.loc4_15.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc4_15.2: type = bind_symbolic_name T 0, %T.loc4_15.1 [symbolic = @Generic.%T (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Generic.decl.loc6: %Generic.type = class_decl @Generic [template = constants.%Generic.1] {
 // CHECK:STDOUT:     %T.loc6_15.1: type = param T
@@ -122,15 +122,19 @@ class E(U:! type) {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @Generic
-// CHECK:STDOUT:     generic [file.%T.loc4_15.2: type] {
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%Generic.2
+// CHECK:STDOUT: generic class @Generic(file.%T.loc4_15.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%Generic.2
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Generic.decl.loc4(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_15.2 => constants.%T
+// CHECK:STDOUT: specific @Generic(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_mismatch_param_list.carbon
@@ -141,7 +145,7 @@ class E(U:! type) {}
 // CHECK:STDOUT:   %.type: type = generic_class_type @.1 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %.2: %.type = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = class_type @.1, file.%.decl(%T) [symbolic]
+// CHECK:STDOUT:   %.3: type = class_type @.1, @.1(%T) [symbolic]
 // CHECK:STDOUT:   %.4: type = struct_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -163,21 +167,25 @@ class E(U:! type) {}
 // CHECK:STDOUT:   %A.decl: type = class_decl @A [template = constants.%A] {}
 // CHECK:STDOUT:   %.decl: %.type = class_decl @.1 [template = constants.%.2] {
 // CHECK:STDOUT:     %T.loc12_9.1: type = param T
-// CHECK:STDOUT:     %T.loc12_9.2: type = bind_symbolic_name T 0, %T.loc12_9.1 [symbolic = %T.loc12_9.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc12_9.2: type = bind_symbolic_name T 0, %T.loc12_9.1 [symbolic = @.1.%T (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @A;
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @.1
-// CHECK:STDOUT:     generic [file.%T.loc12_9.2: type] {
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%.3
+// CHECK:STDOUT: generic class @.1(file.%T.loc12_9.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%.3
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc12_9.2 => constants.%T
+// CHECK:STDOUT: specific @.1(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_mismatch_implicit_param_list.carbon
@@ -189,12 +197,12 @@ class E(U:! type) {}
 // CHECK:STDOUT:   %N.1: i32 = bind_symbolic_name N 0 [symbolic]
 // CHECK:STDOUT:   %B.type: type = generic_class_type @B [template]
 // CHECK:STDOUT:   %B.1: %B.type = struct_value () [template]
-// CHECK:STDOUT:   %B.2: type = class_type @B, file.%B.decl(%N.1) [symbolic]
+// CHECK:STDOUT:   %B.2: type = class_type @B, @B(%N.1) [symbolic]
 // CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic]
 // CHECK:STDOUT:   %N.2: %T = bind_symbolic_name N 1 [symbolic]
 // CHECK:STDOUT:   %.type: type = generic_class_type @.1 [template]
 // CHECK:STDOUT:   %.2: %.type = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = class_type @.1, file.%.decl(%T, %N.2) [symbolic]
+// CHECK:STDOUT:   %.3: type = class_type @.1, @.1(%T, %N.2) [symbolic]
 // CHECK:STDOUT:   %.4: type = struct_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -222,37 +230,44 @@ class E(U:! type) {}
 // CHECK:STDOUT:     %.loc4_13.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:     %.loc4_13.2: type = converted %int.make_type_32, %.loc4_13.1 [template = i32]
 // CHECK:STDOUT:     %N.loc4_9.1: i32 = param N
-// CHECK:STDOUT:     %N.loc4_9.2: i32 = bind_symbolic_name N 0, %N.loc4_9.1 [symbolic = %N.loc4_9.2 (constants.%N.1)]
+// CHECK:STDOUT:     %N.loc4_9.2: i32 = bind_symbolic_name N 0, %N.loc4_9.1 [symbolic = @B.%N (constants.%N.1)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.decl: %.type = class_decl @.1 [template = constants.%.2] {
 // CHECK:STDOUT:     %T.loc12_9.1: type = param T
-// CHECK:STDOUT:     %T.loc12_9.2: type = bind_symbolic_name T 0, %T.loc12_9.1 [symbolic = %T.loc12_9.2 (constants.%T)]
-// CHECK:STDOUT:     %T.ref: type = name_ref T, %T.loc12_9.2 [symbolic = %T.loc12_9.2 (constants.%T)]
-// CHECK:STDOUT:     %N.loc12_19.1: file.%T.loc12_9.2 (%T) = param N
-// CHECK:STDOUT:     %N.loc12_19.2: file.%T.loc12_9.2 (%T) = bind_symbolic_name N 1, %N.loc12_19.1 [symbolic = %N.loc12_19.2 (constants.%N.2)]
+// CHECK:STDOUT:     %T.loc12_9.2: type = bind_symbolic_name T 0, %T.loc12_9.1 [symbolic = @.1.%T (constants.%T)]
+// CHECK:STDOUT:     %T.ref: type = name_ref T, %T.loc12_9.2 [symbolic = @.1.%T (constants.%T)]
+// CHECK:STDOUT:     %N.loc12_19.1: @.1.%T (%T) = param N
+// CHECK:STDOUT:     %N.loc12_19.2: @.1.%T (%T) = bind_symbolic_name N 1, %N.loc12_19.1 [symbolic = @.1.%N (constants.%N.2)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @B
-// CHECK:STDOUT:     generic [file.%N.loc4_9.2: i32];
+// CHECK:STDOUT: generic class @B(file.%N.loc4_9.2: i32) {
+// CHECK:STDOUT:   %N: i32 = bind_symbolic_name N 0 [symbolic = %N (constants.%N.1)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @.1
-// CHECK:STDOUT:     generic [file.%T.loc12_9.2: type, file.%N.loc12_19.2: file.%T.loc12_9.2 (%T)] {
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%.3
+// CHECK:STDOUT:   class;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic class @.1(file.%T.loc12_9.2: type, file.%N.loc12_19.2: @.1.%T (%T)) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %N: %T = bind_symbolic_name N 1 [symbolic = %N (constants.%N.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%.3
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%B.decl(constants.%N.1) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%N.loc4_9.2 => constants.%N.1
+// CHECK:STDOUT: specific @B(constants.%N.1) {
+// CHECK:STDOUT:   %N => constants.%N.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%.decl(constants.%T, constants.%N.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc12_9.2 => constants.%T
-// CHECK:STDOUT:   file.%N.loc12_19.2 => constants.%N.2
+// CHECK:STDOUT: specific @.1(constants.%T, constants.%N.2) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %N => constants.%N.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_mismatch_param_count.carbon
@@ -262,13 +277,13 @@ class E(U:! type) {}
 // CHECK:STDOUT:   %C.type: type = generic_class_type @C [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %C.1: %C.type = struct_value () [template]
-// CHECK:STDOUT:   %C.2: type = class_type @C, file.%C.decl(%T) [symbolic]
+// CHECK:STDOUT:   %C.2: type = class_type @C, @C(%T) [symbolic]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %U: i32 = bind_symbolic_name U 1 [symbolic]
 // CHECK:STDOUT:   %.type: type = generic_class_type @.1 [template]
 // CHECK:STDOUT:   %.2: %.type = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = class_type @.1, file.%.decl(%T, %U) [symbolic]
+// CHECK:STDOUT:   %.3: type = class_type @.1, @.1(%T, %U) [symbolic]
 // CHECK:STDOUT:   %.4: type = struct_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -293,39 +308,46 @@ class E(U:! type) {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %C.decl: %C.type = class_decl @C [template = constants.%C.1] {
 // CHECK:STDOUT:     %T.loc4_9.1: type = param T
-// CHECK:STDOUT:     %T.loc4_9.2: type = bind_symbolic_name T 0, %T.loc4_9.1 [symbolic = %T.loc4_9.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc4_9.2: type = bind_symbolic_name T 0, %T.loc4_9.1 [symbolic = @C.%T (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.decl: %.type = class_decl @.1 [template = constants.%.2] {
 // CHECK:STDOUT:     %T.loc12_9.1: type = param T
-// CHECK:STDOUT:     %T.loc12_9.2: type = bind_symbolic_name T 0, %T.loc12_9.1 [symbolic = %T.loc12_9.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc12_9.2: type = bind_symbolic_name T 0, %T.loc12_9.1 [symbolic = @.1.%T (constants.%T)]
 // CHECK:STDOUT:     %int.make_type_32: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:     %.loc12_23.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:     %.loc12_23.2: type = converted %int.make_type_32, %.loc12_23.1 [template = i32]
 // CHECK:STDOUT:     %U.loc12_19.1: i32 = param U
-// CHECK:STDOUT:     %U.loc12_19.2: i32 = bind_symbolic_name U 1, %U.loc12_19.1 [symbolic = %U.loc12_19.2 (constants.%U)]
+// CHECK:STDOUT:     %U.loc12_19.2: i32 = bind_symbolic_name U 1, %U.loc12_19.1 [symbolic = @.1.%U (constants.%U)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @C
-// CHECK:STDOUT:     generic [file.%T.loc4_9.2: type];
+// CHECK:STDOUT: generic class @C(file.%T.loc4_9.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic class @.1(file.%T.loc12_9.2: type, file.%U.loc12_19.2: i32) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %U: i32 = bind_symbolic_name U 1 [symbolic = %U (constants.%U)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @.1
-// CHECK:STDOUT:     generic [file.%T.loc12_9.2: type, file.%U.loc12_19.2: i32] {
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%.3
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%.3
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%C.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_9.2 => constants.%T
+// CHECK:STDOUT: specific @C(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%.decl(constants.%T, constants.%U) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc12_9.2 => constants.%T
-// CHECK:STDOUT:   file.%U.loc12_19.2 => constants.%U
+// CHECK:STDOUT: specific @.1(constants.%T, constants.%U) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %U => constants.%U
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_mismatch_param_type.carbon
@@ -335,13 +357,13 @@ class E(U:! type) {}
 // CHECK:STDOUT:   %D.type: type = generic_class_type @D [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %D.1: %D.type = struct_value () [template]
-// CHECK:STDOUT:   %D.2: type = class_type @D, file.%D.decl(%T.1) [symbolic]
+// CHECK:STDOUT:   %D.2: type = class_type @D, @D(%T.1) [symbolic]
 // CHECK:STDOUT:   %Int32.type: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %Int32: %Int32.type = struct_value () [template]
 // CHECK:STDOUT:   %T.2: i32 = bind_symbolic_name T 0 [symbolic]
 // CHECK:STDOUT:   %.type: type = generic_class_type @.1 [template]
 // CHECK:STDOUT:   %.2: %.type = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = class_type @.1, file.%.decl(%T.2) [symbolic]
+// CHECK:STDOUT:   %.3: type = class_type @.1, @.1(%T.2) [symbolic]
 // CHECK:STDOUT:   %.4: type = struct_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -366,36 +388,42 @@ class E(U:! type) {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %D.decl: %D.type = class_decl @D [template = constants.%D.1] {
 // CHECK:STDOUT:     %T.loc4_9.1: type = param T
-// CHECK:STDOUT:     %T.loc4_9.2: type = bind_symbolic_name T 0, %T.loc4_9.1 [symbolic = %T.loc4_9.2 (constants.%T.1)]
+// CHECK:STDOUT:     %T.loc4_9.2: type = bind_symbolic_name T 0, %T.loc4_9.1 [symbolic = @D.%T (constants.%T.1)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.decl: %.type = class_decl @.1 [template = constants.%.2] {
 // CHECK:STDOUT:     %int.make_type_32: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:     %.loc12_13.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:     %.loc12_13.2: type = converted %int.make_type_32, %.loc12_13.1 [template = i32]
 // CHECK:STDOUT:     %T.loc12_9.1: i32 = param T
-// CHECK:STDOUT:     %T.loc12_9.2: i32 = bind_symbolic_name T 0, %T.loc12_9.1 [symbolic = %T.loc12_9.2 (constants.%T.2)]
+// CHECK:STDOUT:     %T.loc12_9.2: i32 = bind_symbolic_name T 0, %T.loc12_9.1 [symbolic = @.1.%T (constants.%T.2)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @D
-// CHECK:STDOUT:     generic [file.%T.loc4_9.2: type];
+// CHECK:STDOUT: generic class @D(file.%T.loc4_9.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T.1)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @.1
-// CHECK:STDOUT:     generic [file.%T.loc12_9.2: i32] {
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%.3
+// CHECK:STDOUT:   class;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic class @.1(file.%T.loc12_9.2: i32) {
+// CHECK:STDOUT:   %T: i32 = bind_symbolic_name T 0 [symbolic = %T (constants.%T.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%.3
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%D.decl(constants.%T.1) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_9.2 => constants.%T.1
+// CHECK:STDOUT: specific @D(constants.%T.1) {
+// CHECK:STDOUT:   %T => constants.%T.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%.decl(constants.%T.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc12_9.2 => constants.%T.2
+// CHECK:STDOUT: specific @.1(constants.%T.2) {
+// CHECK:STDOUT:   %T => constants.%T.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_mismatch_param_name.carbon
@@ -405,11 +433,11 @@ class E(U:! type) {}
 // CHECK:STDOUT:   %E.type: type = generic_class_type @E [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %E.1: %E.type = struct_value () [template]
-// CHECK:STDOUT:   %E.2: type = class_type @E, file.%E.decl(%T) [symbolic]
+// CHECK:STDOUT:   %E.2: type = class_type @E, @E(%T) [symbolic]
 // CHECK:STDOUT:   %U: type = bind_symbolic_name U 0 [symbolic]
 // CHECK:STDOUT:   %.type: type = generic_class_type @.1 [template]
 // CHECK:STDOUT:   %.2: %.type = struct_value () [template]
-// CHECK:STDOUT:   %.3: type = class_type @.1, file.%.decl(%U) [symbolic]
+// CHECK:STDOUT:   %.3: type = class_type @.1, @.1(%U) [symbolic]
 // CHECK:STDOUT:   %.4: type = struct_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -430,30 +458,36 @@ class E(U:! type) {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %E.decl: %E.type = class_decl @E [template = constants.%E.1] {
 // CHECK:STDOUT:     %T.loc4_9.1: type = param T
-// CHECK:STDOUT:     %T.loc4_9.2: type = bind_symbolic_name T 0, %T.loc4_9.1 [symbolic = %T.loc4_9.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc4_9.2: type = bind_symbolic_name T 0, %T.loc4_9.1 [symbolic = @E.%T (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.decl: %.type = class_decl @.1 [template = constants.%.2] {
 // CHECK:STDOUT:     %U.loc11_9.1: type = param U
-// CHECK:STDOUT:     %U.loc11_9.2: type = bind_symbolic_name U 0, %U.loc11_9.1 [symbolic = %U.loc11_9.2 (constants.%U)]
+// CHECK:STDOUT:     %U.loc11_9.2: type = bind_symbolic_name U 0, %U.loc11_9.1 [symbolic = @.1.%U (constants.%U)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @E
-// CHECK:STDOUT:     generic [file.%T.loc4_9.2: type];
+// CHECK:STDOUT: generic class @E(file.%T.loc4_9.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic class @.1(file.%U.loc11_9.2: type) {
+// CHECK:STDOUT:   %U: type = bind_symbolic_name U 0 [symbolic = %U (constants.%U)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @.1
-// CHECK:STDOUT:     generic [file.%U.loc11_9.2: type] {
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%.3
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%.3
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%E.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_9.2 => constants.%T
+// CHECK:STDOUT: specific @E(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%.decl(constants.%U) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%U.loc11_9.2 => constants.%U
+// CHECK:STDOUT: specific @.1(constants.%U) {
+// CHECK:STDOUT:   %U => constants.%U
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 89 - 63
toolchain/check/testdata/class/generic/self.carbon

@@ -26,7 +26,7 @@ class Class(T:! type) {
 // CHECK:STDOUT:   %Class.type: type = generic_class_type @Class [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %Class.1: %Class.type = struct_value () [template]
-// CHECK:STDOUT:   %Class.2: type = class_type @Class, file.%Class.decl(%T) [symbolic]
+// CHECK:STDOUT:   %Class.2: type = class_type @Class, @Class(%T) [symbolic]
 // CHECK:STDOUT:   %MakeSelf.type: type = fn_type @MakeSelf [template]
 // CHECK:STDOUT:   %MakeSelf: %MakeSelf.type = struct_value () [template]
 // CHECK:STDOUT:   %MakeClass.type: type = fn_type @MakeClass [template]
@@ -54,84 +54,110 @@ class Class(T:! type) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Class.decl: %Class.type = class_decl @Class [template = constants.%Class.1] {
 // CHECK:STDOUT:     %T.loc11_13.1: type = param T
-// CHECK:STDOUT:     %T.loc11_13.2: type = bind_symbolic_name T 0, %T.loc11_13.1 [symbolic = %T.loc11_13.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc11_13.2: type = bind_symbolic_name T 0, %T.loc11_13.1 [symbolic = @Class.%T (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @Class
-// CHECK:STDOUT:     generic [file.%T.loc11_13.2: type] {
-// CHECK:STDOUT:   %MakeSelf.decl: %MakeSelf.type = fn_decl @MakeSelf [template = constants.%MakeSelf] {
-// CHECK:STDOUT:     %.loc14: type = specific_constant constants.%Class.2, file.%Class.decl(constants.%T) [symbolic = %.loc14 (constants.%Class.2)]
-// CHECK:STDOUT:     %Self.ref: type = name_ref Self, %.loc14 [symbolic = %.loc14 (constants.%Class.2)]
-// CHECK:STDOUT:     %return.var.loc14: ref %Class.2 = var <return slot>
+// CHECK:STDOUT: generic class @Class(file.%T.loc11_13.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:     %MakeSelf.decl: %MakeSelf.type = fn_decl @MakeSelf [template = constants.%MakeSelf] {
+// CHECK:STDOUT:       %.loc14: type = specific_constant constants.%Class.2, @Class(constants.%T) [symbolic = @MakeSelf.%Class (constants.%Class.2)]
+// CHECK:STDOUT:       %Self.ref: type = name_ref Self, %.loc14 [symbolic = @MakeSelf.%Class (constants.%Class.2)]
+// CHECK:STDOUT:       %return.var.loc14: ref %Class.2 = var <return slot>
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %MakeClass.decl: %MakeClass.type = fn_decl @MakeClass [template = constants.%MakeClass] {
+// CHECK:STDOUT:       %Class.ref: %Class.type = name_ref Class, file.%Class.decl [template = constants.%Class.1]
+// CHECK:STDOUT:       %T.ref: type = name_ref T, file.%T.loc11_13.2 [symbolic = @MakeClass.%T (constants.%T)]
+// CHECK:STDOUT:       %.loc15_26: init type = call %Class.ref(%T.ref) [symbolic = @MakeClass.%Class (constants.%Class.2)]
+// CHECK:STDOUT:       %.loc15_28.1: type = value_of_initializer %.loc15_26 [symbolic = @MakeClass.%Class (constants.%Class.2)]
+// CHECK:STDOUT:       %.loc15_28.2: type = converted %.loc15_26, %.loc15_28.1 [symbolic = @MakeClass.%Class (constants.%Class.2)]
+// CHECK:STDOUT:       %return.var.loc15: ref %Class.2 = var <return slot>
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %F.decl: %F.type = fn_decl @F [template = constants.%F] {}
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%Class.2
+// CHECK:STDOUT:     .MakeSelf = %MakeSelf.decl
+// CHECK:STDOUT:     .MakeClass = %MakeClass.decl
+// CHECK:STDOUT:     .F = %F.decl
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %MakeClass.decl: %MakeClass.type = fn_decl @MakeClass [template = constants.%MakeClass] {
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @MakeSelf(file.%T.loc11_13.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn() -> %Class.2;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @MakeClass(file.%T.loc11_13.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn() -> %Class.2;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @F(file.%T.loc11_13.2: type) {
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn() {
+// CHECK:STDOUT:   !entry:
 // CHECK:STDOUT:     %Class.ref: %Class.type = name_ref Class, file.%Class.decl [template = constants.%Class.1]
-// CHECK:STDOUT:     %T.ref: type = name_ref T, file.%T.loc11_13.2 [symbolic = %T.ref (constants.%T)]
-// CHECK:STDOUT:     %.loc15_26: init type = call %Class.ref(%T.ref) [symbolic = %.loc15_26 (constants.%Class.2)]
-// CHECK:STDOUT:     %.loc15_28.1: type = value_of_initializer %.loc15_26 [symbolic = %.loc15_26 (constants.%Class.2)]
-// CHECK:STDOUT:     %.loc15_28.2: type = converted %.loc15_26, %.loc15_28.1 [symbolic = %.loc15_26 (constants.%Class.2)]
-// CHECK:STDOUT:     %return.var.loc15: ref %Class.2 = var <return slot>
+// CHECK:STDOUT:     %T.ref: type = name_ref T, file.%T.loc11_13.2 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:     %.loc17_17: init type = call %Class.ref(%T.ref) [symbolic = %Class (constants.%Class.2)]
+// CHECK:STDOUT:     %.loc17_19.1: type = value_of_initializer %.loc17_17 [symbolic = %Class (constants.%Class.2)]
+// CHECK:STDOUT:     %.loc17_19.2: type = converted %.loc17_17, %.loc17_19.1 [symbolic = %Class (constants.%Class.2)]
+// CHECK:STDOUT:     %c.var: ref @F.%Class (%Class.2) = var c
+// CHECK:STDOUT:     %c: ref @F.%Class (%Class.2) = bind_name c, %c.var
+// CHECK:STDOUT:     %MakeSelf.ref: %MakeSelf.type = name_ref MakeSelf, @Class.%MakeSelf.decl [template = constants.%MakeSelf]
+// CHECK:STDOUT:     %.loc17_9: ref @F.%Class (%Class.2) = splice_block %c.var {}
+// CHECK:STDOUT:     %MakeSelf.call: init @F.%Class (%Class.2) = call %MakeSelf.ref() to %.loc17_9
+// CHECK:STDOUT:     assign %c.var, %MakeSelf.call
+// CHECK:STDOUT:     %.loc18_12: type = specific_constant constants.%Class.2, @Class(constants.%T) [symbolic = %Class (constants.%Class.2)]
+// CHECK:STDOUT:     %Self.ref: type = name_ref Self, %.loc18_12 [symbolic = %Class (constants.%Class.2)]
+// CHECK:STDOUT:     %s.var: ref @F.%Class (%Class.2) = var s
+// CHECK:STDOUT:     %s: ref @F.%Class (%Class.2) = bind_name s, %s.var
+// CHECK:STDOUT:     %MakeClass.ref: %MakeClass.type = name_ref MakeClass, @Class.%MakeClass.decl [template = constants.%MakeClass]
+// CHECK:STDOUT:     %.loc18_9: ref @F.%Class (%Class.2) = splice_block %s.var {}
+// CHECK:STDOUT:     %MakeClass.call: init @F.%Class (%Class.2) = call %MakeClass.ref() to %.loc18_9
+// CHECK:STDOUT:     assign %s.var, %MakeClass.call
+// CHECK:STDOUT:     return
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {}
-// CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%Class.2
-// CHECK:STDOUT:   .MakeSelf = %MakeSelf.decl
-// CHECK:STDOUT:   .MakeClass = %MakeClass.decl
-// CHECK:STDOUT:   .F = %F.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @MakeSelf() -> %Class.2
-// CHECK:STDOUT:     generic [file.%T.loc11_13.2: type];
-// CHECK:STDOUT:
-// CHECK:STDOUT: fn @MakeClass() -> %Class.2
-// CHECK:STDOUT:     generic [file.%T.loc11_13.2: type];
-// CHECK:STDOUT:
-// CHECK:STDOUT: fn @F()
-// CHECK:STDOUT:     generic [file.%T.loc11_13.2: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Class.ref: %Class.type = name_ref Class, file.%Class.decl [template = constants.%Class.1]
-// CHECK:STDOUT:   %T.ref: type = name_ref T, file.%T.loc11_13.2 [symbolic = %T.ref (constants.%T)]
-// CHECK:STDOUT:   %.loc17_17: init type = call %Class.ref(%T.ref) [symbolic = %.loc17_17 (constants.%Class.2)]
-// CHECK:STDOUT:   %.loc17_19.1: type = value_of_initializer %.loc17_17 [symbolic = %.loc17_17 (constants.%Class.2)]
-// CHECK:STDOUT:   %.loc17_19.2: type = converted %.loc17_17, %.loc17_19.1 [symbolic = %.loc17_17 (constants.%Class.2)]
-// CHECK:STDOUT:   %c.var: ref @F.%.loc17_17 (%Class.2) = var c
-// CHECK:STDOUT:   %c: ref @F.%.loc17_17 (%Class.2) = bind_name c, %c.var
-// CHECK:STDOUT:   %MakeSelf.ref: %MakeSelf.type = name_ref MakeSelf, @Class.%MakeSelf.decl [template = constants.%MakeSelf]
-// CHECK:STDOUT:   %.loc17_9: ref @F.%.loc17_17 (%Class.2) = splice_block %c.var {}
-// CHECK:STDOUT:   %MakeSelf.call: init @F.%.loc17_17 (%Class.2) = call %MakeSelf.ref() to %.loc17_9
-// CHECK:STDOUT:   assign %c.var, %MakeSelf.call
-// CHECK:STDOUT:   %.loc18_12: type = specific_constant constants.%Class.2, file.%Class.decl(constants.%T) [symbolic = %.loc17_17 (constants.%Class.2)]
-// CHECK:STDOUT:   %Self.ref: type = name_ref Self, %.loc18_12 [symbolic = %.loc17_17 (constants.%Class.2)]
-// CHECK:STDOUT:   %s.var: ref @F.%.loc17_17 (%Class.2) = var s
-// CHECK:STDOUT:   %s: ref @F.%.loc17_17 (%Class.2) = bind_name s, %s.var
-// CHECK:STDOUT:   %MakeClass.ref: %MakeClass.type = name_ref MakeClass, @Class.%MakeClass.decl [template = constants.%MakeClass]
-// CHECK:STDOUT:   %.loc18_9: ref @F.%.loc17_17 (%Class.2) = splice_block %s.var {}
-// CHECK:STDOUT:   %MakeClass.call: init @F.%.loc17_17 (%Class.2) = call %MakeClass.ref() to %.loc18_9
-// CHECK:STDOUT:   assign %s.var, %MakeClass.call
-// CHECK:STDOUT:   return
+// CHECK:STDOUT: specific @Class(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc11_13.2 => constants.%T
+// CHECK:STDOUT: specific @Class(@MakeSelf.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: definition:
+// CHECK:STDOUT: specific @MakeSelf(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %Class => constants.%Class.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Class.%MakeSelf.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @Class.%.loc14 => constants.%Class.2
+// CHECK:STDOUT: specific @Class(@MakeClass.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Class.%MakeClass.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @Class.%T.ref => constants.%T
-// CHECK:STDOUT:   @Class.%.loc15_26 => constants.%Class.2
+// CHECK:STDOUT: specific @MakeClass(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %Class => constants.%Class.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Class.%F.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
+// CHECK:STDOUT: specific @F(constants.%T) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Class(@F.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 51 - 38
toolchain/check/testdata/class/generic_method.carbon

@@ -22,7 +22,7 @@ fn Class(T:! type).F[self: Self](n: T) {}
 // CHECK:STDOUT:   %Class.type: type = generic_class_type @Class [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %Class.1: %Class.type = struct_value () [template]
-// CHECK:STDOUT:   %Class.2: type = class_type @Class, file.%Class.decl(%T) [symbolic]
+// CHECK:STDOUT:   %Class.2: type = class_type @Class, @Class(%T) [symbolic]
 // CHECK:STDOUT:   %.2: type = unbound_element_type %Class.2, %T [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
@@ -47,12 +47,12 @@ fn Class(T:! type).F[self: Self](n: T) {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Class.decl: %Class.type = class_decl @Class [template = constants.%Class.1] {
 // CHECK:STDOUT:     %T.loc11_13.1: type = param T
-// CHECK:STDOUT:     %T.loc11_13.2: type = bind_symbolic_name T 0, %T.loc11_13.1 [symbolic = %T.loc11_13.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc11_13.2: type = bind_symbolic_name T 0, %T.loc11_13.1 [symbolic = @Class.%T (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
 // CHECK:STDOUT:     %T.loc16_10.1: type = param T
 // CHECK:STDOUT:     %T.loc16_10.2: type = bind_symbolic_name T 0, %T.loc16_10.1 [symbolic = constants.%T]
-// CHECK:STDOUT:     %.loc16: type = specific_constant constants.%Class.2, %Class.decl(constants.%T) [symbolic = constants.%Class.2]
+// CHECK:STDOUT:     %.loc16: type = specific_constant constants.%Class.2, @Class(constants.%T) [symbolic = constants.%Class.2]
 // CHECK:STDOUT:     %Self.ref: type = name_ref Self, %.loc16 [symbolic = constants.%Class.2]
 // CHECK:STDOUT:     %self.loc16_22.1: %Class.2 = param self
 // CHECK:STDOUT:     @F.%self: %Class.2 = bind_name self, %self.loc16_22.1
@@ -62,50 +62,63 @@ fn Class(T:! type).F[self: Self](n: T) {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @Class
-// CHECK:STDOUT:     generic [file.%T.loc11_13.2: type] {
-// CHECK:STDOUT:   %T.ref.loc12: type = name_ref T, file.%T.loc11_13.2 [symbolic = file.%T.loc11_13.2 (constants.%T)]
-// CHECK:STDOUT:   %.loc12: <unexpected>.inst+28 (%.2) = field_decl a, element0 [template]
-// CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
-// CHECK:STDOUT:     %.loc13: type = specific_constant constants.%Class.2, file.%Class.decl(constants.%T) [symbolic = %.loc13 (constants.%Class.2)]
-// CHECK:STDOUT:     %Self.ref: type = name_ref Self, %.loc13 [symbolic = %.loc13 (constants.%Class.2)]
-// CHECK:STDOUT:     %self.loc13_8.1: @Class.%.loc13 (%Class.2) = param self
-// CHECK:STDOUT:     %self.loc13_8.2: @Class.%.loc13 (%Class.2) = bind_name self, %self.loc13_8.1
-// CHECK:STDOUT:     %T.ref.loc13: type = name_ref T, file.%T.loc11_13.2 [symbolic = %T.ref.loc13 (constants.%T)]
-// CHECK:STDOUT:     %n.loc13_20.1: @Class.%T.ref.loc13 (%T) = param n
-// CHECK:STDOUT:     %n.loc13_20.2: @Class.%T.ref.loc13 (%T) = bind_name n, %n.loc13_20.1
-// CHECK:STDOUT:   }
+// CHECK:STDOUT: generic class @Class(file.%T.loc11_13.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class.2)]
+// CHECK:STDOUT:   %.1: type = unbound_element_type @Class.%Class (%Class.2), @Class.%T (%T) [symbolic = %.1 (constants.%.2)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%Class.2
-// CHECK:STDOUT:   .a = %.loc12
-// CHECK:STDOUT:   .F = %F.decl
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:     %T.ref.loc12: type = name_ref T, file.%T.loc11_13.2 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:     %.loc12: @Class.%.1 (%.2) = field_decl a, element0 [template]
+// CHECK:STDOUT:     %F.decl: %F.type = fn_decl @F [template = constants.%F] {
+// CHECK:STDOUT:       %.loc13: type = specific_constant constants.%Class.2, @Class(constants.%T) [symbolic = @F.%Class (constants.%Class.2)]
+// CHECK:STDOUT:       %Self.ref: type = name_ref Self, %.loc13 [symbolic = @F.%Class (constants.%Class.2)]
+// CHECK:STDOUT:       %self.loc13_8.1: @F.%Class (%Class.2) = param self
+// CHECK:STDOUT:       %self.loc13_8.2: @F.%Class (%Class.2) = bind_name self, %self.loc13_8.1
+// CHECK:STDOUT:       %T.ref.loc13: type = name_ref T, file.%T.loc11_13.2 [symbolic = @F.%T (constants.%T)]
+// CHECK:STDOUT:       %n.loc13_20.1: @F.%T (%T) = param n
+// CHECK:STDOUT:       %n.loc13_20.2: @F.%T (%T) = bind_name n, %n.loc13_20.1
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%Class.2
+// CHECK:STDOUT:     .a = %.loc12
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F[%self: %Class.2](%n: %T)
-// CHECK:STDOUT:     generic [file.%T.loc11_13.2: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   return
+// CHECK:STDOUT: generic fn @F(file.%T.loc11_13.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn[%self: %Class.2](%n: %T) {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc11_13.2 => constants.%T
+// CHECK:STDOUT: specific @Class(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Class => constants.%Class.2
+// CHECK:STDOUT:   %.1 => constants.%.2
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: definition:
-// CHECK:STDOUT:   <unexpected>.inst+27 => constants.%Class.2
-// CHECK:STDOUT:   <unexpected>.inst+28 => constants.%.2
-// CHECK:STDOUT:   <unexpected>.inst+14.loc12_8 => <unexpected>.inst+15
+// CHECK:STDOUT: specific @Class(@F.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Class.%F.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @Class.%.loc13 => constants.%Class.2
-// CHECK:STDOUT:   @Class.%T.ref.loc13 => constants.%T
+// CHECK:STDOUT: specific @F(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %Class => constants.%Class.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Class.decl(file.%T.loc11_13.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc11_13.2 => constants.%T
+// CHECK:STDOUT: specific @Class(@Class.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 4 - 4
toolchain/check/testdata/class/syntactic_merge_literal.carbon

@@ -39,7 +39,7 @@ class D(b: C(1_000)) {}
 // CHECK:STDOUT:   %C.2: type = class_type @C [template]
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %.3: i32 = int_literal 1000 [template]
-// CHECK:STDOUT:   %C.3: type = class_type @C, <invalid>(%.3) [template]
+// CHECK:STDOUT:   %C.3: type = class_type @C, invalid(%.3) [template]
 // CHECK:STDOUT:   %D.type: type = generic_class_type @D [template]
 // CHECK:STDOUT:   %D.1: %D.type = struct_value () [template]
 // CHECK:STDOUT:   %D.2: type = class_type @D [template]
@@ -104,7 +104,7 @@ class D(b: C(1_000)) {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%.3);
+// CHECK:STDOUT: specific invalid(constants.%.3);
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_int_mismatch.carbon
 // CHECK:STDOUT:
@@ -117,7 +117,7 @@ class D(b: C(1_000)) {}
 // CHECK:STDOUT:   %C.2: type = class_type @C [template]
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %.3: i32 = int_literal 1000 [template]
-// CHECK:STDOUT:   %C.3: type = class_type @C, <invalid>(%.3) [template]
+// CHECK:STDOUT:   %C.3: type = class_type @C, invalid(%.3) [template]
 // CHECK:STDOUT:   %D.type: type = generic_class_type @D [template]
 // CHECK:STDOUT:   %D.1: %D.type = struct_value () [template]
 // CHECK:STDOUT:   %D.2: type = class_type @D [template]
@@ -187,5 +187,5 @@ class D(b: C(1_000)) {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%.3);
+// CHECK:STDOUT: specific invalid(constants.%.3);
 // CHECK:STDOUT:

+ 19 - 15
toolchain/check/testdata/eval/fail_symbolic.carbon

@@ -52,27 +52,31 @@ fn G(N:! i32) {
 // CHECK:STDOUT:     %.loc12_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:     %.loc12_10.2: type = converted %int.make_type_32, %.loc12_10.1 [template = i32]
 // CHECK:STDOUT:     %N.loc12_6.1: i32 = param N
-// CHECK:STDOUT:     @G.%N: i32 = bind_symbolic_name N 0, %N.loc12_6.1 [symbolic = @G.%N (constants.%N)]
+// CHECK:STDOUT:     @G.%N.loc12: i32 = bind_symbolic_name N 0, %N.loc12_6.1 [symbolic = @G.%N.1 (constants.%N)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @G(%N: i32)
-// CHECK:STDOUT:     generic [%N: i32] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:   %N.ref: i32 = name_ref N, %N [symbolic = %N (constants.%N)]
-// CHECK:STDOUT:   %.loc16_11.1: type = value_of_initializer %int.make_type_32 [template = i32]
-// CHECK:STDOUT:   %.loc16_11.2: type = converted %int.make_type_32, %.loc16_11.1 [template = i32]
-// CHECK:STDOUT:   %.loc16_17: type = array_type %N.ref, i32 [template = <error>]
-// CHECK:STDOUT:   %k.var: ref <error> = var k
-// CHECK:STDOUT:   %k: ref <error> = bind_name k, %k.var
-// CHECK:STDOUT:   return
+// CHECK:STDOUT: generic fn @G(%N.loc12: i32) {
+// CHECK:STDOUT:   %N.1: i32 = bind_symbolic_name N 0 [symbolic = %N.1 (constants.%N)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%N.loc12: i32) {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %int.make_type_32: init type = call constants.%Int32() [template = i32]
+// CHECK:STDOUT:     %N.ref: i32 = name_ref N, %N.loc12 [symbolic = %N.1 (constants.%N)]
+// CHECK:STDOUT:     %.loc16_11.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:     %.loc16_11.2: type = converted %int.make_type_32, %.loc16_11.1 [template = i32]
+// CHECK:STDOUT:     %.loc16_17: type = array_type %N.ref, i32 [template = <error>]
+// CHECK:STDOUT:     %k.var: ref <error> = var k
+// CHECK:STDOUT:     %k: ref <error> = bind_name k, %k.var
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%G.decl(constants.%N) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @G.%N => constants.%N
+// CHECK:STDOUT: specific @G(constants.%N) {
+// CHECK:STDOUT:   %N.1 => constants.%N
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 34 - 25
toolchain/check/testdata/eval/symbolic.carbon

@@ -51,35 +51,44 @@ fn F(T:! type) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
 // CHECK:STDOUT:     %T.loc12_6.1: type = param T
-// CHECK:STDOUT:     @F.%T: type = bind_symbolic_name T 0, %T.loc12_6.1 [symbolic = @F.%T (constants.%T)]
+// CHECK:STDOUT:     @F.%T.loc12: type = bind_symbolic_name T 0, %T.loc12_6.1 [symbolic = @F.%T.1 (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F(%T: type)
-// CHECK:STDOUT:     generic [%T: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %T.ref.loc13_11: type = name_ref T, %T [symbolic = %T (constants.%T)]
-// CHECK:STDOUT:   %.loc13_12: type = ptr_type %T [symbolic = %.loc13_12 (constants.%.2)]
-// CHECK:STDOUT:   %T.ref.loc13_21: type = name_ref T, %T [symbolic = %T (constants.%T)]
-// CHECK:STDOUT:   %.loc13_15: type = const_type %T [symbolic = %.loc13_15 (constants.%.3)]
-// CHECK:STDOUT:   %.loc13_22.1: %.4 = tuple_literal (%.loc13_12, %.loc13_15)
-// CHECK:STDOUT:   %.loc13_22.2: type = converted %.loc13_22.1, constants.%.5 [symbolic = %.loc13_22.2 (constants.%.5)]
-// CHECK:STDOUT:   %u.var: ref @F.%.loc13_22.2 (%.5) = var u
-// CHECK:STDOUT:   %u: ref @F.%.loc13_22.2 (%.5) = bind_name u, %u.var
-// CHECK:STDOUT:   %T.ref.loc14: type = name_ref T, %T [symbolic = %T (constants.%T)]
-// CHECK:STDOUT:   %.loc14: type = struct_type {.a: %T} [symbolic = %.loc14 (constants.%.8)]
-// CHECK:STDOUT:   %v.var: ref @F.%.loc14 (%.8) = var v
-// CHECK:STDOUT:   %v: ref @F.%.loc14 (%.8) = bind_name v, %v.var
-// CHECK:STDOUT:   %T.ref.loc15: type = name_ref T, %T [symbolic = %T (constants.%T)]
-// CHECK:STDOUT:   %.loc15_14: i32 = int_literal 5 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc15_15: type = array_type %.loc15_14, %T [symbolic = %.loc15_15 (constants.%.10)]
-// CHECK:STDOUT:   %w.var: ref @F.%.loc15_15 (%.10) = var w
-// CHECK:STDOUT:   %w: ref @F.%.loc15_15 (%.10) = bind_name w, %w.var
-// CHECK:STDOUT:   return
+// CHECK:STDOUT: generic fn @F(%T.loc12: type) {
+// CHECK:STDOUT:   %T.1: type = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1: type = ptr_type @F.%T.1 (%T) [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:   %.2: type = const_type @F.%T.1 (%T) [symbolic = %.2 (constants.%.3)]
+// CHECK:STDOUT:   %.3: type = tuple_type (@F.%.1 (%.2), @F.%.2 (%.3)) [symbolic = %.3 (constants.%.5)]
+// CHECK:STDOUT:   %.4: type = struct_type {.a: @F.%T.1 (%T)} [symbolic = %.4 (constants.%.8)]
+// CHECK:STDOUT:   %.5: type = array_type constants.%.9, @F.%T.1 (%T) [symbolic = %.5 (constants.%.10)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%T.loc12: type) {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %T.ref.loc13_11: type = name_ref T, %T.loc12 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:     %.loc13_12: type = ptr_type %T [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:     %T.ref.loc13_21: type = name_ref T, %T.loc12 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:     %.loc13_15: type = const_type %T [symbolic = %.2 (constants.%.3)]
+// CHECK:STDOUT:     %.loc13_22.1: %.4 = tuple_literal (%.loc13_12, %.loc13_15)
+// CHECK:STDOUT:     %.loc13_22.2: type = converted %.loc13_22.1, constants.%.5 [symbolic = %.3 (constants.%.5)]
+// CHECK:STDOUT:     %u.var: ref @F.%.3 (%.5) = var u
+// CHECK:STDOUT:     %u: ref @F.%.3 (%.5) = bind_name u, %u.var
+// CHECK:STDOUT:     %T.ref.loc14: type = name_ref T, %T.loc12 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:     %.loc14: type = struct_type {.a: %T} [symbolic = %.4 (constants.%.8)]
+// CHECK:STDOUT:     %v.var: ref @F.%.4 (%.8) = var v
+// CHECK:STDOUT:     %v: ref @F.%.4 (%.8) = bind_name v, %v.var
+// CHECK:STDOUT:     %T.ref.loc15: type = name_ref T, %T.loc12 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:     %.loc15_14: i32 = int_literal 5 [template = constants.%.9]
+// CHECK:STDOUT:     %.loc15_15: type = array_type %.loc15_14, %T [symbolic = %.5 (constants.%.10)]
+// CHECK:STDOUT:     %w.var: ref @F.%.5 (%.10) = var w
+// CHECK:STDOUT:     %w: ref @F.%.5 (%.10) = bind_name w, %w.var
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%F.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @F.%T => constants.%T
+// CHECK:STDOUT: specific @F(constants.%T) {
+// CHECK:STDOUT:   %T.1 => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 20 - 18
toolchain/check/testdata/function/builtin/method.carbon

@@ -90,19 +90,19 @@ var arr: [i32; 1.(I.F)(2)];
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %.1 = bind_symbolic_name Self 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type.1 = fn_decl @F.1 [template = constants.%F.1] {
-// CHECK:STDOUT:     %Self.ref.loc12_14: %.1 = name_ref Self, %Self [symbolic = %Self.ref.loc12_14 (constants.%Self)]
-// CHECK:STDOUT:     %.loc12_14.1: type = facet_type_access %Self.ref.loc12_14 [symbolic = %Self.ref.loc12_14 (constants.%Self)]
-// CHECK:STDOUT:     %.loc12_14.2: type = converted %Self.ref.loc12_14, %.loc12_14.1 [symbolic = %Self.ref.loc12_14 (constants.%Self)]
-// CHECK:STDOUT:     %self.loc12_8.1: @I.%Self.ref.loc12_14 (%Self) = param self
-// CHECK:STDOUT:     %self.loc12_8.2: @I.%Self.ref.loc12_14 (%Self) = bind_name self, %self.loc12_8.1
-// CHECK:STDOUT:     %Self.ref.loc12_27: %.1 = name_ref Self, %Self [symbolic = %Self.ref.loc12_14 (constants.%Self)]
-// CHECK:STDOUT:     %.loc12_27.1: type = facet_type_access %Self.ref.loc12_27 [symbolic = %Self.ref.loc12_14 (constants.%Self)]
-// CHECK:STDOUT:     %.loc12_27.2: type = converted %Self.ref.loc12_27, %.loc12_27.1 [symbolic = %Self.ref.loc12_14 (constants.%Self)]
-// CHECK:STDOUT:     %other.loc12_20.1: @I.%Self.ref.loc12_14 (%Self) = param other
-// CHECK:STDOUT:     %other.loc12_20.2: @I.%Self.ref.loc12_14 (%Self) = bind_name other, %other.loc12_20.1
-// CHECK:STDOUT:     %Self.ref.loc12_36: %.1 = name_ref Self, %Self [symbolic = %Self.ref.loc12_14 (constants.%Self)]
-// CHECK:STDOUT:     %.loc12_36.1: type = facet_type_access %Self.ref.loc12_36 [symbolic = %Self.ref.loc12_14 (constants.%Self)]
-// CHECK:STDOUT:     %.loc12_36.2: type = converted %Self.ref.loc12_36, %.loc12_36.1 [symbolic = %Self.ref.loc12_14 (constants.%Self)]
+// CHECK:STDOUT:     %Self.ref.loc12_14: %.1 = name_ref Self, %Self [symbolic = @F.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc12_14.1: type = facet_type_access %Self.ref.loc12_14 [symbolic = @F.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc12_14.2: type = converted %Self.ref.loc12_14, %.loc12_14.1 [symbolic = @F.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %self.loc12_8.1: @F.1.%Self (%Self) = param self
+// CHECK:STDOUT:     %self.loc12_8.2: @F.1.%Self (%Self) = bind_name self, %self.loc12_8.1
+// CHECK:STDOUT:     %Self.ref.loc12_27: %.1 = name_ref Self, %Self [symbolic = @F.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc12_27.1: type = facet_type_access %Self.ref.loc12_27 [symbolic = @F.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc12_27.2: type = converted %Self.ref.loc12_27, %.loc12_27.1 [symbolic = @F.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %other.loc12_20.1: @F.1.%Self (%Self) = param other
+// CHECK:STDOUT:     %other.loc12_20.2: @F.1.%Self (%Self) = bind_name other, %other.loc12_20.1
+// CHECK:STDOUT:     %Self.ref.loc12_36: %.1 = name_ref Self, %Self [symbolic = @F.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc12_36.1: type = facet_type_access %Self.ref.loc12_36 [symbolic = @F.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc12_36.2: type = converted %Self.ref.loc12_36, %.loc12_36.1 [symbolic = @F.1.%Self (constants.%Self)]
 // CHECK:STDOUT:     %return.var: ref %Self = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.loc12_40: %.3 = assoc_entity element0, %F.decl [template = constants.%.4]
@@ -137,15 +137,17 @@ var arr: [i32; 1.(I.F)(2)];
 // CHECK:STDOUT:   witness = %.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.1[@I.%self.loc12_8.2: @I.%Self.ref.loc12_14 (%Self)](@I.%other.loc12_20.2: @I.%Self.ref.loc12_14 (%Self)) -> %Self
-// CHECK:STDOUT:     generic [@I.%Self: %.1];
+// CHECK:STDOUT: generic fn @F.1(@I.%Self: %.1) {
+// CHECK:STDOUT:   %Self: %.1 = bind_symbolic_name Self 0 [symbolic = %Self (constants.%Self)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn[@I.%self.loc12_8.2: @F.1.%Self (%Self)](@I.%other.loc12_20.2: @F.1.%Self (%Self)) -> %Self;
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.2[@impl.%self.loc16_8.2: i32](@impl.%other.loc16_19.2: i32) -> i32 = "int.sadd";
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @I.%F.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @I.%Self.ref.loc12_14 => constants.%Self
+// CHECK:STDOUT: specific @F.1(constants.%Self) {
+// CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

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

@@ -58,19 +58,19 @@ var arr: [i32; 1 + 2] = (3, 4, 3 + 4);
 // CHECK:STDOUT: interface @Add {
 // CHECK:STDOUT:   %Self: %.2 = bind_symbolic_name Self 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %Op.decl: %Op.type = fn_decl @Op [template = constants.%Op] {
-// CHECK:STDOUT:     %Self.ref.loc7_15: %.2 = name_ref Self, %Self [symbolic = %Self.ref.loc7_15 (constants.%Self)]
-// CHECK:STDOUT:     %.loc7_15.1: type = facet_type_access %Self.ref.loc7_15 [symbolic = %Self.ref.loc7_15 (constants.%Self)]
-// CHECK:STDOUT:     %.loc7_15.2: type = converted %Self.ref.loc7_15, %.loc7_15.1 [symbolic = %Self.ref.loc7_15 (constants.%Self)]
-// CHECK:STDOUT:     %self.loc7_9.1: @Add.%Self.ref.loc7_15 (%Self) = param self
-// CHECK:STDOUT:     %self.loc7_9.2: @Add.%Self.ref.loc7_15 (%Self) = bind_name self, %self.loc7_9.1
-// CHECK:STDOUT:     %Self.ref.loc7_28: %.2 = name_ref Self, %Self [symbolic = %Self.ref.loc7_15 (constants.%Self)]
-// CHECK:STDOUT:     %.loc7_28.1: type = facet_type_access %Self.ref.loc7_28 [symbolic = %Self.ref.loc7_15 (constants.%Self)]
-// CHECK:STDOUT:     %.loc7_28.2: type = converted %Self.ref.loc7_28, %.loc7_28.1 [symbolic = %Self.ref.loc7_15 (constants.%Self)]
-// CHECK:STDOUT:     %other.loc7_21.1: @Add.%Self.ref.loc7_15 (%Self) = param other
-// CHECK:STDOUT:     %other.loc7_21.2: @Add.%Self.ref.loc7_15 (%Self) = bind_name other, %other.loc7_21.1
-// CHECK:STDOUT:     %Self.ref.loc7_37: %.2 = name_ref Self, %Self [symbolic = %Self.ref.loc7_15 (constants.%Self)]
-// CHECK:STDOUT:     %.loc7_37.1: type = facet_type_access %Self.ref.loc7_37 [symbolic = %Self.ref.loc7_15 (constants.%Self)]
-// CHECK:STDOUT:     %.loc7_37.2: type = converted %Self.ref.loc7_37, %.loc7_37.1 [symbolic = %Self.ref.loc7_15 (constants.%Self)]
+// CHECK:STDOUT:     %Self.ref.loc7_15: %.2 = name_ref Self, %Self [symbolic = @Op.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc7_15.1: type = facet_type_access %Self.ref.loc7_15 [symbolic = @Op.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc7_15.2: type = converted %Self.ref.loc7_15, %.loc7_15.1 [symbolic = @Op.%Self (constants.%Self)]
+// CHECK:STDOUT:     %self.loc7_9.1: @Op.%Self (%Self) = param self
+// CHECK:STDOUT:     %self.loc7_9.2: @Op.%Self (%Self) = bind_name self, %self.loc7_9.1
+// CHECK:STDOUT:     %Self.ref.loc7_28: %.2 = name_ref Self, %Self [symbolic = @Op.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc7_28.1: type = facet_type_access %Self.ref.loc7_28 [symbolic = @Op.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc7_28.2: type = converted %Self.ref.loc7_28, %.loc7_28.1 [symbolic = @Op.%Self (constants.%Self)]
+// CHECK:STDOUT:     %other.loc7_21.1: @Op.%Self (%Self) = param other
+// CHECK:STDOUT:     %other.loc7_21.2: @Op.%Self (%Self) = bind_name other, %other.loc7_21.1
+// CHECK:STDOUT:     %Self.ref.loc7_37: %.2 = name_ref Self, %Self [symbolic = @Op.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc7_37.1: type = facet_type_access %Self.ref.loc7_37 [symbolic = @Op.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc7_37.2: type = converted %Self.ref.loc7_37, %.loc7_37.1 [symbolic = @Op.%Self (constants.%Self)]
 // CHECK:STDOUT:     %return.var: ref %Self = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.loc7_41: %.3 = assoc_entity element0, %Op.decl [template = constants.%.4]
@@ -83,12 +83,14 @@ var arr: [i32; 1 + 2] = (3, 4, 3 + 4);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @Op[@Add.%self.loc7_9.2: @Add.%Self.ref.loc7_15 (%Self)](@Add.%other.loc7_21.2: @Add.%Self.ref.loc7_15 (%Self)) -> %Self
-// CHECK:STDOUT:     generic [@Add.%Self: %.2];
+// CHECK:STDOUT: generic fn @Op(@Add.%Self: %.2) {
+// CHECK:STDOUT:   %Self: %.2 = bind_symbolic_name Self 0 [symbolic = %Self (constants.%Self)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Add.%Op.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @Add.%Self.ref.loc7_15 => constants.%Self
+// CHECK:STDOUT:   fn[@Add.%self.loc7_9.2: @Op.%Self (%Self)](@Add.%other.loc7_21.2: @Op.%Self (%Self)) -> %Self;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Op(constants.%Self) {
+// CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- user.carbon
@@ -124,7 +126,7 @@ var arr: [i32; 1 + 2] = (3, 4, 3 + 4);
 // CHECK:STDOUT:   %import_ref.1: %Int32.type = import_ref Core//default, inst+2, loaded [template = constants.%Int32]
 // CHECK:STDOUT:   %import_ref.2: type = import_ref Core//default, inst+6, loaded [template = constants.%.2]
 // CHECK:STDOUT:   %import_ref.3 = import_ref Core//default, inst+8, unloaded
-// CHECK:STDOUT:   %import_ref.4: %.6 = import_ref Core//default, inst+28, loaded [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.4: %.6 = import_ref Core//default, inst+29, loaded [template = constants.%.7]
 // CHECK:STDOUT:   %import_ref.5: %Op.type.2 = import_ref Core//default, inst+24, loaded [template = constants.%Op.2]
 // CHECK:STDOUT:   %import_ref.6: %Int32.type = import_ref Core//default, inst+2, loaded [template = constants.%Int32]
 // CHECK:STDOUT:   %import_ref.7: type = import_ref Core//default, inst+6, loaded [template = constants.%.2]

+ 9 - 7
toolchain/check/testdata/function/generic/fail_todo_param_in_type.carbon

@@ -49,9 +49,9 @@ fn F(N:! i32, a: [i32; N]*);
 // CHECK:STDOUT:     %.loc14_10.1: type = value_of_initializer %int.make_type_32.loc14_10 [template = i32]
 // CHECK:STDOUT:     %.loc14_10.2: type = converted %int.make_type_32.loc14_10, %.loc14_10.1 [template = i32]
 // CHECK:STDOUT:     %N.loc14_6.1: i32 = param N
-// CHECK:STDOUT:     @F.%N: i32 = bind_symbolic_name N 0, %N.loc14_6.1 [symbolic = @F.%N (constants.%N)]
+// CHECK:STDOUT:     @F.%N.loc14: i32 = bind_symbolic_name N 0, %N.loc14_6.1 [symbolic = @F.%N.1 (constants.%N)]
 // CHECK:STDOUT:     %int.make_type_32.loc14_19: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT:     %N.ref: i32 = name_ref N, @F.%N [symbolic = @F.%N (constants.%N)]
+// CHECK:STDOUT:     %N.ref: i32 = name_ref N, @F.%N.loc14 [symbolic = @F.%N.1 (constants.%N)]
 // CHECK:STDOUT:     %.loc14_19.1: type = value_of_initializer %int.make_type_32.loc14_19 [template = i32]
 // CHECK:STDOUT:     %.loc14_19.2: type = converted %int.make_type_32.loc14_19, %.loc14_19.1 [template = i32]
 // CHECK:STDOUT:     %.loc14_25: type = array_type %N.ref, i32 [template = <error>]
@@ -63,11 +63,13 @@ fn F(N:! i32, a: [i32; N]*);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F(%N: i32, %a: <error>)
-// CHECK:STDOUT:     generic [%N: i32];
+// CHECK:STDOUT: generic fn @F(%N.loc14: i32) {
+// CHECK:STDOUT:   %N.1: i32 = bind_symbolic_name N 0 [symbolic = %N.1 (constants.%N)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%F.decl(constants.%N) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @F.%N => constants.%N
+// CHECK:STDOUT:   fn(%N.loc14: i32, %a: <error>);
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F(constants.%N) {
+// CHECK:STDOUT:   %N.1 => constants.%N
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 25 - 19
toolchain/check/testdata/function/generic/no_prelude/fail_type_param_mismatch.carbon

@@ -33,30 +33,36 @@ fn F(T:! type, U:! type) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
 // CHECK:STDOUT:     %T.loc11_6.1: type = param T
-// CHECK:STDOUT:     @F.%T: type = bind_symbolic_name T 0, %T.loc11_6.1 [symbolic = @F.%T (constants.%T)]
+// CHECK:STDOUT:     @F.%T.loc11: type = bind_symbolic_name T 0, %T.loc11_6.1 [symbolic = @F.%T.1 (constants.%T)]
 // CHECK:STDOUT:     %U.loc11_16.1: type = param U
-// CHECK:STDOUT:     @F.%U: type = bind_symbolic_name U 1, %U.loc11_16.1 [symbolic = @F.%U (constants.%U)]
+// CHECK:STDOUT:     @F.%U.loc11: type = bind_symbolic_name U 1, %U.loc11_16.1 [symbolic = @F.%U.1 (constants.%U)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F(%T: type, %U: type)
-// CHECK:STDOUT:     generic [%T: type, %U: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %T.ref: type = name_ref T, %T [symbolic = %T (constants.%T)]
-// CHECK:STDOUT:   %.loc12: type = ptr_type %T [symbolic = %.loc12 (constants.%.2)]
-// CHECK:STDOUT:   %p.var: ref @F.%.loc12 (%.2) = var p
-// CHECK:STDOUT:   %p: ref @F.%.loc12 (%.2) = bind_name p, %p.var
-// CHECK:STDOUT:   %U.ref: type = name_ref U, %U [symbolic = %U (constants.%U)]
-// CHECK:STDOUT:   %p.ref: ref @F.%.loc12 (%.2) = name_ref p, %p
-// CHECK:STDOUT:   %.loc16_15: @F.%.loc12 (%.2) = bind_value %p.ref
-// CHECK:STDOUT:   %.loc16_14: ref @F.%T (%T) = deref %.loc16_15
-// CHECK:STDOUT:   %n: @F.%U (%U) = bind_name n, <error>
-// CHECK:STDOUT:   return
+// CHECK:STDOUT: generic fn @F(%T.loc11: type, %U.loc11: type) {
+// CHECK:STDOUT:   %T.1: type = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:   %U.1: type = bind_symbolic_name U 1 [symbolic = %U.1 (constants.%U)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1: type = ptr_type @F.%T.1 (%T) [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%T.loc11: type, %U.loc11: type) {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %T.ref: type = name_ref T, %T.loc11 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:     %.loc12: type = ptr_type %T [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:     %p.var: ref @F.%.1 (%.2) = var p
+// CHECK:STDOUT:     %p: ref @F.%.1 (%.2) = bind_name p, %p.var
+// CHECK:STDOUT:     %U.ref: type = name_ref U, %U.loc11 [symbolic = %U.1 (constants.%U)]
+// CHECK:STDOUT:     %p.ref: ref @F.%.1 (%.2) = name_ref p, %p
+// CHECK:STDOUT:     %.loc16_15: @F.%.1 (%.2) = bind_value %p.ref
+// CHECK:STDOUT:     %.loc16_14: ref @F.%T.1 (%T) = deref %.loc16_15
+// CHECK:STDOUT:     %n: @F.%U.1 (%U) = bind_name n, <error>
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%F.decl(constants.%T, constants.%U) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @F.%T => constants.%T
-// CHECK:STDOUT:   @F.%U => constants.%U
+// CHECK:STDOUT: specific @F(constants.%T, constants.%U) {
+// CHECK:STDOUT:   %T.1 => constants.%T
+// CHECK:STDOUT:   %U.1 => constants.%U
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 41 - 0
toolchain/check/testdata/function/generic/no_prelude/forward_decl.carbon

@@ -0,0 +1,41 @@
+// 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/function/generic/no_prelude/forward_decl.carbon
+// TIP: To dump output, run:
+// TIP:   bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/function/generic/no_prelude/forward_decl.carbon
+
+fn F(T:! type);
+
+// CHECK:STDOUT: --- forward_decl.carbon
+// CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic]
+// CHECK:STDOUT:   %F.type: type = fn_type @F [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %F: %F.type = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: file {
+// CHECK:STDOUT:   package: <namespace> = namespace [template] {
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
+// CHECK:STDOUT:     %T.loc11_6.1: type = param T
+// CHECK:STDOUT:     @F.%T.loc11: type = bind_symbolic_name T 0, %T.loc11_6.1 [symbolic = @F.%T.1 (constants.%T)]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @F(%T.loc11: type) {
+// CHECK:STDOUT:   %T.1: type = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%T.loc11: type);
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F(constants.%T) {
+// CHECK:STDOUT:   %T.1 => constants.%T
+// CHECK:STDOUT: }
+// CHECK:STDOUT:

+ 26 - 20
toolchain/check/testdata/function/generic/no_prelude/indirect_generic_type.carbon

@@ -29,31 +29,37 @@ fn F(T:! type, p: T**) -> T* {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
 // CHECK:STDOUT:     %T.loc11_6.1: type = param T
-// CHECK:STDOUT:     @F.%T: type = bind_symbolic_name T 0, %T.loc11_6.1 [symbolic = @F.%T (constants.%T)]
-// CHECK:STDOUT:     %T.ref.loc11_19: type = name_ref T, @F.%T [symbolic = @F.%T (constants.%T)]
-// CHECK:STDOUT:     %.loc11_20: type = ptr_type %T [symbolic = %.loc11_20 (constants.%.1)]
-// CHECK:STDOUT:     %.loc11_21: type = ptr_type %.1 [symbolic = %.loc11_21 (constants.%.2)]
-// CHECK:STDOUT:     %p.loc11_16.1: file.%.loc11_21 (%.2) = param p
-// CHECK:STDOUT:     @F.%p: file.%.loc11_21 (%.2) = bind_name p, %p.loc11_16.1
-// CHECK:STDOUT:     %T.ref.loc11_27: type = name_ref T, @F.%T [symbolic = @F.%T (constants.%T)]
-// CHECK:STDOUT:     %.loc11_28: type = ptr_type %T [symbolic = %.loc11_20 (constants.%.1)]
+// CHECK:STDOUT:     @F.%T.loc11: type = bind_symbolic_name T 0, %T.loc11_6.1 [symbolic = @F.%T.1 (constants.%T)]
+// CHECK:STDOUT:     %T.ref.loc11_19: type = name_ref T, @F.%T.loc11 [symbolic = @F.%T.1 (constants.%T)]
+// CHECK:STDOUT:     %.loc11_20: type = ptr_type %T [symbolic = @F.%.1 (constants.%.1)]
+// CHECK:STDOUT:     %.loc11_21: type = ptr_type %.1 [symbolic = @F.%.2 (constants.%.2)]
+// CHECK:STDOUT:     %p.loc11_16.1: @F.%.2 (%.2) = param p
+// CHECK:STDOUT:     @F.%p: @F.%.2 (%.2) = bind_name p, %p.loc11_16.1
+// CHECK:STDOUT:     %T.ref.loc11_27: type = name_ref T, @F.%T.loc11 [symbolic = @F.%T.1 (constants.%T)]
+// CHECK:STDOUT:     %.loc11_28: type = ptr_type %T [symbolic = @F.%.1 (constants.%.1)]
 // CHECK:STDOUT:     @F.%return: ref %.1 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F(%T: type, %p: file.%.loc11_21 (%.2)) -> %.1
-// CHECK:STDOUT:     generic [%T: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %p.ref: file.%.loc11_21 (%.2) = name_ref p, %p
-// CHECK:STDOUT:   %.loc12_10.1: ref file.%.loc11_20 (%.1) = deref %p.ref
-// CHECK:STDOUT:   %.loc12_10.2: file.%.loc11_20 (%.1) = bind_value %.loc12_10.1
-// CHECK:STDOUT:   return %.loc12_10.2
+// CHECK:STDOUT: generic fn @F(%T.loc11: type) {
+// CHECK:STDOUT:   %T.1: type = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:   %.1: type = ptr_type @F.%T.1 (%T) [symbolic = %.1 (constants.%.1)]
+// CHECK:STDOUT:   %.2: type = ptr_type @F.%.1 (%.1) [symbolic = %.2 (constants.%.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%T.loc11: type, %p: @F.%.2 (%.2)) -> %.1 {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %p.ref: @F.%.2 (%.2) = name_ref p, %p
+// CHECK:STDOUT:     %.loc12_10.1: ref @F.%.1 (%.1) = deref %p.ref
+// CHECK:STDOUT:     %.loc12_10.2: @F.%.1 (%.1) = bind_value %.loc12_10.1
+// CHECK:STDOUT:     return %.loc12_10.2
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%F.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @F.%T => constants.%T
-// CHECK:STDOUT:   file.%.loc11_20 => constants.%.1
-// CHECK:STDOUT:   file.%.loc11_21 => constants.%.2
+// CHECK:STDOUT: specific @F(constants.%T) {
+// CHECK:STDOUT:   %T.1 => constants.%T
+// CHECK:STDOUT:   %.1 => constants.%.1
+// CHECK:STDOUT:   %.2 => constants.%.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 23 - 18
toolchain/check/testdata/function/generic/no_prelude/type_param.carbon

@@ -29,28 +29,33 @@ fn F(T:! type) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
 // CHECK:STDOUT:     %T.loc11_6.1: type = param T
-// CHECK:STDOUT:     @F.%T: type = bind_symbolic_name T 0, %T.loc11_6.1 [symbolic = @F.%T (constants.%T)]
+// CHECK:STDOUT:     @F.%T.loc11: type = bind_symbolic_name T 0, %T.loc11_6.1 [symbolic = @F.%T.1 (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F(%T: type)
-// CHECK:STDOUT:     generic [%T: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %T.ref.loc12: type = name_ref T, %T [symbolic = %T (constants.%T)]
-// CHECK:STDOUT:   %.loc12: type = ptr_type %T [symbolic = %.loc12 (constants.%.2)]
-// CHECK:STDOUT:   %p.var: ref @F.%.loc12 (%.2) = var p
-// CHECK:STDOUT:   %p: ref @F.%.loc12 (%.2) = bind_name p, %p.var
-// CHECK:STDOUT:   %T.ref.loc13: type = name_ref T, %T [symbolic = %T (constants.%T)]
-// CHECK:STDOUT:   %p.ref: ref @F.%.loc12 (%.2) = name_ref p, %p
-// CHECK:STDOUT:   %.loc13_15: @F.%.loc12 (%.2) = bind_value %p.ref
-// CHECK:STDOUT:   %.loc13_14.1: ref @F.%T (%T) = deref %.loc13_15
-// CHECK:STDOUT:   %.loc13_14.2: @F.%T (%T) = bind_value %.loc13_14.1
-// CHECK:STDOUT:   %n: @F.%T (%T) = bind_name n, %.loc13_14.2
-// CHECK:STDOUT:   return
+// CHECK:STDOUT: generic fn @F(%T.loc11: type) {
+// CHECK:STDOUT:   %T.1: type = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1: type = ptr_type @F.%T.1 (%T) [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%T.loc11: type) {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %T.ref.loc12: type = name_ref T, %T.loc11 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:     %.loc12: type = ptr_type %T [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:     %p.var: ref @F.%.1 (%.2) = var p
+// CHECK:STDOUT:     %p: ref @F.%.1 (%.2) = bind_name p, %p.var
+// CHECK:STDOUT:     %T.ref.loc13: type = name_ref T, %T.loc11 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:     %p.ref: ref @F.%.1 (%.2) = name_ref p, %p
+// CHECK:STDOUT:     %.loc13_15: @F.%.1 (%.2) = bind_value %p.ref
+// CHECK:STDOUT:     %.loc13_14.1: ref @F.%T.1 (%T) = deref %.loc13_15
+// CHECK:STDOUT:     %.loc13_14.2: @F.%T.1 (%T) = bind_value %.loc13_14.1
+// CHECK:STDOUT:     %n: @F.%T.1 (%T) = bind_name n, %.loc13_14.2
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%F.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @F.%T => constants.%T
+// CHECK:STDOUT: specific @F(constants.%T) {
+// CHECK:STDOUT:   %T.1 => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 20 - 16
toolchain/check/testdata/function/generic/no_prelude/type_param_scope.carbon

@@ -28,27 +28,31 @@ fn F(T:! type, n: T) -> T {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
 // CHECK:STDOUT:     %T.loc11_6.1: type = param T
-// CHECK:STDOUT:     @F.%T: type = bind_symbolic_name T 0, %T.loc11_6.1 [symbolic = @F.%T (constants.%T)]
-// CHECK:STDOUT:     %T.ref.loc11_19: type = name_ref T, @F.%T [symbolic = @F.%T (constants.%T)]
-// CHECK:STDOUT:     %n.loc11_16.1: @F.%T (%T) = param n
-// CHECK:STDOUT:     @F.%n: @F.%T (%T) = bind_name n, %n.loc11_16.1
-// CHECK:STDOUT:     %T.ref.loc11_25: type = name_ref T, @F.%T [symbolic = @F.%T (constants.%T)]
+// CHECK:STDOUT:     @F.%T.loc11: type = bind_symbolic_name T 0, %T.loc11_6.1 [symbolic = @F.%T.1 (constants.%T)]
+// CHECK:STDOUT:     %T.ref.loc11_19: type = name_ref T, @F.%T.loc11 [symbolic = @F.%T.1 (constants.%T)]
+// CHECK:STDOUT:     %n.loc11_16.1: @F.%T.1 (%T) = param n
+// CHECK:STDOUT:     @F.%n: @F.%T.1 (%T) = bind_name n, %n.loc11_16.1
+// CHECK:STDOUT:     %T.ref.loc11_25: type = name_ref T, @F.%T.loc11 [symbolic = @F.%T.1 (constants.%T)]
 // CHECK:STDOUT:     @F.%return: ref %T = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F(%T: type, %n: @F.%T (%T)) -> %T
-// CHECK:STDOUT:     generic [%T: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %T.ref: type = name_ref T, %T [symbolic = %T (constants.%T)]
-// CHECK:STDOUT:   %n.ref: @F.%T (%T) = name_ref n, %n
-// CHECK:STDOUT:   %m: @F.%T (%T) = bind_name m, %n.ref
-// CHECK:STDOUT:   %m.ref: @F.%T (%T) = name_ref m, %m
-// CHECK:STDOUT:   return %m.ref
+// CHECK:STDOUT: generic fn @F(%T.loc11: type) {
+// CHECK:STDOUT:   %T.1: type = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%T.loc11: type, %n: @F.%T.1 (%T)) -> %T {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %T.ref: type = name_ref T, %T.loc11 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:     %n.ref: @F.%T.1 (%T) = name_ref n, %n
+// CHECK:STDOUT:     %m: @F.%T.1 (%T) = bind_name m, %n.ref
+// CHECK:STDOUT:     %m.ref: @F.%T.1 (%T) = name_ref m, %m
+// CHECK:STDOUT:     return %m.ref
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%F.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @F.%T => constants.%T
+// CHECK:STDOUT: specific @F(constants.%T) {
+// CHECK:STDOUT:   %T.1 => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 139 - 99
toolchain/check/testdata/function/generic/redeclare.carbon

@@ -128,35 +128,40 @@ fn F(U:! type, T:! type) -> U* {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl.loc4: %F.type = fn_decl @F [template = constants.%F] {
 // CHECK:STDOUT:     %T.loc4_6.1: type = param T
-// CHECK:STDOUT:     %T.loc4_6.2: type = bind_symbolic_name T 0, %T.loc4_6.1 [symbolic = %T.loc4_6.2 (constants.%T)]
-// CHECK:STDOUT:     %T.ref.loc4: type = name_ref T, %T.loc4_6.2 [symbolic = %T.loc4_6.2 (constants.%T)]
-// CHECK:STDOUT:     %.loc4: type = ptr_type %T [symbolic = %.loc4 (constants.%.1)]
+// CHECK:STDOUT:     %T.loc4_6.2: type = bind_symbolic_name T 0, %T.loc4_6.1 [symbolic = @F.%T.1 (constants.%T)]
+// CHECK:STDOUT:     %T.ref.loc4: type = name_ref T, %T.loc4_6.2 [symbolic = @F.%T.1 (constants.%T)]
+// CHECK:STDOUT:     %.loc4: type = ptr_type %T [symbolic = @F.%.1 (constants.%.1)]
 // CHECK:STDOUT:     %return.var.loc4: ref %.1 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl.loc6: %F.type = fn_decl @F [template = constants.%F] {
 // CHECK:STDOUT:     %T.loc6_6.1: type = param T
-// CHECK:STDOUT:     @F.%T: type = bind_symbolic_name T 0, %T.loc6_6.1 [symbolic = constants.%T]
-// CHECK:STDOUT:     %T.ref.loc6: type = name_ref T, @F.%T [symbolic = constants.%T]
+// CHECK:STDOUT:     @F.%T.loc6: type = bind_symbolic_name T 0, %T.loc6_6.1 [symbolic = constants.%T]
+// CHECK:STDOUT:     %T.ref.loc6: type = name_ref T, @F.%T.loc6 [symbolic = constants.%T]
 // CHECK:STDOUT:     %.loc6: type = ptr_type %T [symbolic = constants.%.1]
 // CHECK:STDOUT:     @F.%return: ref %.1 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F(%T: type) -> %.1
-// CHECK:STDOUT:     generic [file.%T.loc4_6.2: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %F.ref: %F.type = name_ref F, file.%F.decl.loc4 [template = constants.%F]
-// CHECK:STDOUT:   %T.ref: type = name_ref T, %T [symbolic = file.%T.loc4_6.2 (constants.%T)]
-// CHECK:STDOUT:   %F.call: init file.%.loc4 (%.1) = call %F.ref(%T.ref)
-// CHECK:STDOUT:   %.loc7_14.1: file.%.loc4 (%.1) = value_of_initializer %F.call
-// CHECK:STDOUT:   %.loc7_14.2: file.%.loc4 (%.1) = converted %F.call, %.loc7_14.1
-// CHECK:STDOUT:   return %.loc7_14.2
+// CHECK:STDOUT: generic fn @F(file.%T.loc4_6.2: type) {
+// CHECK:STDOUT:   %T.1: type = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:   %.1: type = ptr_type @F.%T.1 (%T) [symbolic = %.1 (constants.%.1)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%T.loc6: type) -> %.1 {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %F.ref: %F.type = name_ref F, file.%F.decl.loc4 [template = constants.%F]
+// CHECK:STDOUT:     %T.ref: type = name_ref T, %T.loc6 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:     %F.call: init @F.%.1 (%.1) = call %F.ref(%T.ref)
+// CHECK:STDOUT:     %.loc7_14.1: @F.%.1 (%.1) = value_of_initializer %F.call
+// CHECK:STDOUT:     %.loc7_14.2: @F.%.1 (%.1) = converted %F.call, %.loc7_14.1
+// CHECK:STDOUT:     return %.loc7_14.2
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%F.decl.loc4(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_6.2 => constants.%T
-// CHECK:STDOUT:   file.%.loc4 => constants.%.1
+// CHECK:STDOUT: specific @F(constants.%T) {
+// CHECK:STDOUT:   %T.1 => constants.%T
+// CHECK:STDOUT:   %.1 => constants.%.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_different_return_type.carbon
@@ -190,48 +195,59 @@ fn F(U:! type, T:! type) -> U* {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
 // CHECK:STDOUT:     %T.loc4_6.1: type = param T
-// CHECK:STDOUT:     @F.%T: type = bind_symbolic_name T 0, %T.loc4_6.1 [symbolic = @F.%T (constants.%T)]
+// CHECK:STDOUT:     @F.%T.loc4: type = bind_symbolic_name T 0, %T.loc4_6.1 [symbolic = @F.%T.1 (constants.%T)]
 // CHECK:STDOUT:     %U.loc4_16.1: type = param U
-// CHECK:STDOUT:     @F.%U: type = bind_symbolic_name U 1, %U.loc4_16.1 [symbolic = @F.%U (constants.%U)]
-// CHECK:STDOUT:     %T.ref: type = name_ref T, @F.%T [symbolic = @F.%T (constants.%T)]
-// CHECK:STDOUT:     %.loc4: type = ptr_type %T [symbolic = %.loc4 (constants.%.1)]
+// CHECK:STDOUT:     @F.%U.loc4: type = bind_symbolic_name U 1, %U.loc4_16.1 [symbolic = @F.%U.1 (constants.%U)]
+// CHECK:STDOUT:     %T.ref: type = name_ref T, @F.%T.loc4 [symbolic = @F.%T.1 (constants.%T)]
+// CHECK:STDOUT:     %.loc4: type = ptr_type %T [symbolic = @F.%.1 (constants.%.1)]
 // CHECK:STDOUT:     @F.%return: ref %.1 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.decl: %.type = fn_decl @.1 [template = constants.%.4] {
 // CHECK:STDOUT:     %T.loc13_6.1: type = param T
-// CHECK:STDOUT:     @.1.%T: type = bind_symbolic_name T 0, %T.loc13_6.1 [symbolic = @.1.%T (constants.%T)]
+// CHECK:STDOUT:     @.1.%T.loc13: type = bind_symbolic_name T 0, %T.loc13_6.1 [symbolic = @.1.%T.1 (constants.%T)]
 // CHECK:STDOUT:     %U.loc13_16.1: type = param U
-// CHECK:STDOUT:     @.1.%U: type = bind_symbolic_name U 1, %U.loc13_16.1 [symbolic = @.1.%U (constants.%U)]
-// CHECK:STDOUT:     %U.ref: type = name_ref U, @.1.%U [symbolic = @.1.%U (constants.%U)]
-// CHECK:STDOUT:     %.loc13: type = ptr_type %U [symbolic = %.loc13 (constants.%.3)]
+// CHECK:STDOUT:     @.1.%U.loc13: type = bind_symbolic_name U 1, %U.loc13_16.1 [symbolic = @.1.%U.1 (constants.%U)]
+// CHECK:STDOUT:     %U.ref: type = name_ref U, @.1.%U.loc13 [symbolic = @.1.%U.1 (constants.%U)]
+// CHECK:STDOUT:     %.loc13: type = ptr_type %U [symbolic = @.1.%.1 (constants.%.3)]
 // CHECK:STDOUT:     @.1.%return: ref %.3 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F(%T: type, %U: type) -> %.1
-// CHECK:STDOUT:     generic [%T: type, %U: type];
+// CHECK:STDOUT: generic fn @F(%T.loc4: type, %U.loc4: type) {
+// CHECK:STDOUT:   %T.1: type = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:   %U.1: type = bind_symbolic_name U 1 [symbolic = %U.1 (constants.%U)]
+// CHECK:STDOUT:   %.1: type = ptr_type @F.%T.1 (%T) [symbolic = %.1 (constants.%.1)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @.1(%T: type, %U: type) -> %.3
-// CHECK:STDOUT:     generic [%T: type, %U: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
-// CHECK:STDOUT:   %T.ref: type = name_ref T, %T [symbolic = %T (constants.%T)]
-// CHECK:STDOUT:   %F.call: init <unexpected>.inst+32 (%.1) = call %F.ref(<invalid>) [template = <error>]
-// CHECK:STDOUT:   return <error>
+// CHECK:STDOUT:   fn(%T.loc4: type, %U.loc4: type) -> %.1;
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%F.decl(constants.%T, constants.%U) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @F.%T => constants.%T
-// CHECK:STDOUT:   @F.%U => constants.%U
-// CHECK:STDOUT:   file.%.loc4 => constants.%.1
+// CHECK:STDOUT: generic fn @.1(%T.loc13: type, %U.loc13: type) {
+// CHECK:STDOUT:   %T.1: type = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:   %U.1: type = bind_symbolic_name U 1 [symbolic = %U.1 (constants.%U)]
+// CHECK:STDOUT:   %.1: type = ptr_type @.1.%U.1 (%U) [symbolic = %.1 (constants.%.3)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.2: type = ptr_type @.1.%T.1 (%T) [symbolic = %.2 (constants.%.1)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%T.loc13: type, %U.loc13: type) -> %.3 {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
+// CHECK:STDOUT:     %T.ref: type = name_ref T, %T.loc13 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:     %F.call: init @.1.%.2 (%.1) = call %F.ref(<invalid>) [template = <error>]
+// CHECK:STDOUT:     return <error>
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F(constants.%T, constants.%U) {
+// CHECK:STDOUT:   %T.1 => constants.%T
+// CHECK:STDOUT:   %U.1 => constants.%U
+// CHECK:STDOUT:   %.1 => constants.%.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%.decl(constants.%T, constants.%U) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @.1.%T => constants.%T
-// CHECK:STDOUT:   @.1.%U => constants.%U
-// CHECK:STDOUT:   file.%.loc13 => constants.%.3
+// CHECK:STDOUT: specific @.1(constants.%T, constants.%U) {
+// CHECK:STDOUT:   %T.1 => constants.%T
+// CHECK:STDOUT:   %U.1 => constants.%U
+// CHECK:STDOUT:   %.1 => constants.%.3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_reorder.carbon
@@ -267,48 +283,60 @@ fn F(U:! type, T:! type) -> U* {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
 // CHECK:STDOUT:     %T.loc4_6.1: type = param T
-// CHECK:STDOUT:     @F.%T: type = bind_symbolic_name T 0, %T.loc4_6.1 [symbolic = @F.%T (constants.%T.1)]
+// CHECK:STDOUT:     @F.%T.loc4: type = bind_symbolic_name T 0, %T.loc4_6.1 [symbolic = @F.%T.1 (constants.%T.1)]
 // CHECK:STDOUT:     %U.loc4_16.1: type = param U
-// CHECK:STDOUT:     @F.%U: type = bind_symbolic_name U 1, %U.loc4_16.1 [symbolic = @F.%U (constants.%U.1)]
-// CHECK:STDOUT:     %T.ref.loc4: type = name_ref T, @F.%T [symbolic = @F.%T (constants.%T.1)]
-// CHECK:STDOUT:     %.loc4: type = ptr_type %T.1 [symbolic = %.loc4 (constants.%.1)]
+// CHECK:STDOUT:     @F.%U.loc4: type = bind_symbolic_name U 1, %U.loc4_16.1 [symbolic = @F.%U.1 (constants.%U.1)]
+// CHECK:STDOUT:     %T.ref.loc4: type = name_ref T, @F.%T.loc4 [symbolic = @F.%T.1 (constants.%T.1)]
+// CHECK:STDOUT:     %.loc4: type = ptr_type %T.1 [symbolic = @F.%.1 (constants.%.1)]
 // CHECK:STDOUT:     @F.%return: ref %.1 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.decl: %.type = fn_decl @.1 [template = constants.%.4] {
 // CHECK:STDOUT:     %U.loc13_6.1: type = param U
-// CHECK:STDOUT:     @.1.%U: type = bind_symbolic_name U 0, %U.loc13_6.1 [symbolic = @.1.%U (constants.%U.2)]
+// CHECK:STDOUT:     @.1.%U.loc13: type = bind_symbolic_name U 0, %U.loc13_6.1 [symbolic = @.1.%U.1 (constants.%U.2)]
 // CHECK:STDOUT:     %T.loc13_16.1: type = param T
-// CHECK:STDOUT:     @.1.%T: type = bind_symbolic_name T 1, %T.loc13_16.1 [symbolic = @.1.%T (constants.%T.2)]
-// CHECK:STDOUT:     %T.ref.loc13: type = name_ref T, @.1.%T [symbolic = @.1.%T (constants.%T.2)]
-// CHECK:STDOUT:     %.loc13: type = ptr_type %T.2 [symbolic = %.loc13 (constants.%.3)]
+// CHECK:STDOUT:     @.1.%T.loc13: type = bind_symbolic_name T 1, %T.loc13_16.1 [symbolic = @.1.%T.1 (constants.%T.2)]
+// CHECK:STDOUT:     %T.ref.loc13: type = name_ref T, @.1.%T.loc13 [symbolic = @.1.%T.1 (constants.%T.2)]
+// CHECK:STDOUT:     %.loc13: type = ptr_type %T.2 [symbolic = @.1.%.1 (constants.%.3)]
 // CHECK:STDOUT:     @.1.%return: ref %.3 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F(%T: type, %U: type) -> %.1
-// CHECK:STDOUT:     generic [%T: type, %U: type];
+// CHECK:STDOUT: generic fn @F(%T.loc4: type, %U.loc4: type) {
+// CHECK:STDOUT:   %T.1: type = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T.1)]
+// CHECK:STDOUT:   %U.1: type = bind_symbolic_name U 1 [symbolic = %U.1 (constants.%U.1)]
+// CHECK:STDOUT:   %.1: type = ptr_type @F.%T.1 (%T.1) [symbolic = %.1 (constants.%.1)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%T.loc4: type, %U.loc4: type) -> %.1;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @.1(%U.loc13: type, %T.loc13: type) {
+// CHECK:STDOUT:   %U.1: type = bind_symbolic_name U 0 [symbolic = %U.1 (constants.%U.2)]
+// CHECK:STDOUT:   %T.1: type = bind_symbolic_name T 1 [symbolic = %T.1 (constants.%T.2)]
+// CHECK:STDOUT:   %.1: type = ptr_type @.1.%T.1 (%T.2) [symbolic = %.1 (constants.%.3)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %T.2: type = bind_symbolic_name T 0 [symbolic = %T.2 (constants.%T.1)]
+// CHECK:STDOUT:   %.2: type = ptr_type @.1.%T.2 (%T.1) [symbolic = %.2 (constants.%.1)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @.1(%U: type, %T: type) -> %.3
-// CHECK:STDOUT:     generic [%U: type, %T: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
-// CHECK:STDOUT:   %T.ref: type = name_ref T, %T [symbolic = %T (constants.%T.2)]
-// CHECK:STDOUT:   %F.call: init %.1 = call %F.ref(<invalid>) [template = <error>]
-// CHECK:STDOUT:   return <error>
+// CHECK:STDOUT:   fn(%U.loc13: type, %T.loc13: type) -> %.3 {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
+// CHECK:STDOUT:     %T.ref: type = name_ref T, %T.loc13 [symbolic = %T.1 (constants.%T.2)]
+// CHECK:STDOUT:     %F.call: init @.1.%.2 (%.1) = call %F.ref(<invalid>) [template = <error>]
+// CHECK:STDOUT:     return <error>
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%F.decl(constants.%T.1, constants.%U.1) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @F.%T => constants.%T.1
-// CHECK:STDOUT:   @F.%U => constants.%U.1
-// CHECK:STDOUT:   file.%.loc4 => constants.%.1
+// CHECK:STDOUT: specific @F(constants.%T.1, constants.%U.1) {
+// CHECK:STDOUT:   %T.1 => constants.%T.1
+// CHECK:STDOUT:   %U.1 => constants.%U.1
+// CHECK:STDOUT:   %.1 => constants.%.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%.decl(constants.%U.2, constants.%T.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @.1.%U => constants.%U.2
-// CHECK:STDOUT:   @.1.%T => constants.%T.2
-// CHECK:STDOUT:   file.%.loc13 => constants.%.3
+// CHECK:STDOUT: specific @.1(constants.%U.2, constants.%T.2) {
+// CHECK:STDOUT:   %U.1 => constants.%U.2
+// CHECK:STDOUT:   %T.1 => constants.%T.2
+// CHECK:STDOUT:   %.1 => constants.%.3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_rename.carbon
@@ -344,47 +372,59 @@ fn F(U:! type, T:! type) -> U* {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
 // CHECK:STDOUT:     %T.loc4_6.1: type = param T
-// CHECK:STDOUT:     @F.%T: type = bind_symbolic_name T 0, %T.loc4_6.1 [symbolic = @F.%T (constants.%T.1)]
+// CHECK:STDOUT:     @F.%T.loc4: type = bind_symbolic_name T 0, %T.loc4_6.1 [symbolic = @F.%T.1 (constants.%T.1)]
 // CHECK:STDOUT:     %U.loc4_16.1: type = param U
-// CHECK:STDOUT:     @F.%U: type = bind_symbolic_name U 1, %U.loc4_16.1 [symbolic = @F.%U (constants.%U.1)]
-// CHECK:STDOUT:     %T.ref: type = name_ref T, @F.%T [symbolic = @F.%T (constants.%T.1)]
-// CHECK:STDOUT:     %.loc4: type = ptr_type %T.1 [symbolic = %.loc4 (constants.%.1)]
+// CHECK:STDOUT:     @F.%U.loc4: type = bind_symbolic_name U 1, %U.loc4_16.1 [symbolic = @F.%U.1 (constants.%U.1)]
+// CHECK:STDOUT:     %T.ref: type = name_ref T, @F.%T.loc4 [symbolic = @F.%T.1 (constants.%T.1)]
+// CHECK:STDOUT:     %.loc4: type = ptr_type %T.1 [symbolic = @F.%.1 (constants.%.1)]
 // CHECK:STDOUT:     @F.%return: ref %.1 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.decl: %.type = fn_decl @.1 [template = constants.%.4] {
 // CHECK:STDOUT:     %U.loc13_6.1: type = param U
-// CHECK:STDOUT:     @.1.%U: type = bind_symbolic_name U 0, %U.loc13_6.1 [symbolic = @.1.%U (constants.%U.2)]
+// CHECK:STDOUT:     @.1.%U.loc13: type = bind_symbolic_name U 0, %U.loc13_6.1 [symbolic = @.1.%U.1 (constants.%U.2)]
 // CHECK:STDOUT:     %T.loc13_16.1: type = param T
-// CHECK:STDOUT:     @.1.%T: type = bind_symbolic_name T 1, %T.loc13_16.1 [symbolic = @.1.%T (constants.%T.2)]
-// CHECK:STDOUT:     %U.ref: type = name_ref U, @.1.%U [symbolic = @.1.%U (constants.%U.2)]
-// CHECK:STDOUT:     %.loc13: type = ptr_type %U.2 [symbolic = %.loc13 (constants.%.3)]
+// CHECK:STDOUT:     @.1.%T.loc13: type = bind_symbolic_name T 1, %T.loc13_16.1 [symbolic = @.1.%T.1 (constants.%T.2)]
+// CHECK:STDOUT:     %U.ref: type = name_ref U, @.1.%U.loc13 [symbolic = @.1.%U.1 (constants.%U.2)]
+// CHECK:STDOUT:     %.loc13: type = ptr_type %U.2 [symbolic = @.1.%.1 (constants.%.3)]
 // CHECK:STDOUT:     @.1.%return: ref %.3 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F(%T: type, %U: type) -> %.1
-// CHECK:STDOUT:     generic [%T: type, %U: type];
+// CHECK:STDOUT: generic fn @F(%T.loc4: type, %U.loc4: type) {
+// CHECK:STDOUT:   %T.1: type = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T.1)]
+// CHECK:STDOUT:   %U.1: type = bind_symbolic_name U 1 [symbolic = %U.1 (constants.%U.1)]
+// CHECK:STDOUT:   %.1: type = ptr_type @F.%T.1 (%T.1) [symbolic = %.1 (constants.%.1)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @.1(%U: type, %T: type) -> %.3
-// CHECK:STDOUT:     generic [%U: type, %T: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
-// CHECK:STDOUT:   %T.ref: type = name_ref T, %T [symbolic = %T (constants.%T.2)]
-// CHECK:STDOUT:   %F.call: init %.1 = call %F.ref(<invalid>) [template = <error>]
-// CHECK:STDOUT:   return <error>
+// CHECK:STDOUT:   fn(%T.loc4: type, %U.loc4: type) -> %.1;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @.1(%U.loc13: type, %T.loc13: type) {
+// CHECK:STDOUT:   %U.1: type = bind_symbolic_name U 0 [symbolic = %U.1 (constants.%U.2)]
+// CHECK:STDOUT:   %T.1: type = bind_symbolic_name T 1 [symbolic = %T.1 (constants.%T.2)]
+// CHECK:STDOUT:   %.1: type = ptr_type @.1.%U.1 (%U.2) [symbolic = %.1 (constants.%.3)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %T.2: type = bind_symbolic_name T 0 [symbolic = %T.2 (constants.%T.1)]
+// CHECK:STDOUT:   %.2: type = ptr_type @.1.%T.2 (%T.1) [symbolic = %.2 (constants.%.1)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%U.loc13: type, %T.loc13: type) -> %.3 {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
+// CHECK:STDOUT:     %T.ref: type = name_ref T, %T.loc13 [symbolic = %T.1 (constants.%T.2)]
+// CHECK:STDOUT:     %F.call: init @.1.%.2 (%.1) = call %F.ref(<invalid>) [template = <error>]
+// CHECK:STDOUT:     return <error>
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%F.decl(constants.%T.1, constants.%U.1) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @F.%T => constants.%T.1
-// CHECK:STDOUT:   @F.%U => constants.%U.1
-// CHECK:STDOUT:   file.%.loc4 => constants.%.1
+// CHECK:STDOUT: specific @F(constants.%T.1, constants.%U.1) {
+// CHECK:STDOUT:   %T.1 => constants.%T.1
+// CHECK:STDOUT:   %U.1 => constants.%U.1
+// CHECK:STDOUT:   %.1 => constants.%.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%.decl(constants.%U.2, constants.%T.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @.1.%U => constants.%U.2
-// CHECK:STDOUT:   @.1.%T => constants.%T.2
-// CHECK:STDOUT:   file.%.loc13 => constants.%.3
+// CHECK:STDOUT: specific @.1(constants.%U.2, constants.%T.2) {
+// CHECK:STDOUT:   %U.1 => constants.%U.2
+// CHECK:STDOUT:   %T.1 => constants.%T.2
+// CHECK:STDOUT:   %.1 => constants.%.3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 17 - 15
toolchain/check/testdata/impl/compound.carbon

@@ -138,11 +138,11 @@ fn InstanceCallIndirect(p: i32*) {
 // CHECK:STDOUT:   %F.decl: %F.type.1 = fn_decl @F.1 [template = constants.%F.1] {}
 // CHECK:STDOUT:   %.loc12: %.3 = assoc_entity element0, %F.decl [template = constants.%.4]
 // CHECK:STDOUT:   %G.decl: %G.type.1 = fn_decl @G.1 [template = constants.%G.1] {
-// CHECK:STDOUT:     %Self.ref: %.1 = name_ref Self, %Self [symbolic = %Self.ref (constants.%Self)]
-// CHECK:STDOUT:     %.loc13_14.1: type = facet_type_access %Self.ref [symbolic = %Self.ref (constants.%Self)]
-// CHECK:STDOUT:     %.loc13_14.2: type = converted %Self.ref, %.loc13_14.1 [symbolic = %Self.ref (constants.%Self)]
-// CHECK:STDOUT:     %self.loc13_8.1: @Simple.%Self.ref (%Self) = param self
-// CHECK:STDOUT:     %self.loc13_8.2: @Simple.%Self.ref (%Self) = bind_name self, %self.loc13_8.1
+// CHECK:STDOUT:     %Self.ref: %.1 = name_ref Self, %Self [symbolic = @G.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc13_14.1: type = facet_type_access %Self.ref [symbolic = @G.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc13_14.2: type = converted %Self.ref, %.loc13_14.1 [symbolic = @G.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %self.loc13_8.1: @G.1.%Self (%Self) = param self
+// CHECK:STDOUT:     %self.loc13_8.2: @G.1.%Self (%Self) = bind_name self, %self.loc13_8.1
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.loc13_21: %.5 = assoc_entity element1, %G.decl [template = constants.%.6]
 // CHECK:STDOUT:
@@ -170,11 +170,16 @@ fn InstanceCallIndirect(p: i32*) {
 // CHECK:STDOUT:   witness = %.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.1()
-// CHECK:STDOUT:     generic [@Simple.%Self: %.1];
+// CHECK:STDOUT: generic fn @F.1(@Simple.%Self: %.1) {
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @G.1[@Simple.%self.loc13_8.2: @Simple.%Self.ref (%Self)]()
-// CHECK:STDOUT:     generic [@Simple.%Self: %.1];
+// CHECK:STDOUT:   fn();
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @G.1(@Simple.%Self: %.1) {
+// CHECK:STDOUT:   %Self: %.1 = bind_symbolic_name Self 0 [symbolic = %Self (constants.%Self)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn[@Simple.%self.loc13_8.2: @G.1.%Self (%Self)]();
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
@@ -227,12 +232,9 @@ fn InstanceCallIndirect(p: i32*) {
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Simple.%F.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT: }
+// CHECK:STDOUT: specific @F.1(constants.%Self) {}
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Simple.%G.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @Simple.%Self.ref => constants.%Self
+// CHECK:STDOUT: specific @G.1(constants.%Self) {
+// CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

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

@@ -99,8 +99,10 @@ fn G(c: C) {
 // CHECK:STDOUT:   extend name_scope2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.1()
-// CHECK:STDOUT:     generic [@HasF.%Self: %.1];
+// CHECK:STDOUT: generic fn @F.1(@HasF.%Self: %.1) {
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn();
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.2() {
 // CHECK:STDOUT: !entry:
@@ -120,7 +122,5 @@ fn G(c: C) {
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @HasF.%F.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT: }
+// CHECK:STDOUT: specific @F.1(constants.%Self) {}
 // CHECK:STDOUT:

+ 12 - 10
toolchain/check/testdata/impl/fail_call_invalid.carbon

@@ -81,11 +81,11 @@ fn InstanceCall(n: i32) {
 // CHECK:STDOUT: interface @Simple {
 // CHECK:STDOUT:   %Self: %.1 = bind_symbolic_name Self 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %G.decl: %G.type.1 = fn_decl @G.1 [template = constants.%G.1] {
-// CHECK:STDOUT:     %Self.ref: %.1 = name_ref Self, %Self [symbolic = %Self.ref (constants.%Self)]
-// CHECK:STDOUT:     %.loc12_14.1: type = facet_type_access %Self.ref [symbolic = %Self.ref (constants.%Self)]
-// CHECK:STDOUT:     %.loc12_14.2: type = converted %Self.ref, %.loc12_14.1 [symbolic = %Self.ref (constants.%Self)]
-// CHECK:STDOUT:     %self.loc12_8.1: @Simple.%Self.ref (%Self) = param self
-// CHECK:STDOUT:     %self.loc12_8.2: @Simple.%Self.ref (%Self) = bind_name self, %self.loc12_8.1
+// CHECK:STDOUT:     %Self.ref: %.1 = name_ref Self, %Self [symbolic = @G.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc12_14.1: type = facet_type_access %Self.ref [symbolic = @G.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc12_14.2: type = converted %Self.ref, %.loc12_14.1 [symbolic = @G.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %self.loc12_8.1: @G.1.%Self (%Self) = param self
+// CHECK:STDOUT:     %self.loc12_8.2: @G.1.%Self (%Self) = bind_name self, %self.loc12_8.1
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.loc12_21: %.3 = assoc_entity element0, %G.decl [template = constants.%.4]
 // CHECK:STDOUT:
@@ -108,8 +108,11 @@ fn InstanceCall(n: i32) {
 // CHECK:STDOUT:   witness = %.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @G.1[@Simple.%self.loc12_8.2: @Simple.%Self.ref (%Self)]()
-// CHECK:STDOUT:     generic [@Simple.%Self: %.1];
+// CHECK:STDOUT: generic fn @G.1(@Simple.%Self: %.1) {
+// CHECK:STDOUT:   %Self: %.1 = bind_symbolic_name Self 0 [symbolic = %Self (constants.%Self)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn[@Simple.%self.loc12_8.2: @G.1.%Self (%Self)]();
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
@@ -125,8 +128,7 @@ fn InstanceCall(n: i32) {
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Simple.%G.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @Simple.%Self.ref => constants.%Self
+// CHECK:STDOUT: specific @G.1(constants.%Self) {
+// CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 47 - 36
toolchain/check/testdata/impl/fail_extend_impl_forall.carbon

@@ -28,7 +28,7 @@ class C {
 // CHECK:STDOUT:   %GenericInterface.type: type = generic_interface_type @GenericInterface [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %GenericInterface: %GenericInterface.type = struct_value () [template]
-// CHECK:STDOUT:   %.2: type = interface_type @GenericInterface, file.%GenericInterface.decl(%T) [symbolic]
+// CHECK:STDOUT:   %.2: type = interface_type @GenericInterface, @GenericInterface(%T) [symbolic]
 // CHECK:STDOUT:   %Self: %.2 = bind_symbolic_name Self 1 [symbolic]
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
@@ -59,32 +59,39 @@ class C {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %GenericInterface.decl: %GenericInterface.type = interface_decl @GenericInterface [template = constants.%GenericInterface] {
 // CHECK:STDOUT:     %T.loc11_28.1: type = param T
-// CHECK:STDOUT:     %T.loc11_28.2: type = bind_symbolic_name T 0, %T.loc11_28.1 [symbolic = %T.loc11_28.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc11_28.2: type = bind_symbolic_name T 0, %T.loc11_28.1 [symbolic = @GenericInterface.%T (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: interface @GenericInterface
-// CHECK:STDOUT:     generic [file.%T.loc11_28.2: type] {
-// CHECK:STDOUT:   %Self: <unexpected>.inst+22 (%.2) = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self)]
-// CHECK:STDOUT:   %F.decl: %F.type.1 = fn_decl @F.1 [template = constants.%F.1] {
-// CHECK:STDOUT:     %T.ref: type = name_ref T, file.%T.loc11_28.2 [symbolic = %T.ref (constants.%T)]
-// CHECK:STDOUT:     %x.loc12_8.1: @GenericInterface.%T.ref (%T) = param x
-// CHECK:STDOUT:     %x.loc12_8.2: @GenericInterface.%T.ref (%T) = bind_name x, %x.loc12_8.1
-// CHECK:STDOUT:   }
-// CHECK:STDOUT:   %.loc12: %.3 = assoc_entity element0, %F.decl [template = constants.%.4]
+// CHECK:STDOUT: generic interface @GenericInterface(file.%T.loc11_28.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .F = %.loc12
-// CHECK:STDOUT:   witness = (%F.decl)
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1: type = interface_type @GenericInterface, @GenericInterface(%T) [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:   %Self.2: %.2 = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   interface {
+// CHECK:STDOUT:     %Self.1: @GenericInterface.%.1 (%.2) = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self)]
+// CHECK:STDOUT:     %F.decl: %F.type.1 = fn_decl @F.1 [template = constants.%F.1] {
+// CHECK:STDOUT:       %T.ref: type = name_ref T, file.%T.loc11_28.2 [symbolic = @F.1.%T (constants.%T)]
+// CHECK:STDOUT:       %x.loc12_8.1: @F.1.%T (%T) = param x
+// CHECK:STDOUT:       %x.loc12_8.2: @F.1.%T (%T) = bind_name x, %x.loc12_8.1
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %.loc12: %.3 = assoc_entity element0, %F.decl [template = constants.%.4]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = %Self.1
+// CHECK:STDOUT:     .F = %.loc12
+// CHECK:STDOUT:     witness = (%F.decl)
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %C as %.2 {
 // CHECK:STDOUT:   %F.decl: %F.type.2 = fn_decl @F.2 [template = constants.%F.2] {
-// CHECK:STDOUT:     %T.ref: type = name_ref T, @C.%T.loc19_23.2 [symbolic = %T.ref (constants.%T)]
-// CHECK:STDOUT:     %x.loc20_10.1: @impl.%T.ref (%T) = param x
-// CHECK:STDOUT:     %x.loc20_10.2: @impl.%T.ref (%T) = bind_name x, %x.loc20_10.1
+// CHECK:STDOUT:     %T.ref: type = name_ref T, @C.%T.loc19_23.2 [symbolic = @F.2.%T (constants.%T)]
+// CHECK:STDOUT:     %x.loc20_10.1: @F.2.%T (%T) = param x
+// CHECK:STDOUT:     %x.loc20_10.2: @F.2.%T (%T) = bind_name x, %x.loc20_10.1
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.1: <witness> = interface_witness (%F.decl) [template = constants.%.5]
 // CHECK:STDOUT:
@@ -109,32 +116,36 @@ class C {
 // CHECK:STDOUT:   has_error
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.1(@GenericInterface.%x.loc12_8.2: @GenericInterface.%T.ref (%T))
-// CHECK:STDOUT:     generic [file.%T.loc11_28.2: type, @GenericInterface.%Self: <unexpected>.inst+22 (%.2)];
+// CHECK:STDOUT: generic fn @F.1(file.%T.loc11_28.2: type, @GenericInterface.%Self.1: @GenericInterface.%.1 (%.2)) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.2(@impl.%x.loc20_10.2: @impl.%T.ref (%T))
-// CHECK:STDOUT:     generic [@C.%T.loc19_23.2: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   return
+// CHECK:STDOUT:   fn(@GenericInterface.%x.loc12_8.2: @F.1.%T (%T));
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @F.2(@C.%T.loc19_23.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(@impl.%x.loc20_10.2: @F.2.%T (%T)) {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%GenericInterface.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc11_28.2 => constants.%T
+// CHECK:STDOUT: specific @GenericInterface(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @GenericInterface.%F.decl(constants.%T, constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @GenericInterface.%T.ref => constants.%T
+// CHECK:STDOUT: specific @F.1(constants.%T, constants.%Self) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%GenericInterface.decl(file.%T.loc11_28.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc11_28.2 => constants.%T
+// CHECK:STDOUT: specific @GenericInterface(@GenericInterface.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @impl.%F.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @impl.%T.ref => constants.%T
+// CHECK:STDOUT: specific @F.2(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 12 - 11
toolchain/check/testdata/impl/fail_extend_partially_defined_interface.carbon

@@ -59,18 +59,19 @@ interface I {
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %C as %.1;
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @C
-// CHECK:STDOUT:     generic [@I.%Self: %.1] {
-// CHECK:STDOUT:   impl_decl @impl {
-// CHECK:STDOUT:     %I.ref: type = name_ref I, file.%I.decl [template = constants.%.1]
-// CHECK:STDOUT:   }
+// CHECK:STDOUT: generic class @C(@I.%Self: %.1) {
+// CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%C
-// CHECK:STDOUT:   has_error
-// CHECK:STDOUT: }
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:     impl_decl @impl {
+// CHECK:STDOUT:       %I.ref: type = name_ref I, file.%I.decl [template = constants.%.1]
+// CHECK:STDOUT:     }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @I.%C.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%C
+// CHECK:STDOUT:     has_error
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @C(constants.%Self) {}
+// CHECK:STDOUT:

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

@@ -75,15 +75,15 @@ impl as Simple {
 // CHECK:STDOUT:   witness = %.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.1()
-// CHECK:STDOUT:     generic [@Simple.%Self: %.1];
+// CHECK:STDOUT: generic fn @F.1(@Simple.%Self: %.1) {
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn();
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.2() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Simple.%F.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT: }
+// CHECK:STDOUT: specific @F.1(constants.%Self) {}
 // CHECK:STDOUT:

+ 70 - 64
toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon

@@ -278,26 +278,27 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT:   %.13: type = tuple_type (%.10, %.11) [symbolic]
 // CHECK:STDOUT:   %.14: i32 = int_literal 4 [template]
 // CHECK:STDOUT:   %.15: type = array_type %.14, %Self.3 [symbolic]
+// CHECK:STDOUT:   %.16: type = tuple_type (@F.13.%.1 (%.10), @F.13.%.2 (%.11)) [symbolic]
 // CHECK:STDOUT:   %F.type.13: type = fn_type @F.13 [template]
 // CHECK:STDOUT:   %F.14: %F.type.13 = struct_value () [template]
-// CHECK:STDOUT:   %.16: type = assoc_entity_type @SelfNested, %F.type.13 [template]
-// CHECK:STDOUT:   %.17: %.16 = assoc_entity element0, @SelfNested.%F.decl [template]
+// CHECK:STDOUT:   %.17: type = assoc_entity_type @SelfNested, %F.type.13 [template]
+// CHECK:STDOUT:   %.18: %.17 = assoc_entity element0, @SelfNested.%F.decl [template]
 // CHECK:STDOUT:   %SelfNestedBadParam: type = class_type @SelfNestedBadParam [template]
-// CHECK:STDOUT:   %.18: type = ptr_type %SelfNestedBadParam [template]
-// CHECK:STDOUT:   %.19: type = struct_type {.x: i32, .y: i32} [template]
-// CHECK:STDOUT:   %.20: type = tuple_type (%.18, %.19) [template]
-// CHECK:STDOUT:   %.21: type = array_type %.14, %SelfNestedBadParam [template]
+// CHECK:STDOUT:   %.19: type = ptr_type %SelfNestedBadParam [template]
+// CHECK:STDOUT:   %.20: type = struct_type {.x: i32, .y: i32} [template]
+// CHECK:STDOUT:   %.21: type = tuple_type (%.19, %.20) [template]
+// CHECK:STDOUT:   %.22: type = array_type %.14, %SelfNestedBadParam [template]
 // CHECK:STDOUT:   %F.type.14: type = fn_type @F.14 [template]
 // CHECK:STDOUT:   %F.15: %F.type.14 = struct_value () [template]
-// CHECK:STDOUT:   %.22: type = struct_type {.x: %SelfNestedBadParam, .y: i32} [template]
-// CHECK:STDOUT:   %.23: type = tuple_type (%.18, %.22) [template]
+// CHECK:STDOUT:   %.23: type = struct_type {.x: %SelfNestedBadParam, .y: i32} [template]
+// CHECK:STDOUT:   %.24: type = tuple_type (%.19, %.23) [template]
 // CHECK:STDOUT:   %SelfNestedBadReturnType: type = class_type @SelfNestedBadReturnType [template]
-// CHECK:STDOUT:   %.24: type = ptr_type %SelfNestedBadReturnType [template]
-// CHECK:STDOUT:   %.25: type = struct_type {.x: %SelfNestedBadReturnType, .y: i32} [template]
-// CHECK:STDOUT:   %.26: type = tuple_type (%.24, %.25) [template]
+// CHECK:STDOUT:   %.25: type = ptr_type %SelfNestedBadReturnType [template]
+// CHECK:STDOUT:   %.26: type = struct_type {.x: %SelfNestedBadReturnType, .y: i32} [template]
+// CHECK:STDOUT:   %.27: type = tuple_type (%.25, %.26) [template]
 // CHECK:STDOUT:   %F.type.15: type = fn_type @F.15 [template]
 // CHECK:STDOUT:   %F.16: %F.type.15 = struct_value () [template]
-// CHECK:STDOUT:   %.27: type = array_type %.14, %SelfNestedBadReturnType [template]
+// CHECK:STDOUT:   %.28: type = array_type %.14, %SelfNestedBadReturnType [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -421,29 +422,29 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT: interface @SelfNested {
 // CHECK:STDOUT:   %Self: %.9 = bind_symbolic_name Self 0 [symbolic = constants.%Self.3]
 // CHECK:STDOUT:   %F.decl: %F.type.13 = fn_decl @F.13 [template = constants.%F.14] {
-// CHECK:STDOUT:     %Self.ref.loc188_12: %.9 = name_ref Self, %Self [symbolic = %Self.ref.loc188_12 (constants.%Self.3)]
-// CHECK:STDOUT:     %.loc188_16.1: type = facet_type_access %Self.ref.loc188_12 [symbolic = %Self.ref.loc188_12 (constants.%Self.3)]
-// CHECK:STDOUT:     %.loc188_16.2: type = converted %Self.ref.loc188_12, %.loc188_16.1 [symbolic = %Self.ref.loc188_12 (constants.%Self.3)]
-// CHECK:STDOUT:     %.loc188_16.3: type = ptr_type %Self.3 [symbolic = %.loc188_16.3 (constants.%.10)]
-// CHECK:STDOUT:     %Self.ref.loc188_24: %.9 = name_ref Self, %Self [symbolic = %Self.ref.loc188_12 (constants.%Self.3)]
-// CHECK:STDOUT:     %.loc188_24.1: type = facet_type_access %Self.ref.loc188_24 [symbolic = %Self.ref.loc188_12 (constants.%Self.3)]
-// CHECK:STDOUT:     %.loc188_24.2: type = converted %Self.ref.loc188_24, %.loc188_24.1 [symbolic = %Self.ref.loc188_12 (constants.%Self.3)]
+// CHECK:STDOUT:     %Self.ref.loc188_12: %.9 = name_ref Self, %Self [symbolic = @F.13.%Self (constants.%Self.3)]
+// CHECK:STDOUT:     %.loc188_16.1: type = facet_type_access %Self.ref.loc188_12 [symbolic = @F.13.%Self (constants.%Self.3)]
+// CHECK:STDOUT:     %.loc188_16.2: type = converted %Self.ref.loc188_12, %.loc188_16.1 [symbolic = @F.13.%Self (constants.%Self.3)]
+// CHECK:STDOUT:     %.loc188_16.3: type = ptr_type %Self.3 [symbolic = @F.13.%.1 (constants.%.10)]
+// CHECK:STDOUT:     %Self.ref.loc188_24: %.9 = name_ref Self, %Self [symbolic = @F.13.%Self (constants.%Self.3)]
+// CHECK:STDOUT:     %.loc188_24.1: type = facet_type_access %Self.ref.loc188_24 [symbolic = @F.13.%Self (constants.%Self.3)]
+// CHECK:STDOUT:     %.loc188_24.2: type = converted %Self.ref.loc188_24, %.loc188_24.1 [symbolic = @F.13.%Self (constants.%Self.3)]
 // CHECK:STDOUT:     %int.make_type_32: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:     %.loc188_34.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:     %.loc188_34.2: type = converted %int.make_type_32, %.loc188_34.1 [template = i32]
-// CHECK:STDOUT:     %.loc188_37: type = struct_type {.x: %Self.3, .y: i32} [symbolic = %.loc188_37 (constants.%.11)]
+// CHECK:STDOUT:     %.loc188_37: type = struct_type {.x: %Self.3, .y: i32} [symbolic = @F.13.%.2 (constants.%.11)]
 // CHECK:STDOUT:     %.loc188_38.1: %.12 = tuple_literal (%.loc188_16.3, %.loc188_37)
-// CHECK:STDOUT:     %.loc188_38.2: type = converted %.loc188_38.1, constants.%.13 [symbolic = %.loc188_38.2 (constants.%.13)]
-// CHECK:STDOUT:     %x.loc188_8.1: @SelfNested.%.loc188_38.2 (%.13) = param x
-// CHECK:STDOUT:     %x.loc188_8.2: @SelfNested.%.loc188_38.2 (%.13) = bind_name x, %x.loc188_8.1
-// CHECK:STDOUT:     %Self.ref.loc188_45: %.9 = name_ref Self, %Self [symbolic = %Self.ref.loc188_12 (constants.%Self.3)]
+// CHECK:STDOUT:     %.loc188_38.2: type = converted %.loc188_38.1, constants.%.13 [symbolic = @F.13.%.3 (constants.%.13)]
+// CHECK:STDOUT:     %x.loc188_8.1: @F.13.%.3 (%.13) = param x
+// CHECK:STDOUT:     %x.loc188_8.2: @F.13.%.3 (%.13) = bind_name x, %x.loc188_8.1
+// CHECK:STDOUT:     %Self.ref.loc188_45: %.9 = name_ref Self, %Self [symbolic = @F.13.%Self (constants.%Self.3)]
 // CHECK:STDOUT:     %.loc188_51: i32 = int_literal 4 [template = constants.%.14]
-// CHECK:STDOUT:     %.loc188_45.1: type = facet_type_access %Self.ref.loc188_45 [symbolic = %Self.ref.loc188_12 (constants.%Self.3)]
-// CHECK:STDOUT:     %.loc188_45.2: type = converted %Self.ref.loc188_45, %.loc188_45.1 [symbolic = %Self.ref.loc188_12 (constants.%Self.3)]
-// CHECK:STDOUT:     %.loc188_52: type = array_type %.loc188_51, %Self.3 [symbolic = %.loc188_52 (constants.%.15)]
+// CHECK:STDOUT:     %.loc188_45.1: type = facet_type_access %Self.ref.loc188_45 [symbolic = @F.13.%Self (constants.%Self.3)]
+// CHECK:STDOUT:     %.loc188_45.2: type = converted %Self.ref.loc188_45, %.loc188_45.1 [symbolic = @F.13.%Self (constants.%Self.3)]
+// CHECK:STDOUT:     %.loc188_52: type = array_type %.loc188_51, %Self.3 [symbolic = @F.13.%.4 (constants.%.15)]
 // CHECK:STDOUT:     %return.var: ref %.15 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %.loc188_53: %.16 = assoc_entity element0, %F.decl [template = constants.%.17]
+// CHECK:STDOUT:   %.loc188_53: %.17 = assoc_entity element0, %F.decl [template = constants.%.18]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -670,22 +671,22 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT: impl @impl.14: %SelfNestedBadParam as %.9 {
 // CHECK:STDOUT:   %F.decl: %F.type.14 = fn_decl @F.14 [template = constants.%F.15] {
 // CHECK:STDOUT:     %SelfNestedBadParam.ref.loc200_14: type = name_ref SelfNestedBadParam, file.%SelfNestedBadParam.decl [template = constants.%SelfNestedBadParam]
-// CHECK:STDOUT:     %.loc200_32: type = ptr_type %SelfNestedBadParam [template = constants.%.18]
+// CHECK:STDOUT:     %.loc200_32: type = ptr_type %SelfNestedBadParam [template = constants.%.19]
 // CHECK:STDOUT:     %int.make_type_32.loc200_40: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:     %.loc200_40.1: type = value_of_initializer %int.make_type_32.loc200_40 [template = i32]
 // CHECK:STDOUT:     %.loc200_40.2: type = converted %int.make_type_32.loc200_40, %.loc200_40.1 [template = i32]
 // CHECK:STDOUT:     %int.make_type_32.loc200_49: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:     %.loc200_49.1: type = value_of_initializer %int.make_type_32.loc200_49 [template = i32]
 // CHECK:STDOUT:     %.loc200_49.2: type = converted %int.make_type_32.loc200_49, %.loc200_49.1 [template = i32]
-// CHECK:STDOUT:     %.loc200_52: type = struct_type {.x: i32, .y: i32} [template = constants.%.19]
+// CHECK:STDOUT:     %.loc200_52: type = struct_type {.x: i32, .y: i32} [template = constants.%.20]
 // CHECK:STDOUT:     %.loc200_53.1: %.12 = tuple_literal (%.loc200_32, %.loc200_52)
-// CHECK:STDOUT:     %.loc200_53.2: type = converted %.loc200_53.1, constants.%.20 [template = constants.%.20]
-// CHECK:STDOUT:     %x.loc200_10.1: %.20 = param x
-// CHECK:STDOUT:     %x.loc200_10.2: %.20 = bind_name x, %x.loc200_10.1
+// CHECK:STDOUT:     %.loc200_53.2: type = converted %.loc200_53.1, constants.%.21 [template = constants.%.21]
+// CHECK:STDOUT:     %x.loc200_10.1: %.21 = param x
+// CHECK:STDOUT:     %x.loc200_10.2: %.21 = bind_name x, %x.loc200_10.1
 // CHECK:STDOUT:     %SelfNestedBadParam.ref.loc200_60: type = name_ref SelfNestedBadParam, file.%SelfNestedBadParam.decl [template = constants.%SelfNestedBadParam]
 // CHECK:STDOUT:     %.loc200_80: i32 = int_literal 4 [template = constants.%.14]
-// CHECK:STDOUT:     %.loc200_81: type = array_type %.loc200_80, %SelfNestedBadParam [template = constants.%.21]
-// CHECK:STDOUT:     %return.var: ref %.21 = var <return slot>
+// CHECK:STDOUT:     %.loc200_81: type = array_type %.loc200_80, %SelfNestedBadParam [template = constants.%.22]
+// CHECK:STDOUT:     %return.var: ref %.22 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.1: <witness> = interface_witness (<error>) [template = <error>]
 // CHECK:STDOUT:
@@ -697,20 +698,20 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT: impl @impl.15: %SelfNestedBadReturnType as %.9 {
 // CHECK:STDOUT:   %F.decl: %F.type.15 = fn_decl @F.15 [template = constants.%F.16] {
 // CHECK:STDOUT:     %SelfNestedBadReturnType.ref.loc212_14: type = name_ref SelfNestedBadReturnType, file.%SelfNestedBadReturnType.decl [template = constants.%SelfNestedBadReturnType]
-// CHECK:STDOUT:     %.loc212_37: type = ptr_type %SelfNestedBadReturnType [template = constants.%.24]
+// CHECK:STDOUT:     %.loc212_37: type = ptr_type %SelfNestedBadReturnType [template = constants.%.25]
 // CHECK:STDOUT:     %SelfNestedBadReturnType.ref.loc212_45: type = name_ref SelfNestedBadReturnType, file.%SelfNestedBadReturnType.decl [template = constants.%SelfNestedBadReturnType]
 // CHECK:STDOUT:     %int.make_type_32: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:     %.loc212_74.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:     %.loc212_74.2: type = converted %int.make_type_32, %.loc212_74.1 [template = i32]
-// CHECK:STDOUT:     %.loc212_77: type = struct_type {.x: %SelfNestedBadReturnType, .y: i32} [template = constants.%.25]
+// CHECK:STDOUT:     %.loc212_77: type = struct_type {.x: %SelfNestedBadReturnType, .y: i32} [template = constants.%.26]
 // CHECK:STDOUT:     %.loc212_78.1: %.12 = tuple_literal (%.loc212_37, %.loc212_77)
-// CHECK:STDOUT:     %.loc212_78.2: type = converted %.loc212_78.1, constants.%.26 [template = constants.%.26]
-// CHECK:STDOUT:     %x.loc212_10.1: %.26 = param x
-// CHECK:STDOUT:     %x.loc212_10.2: %.26 = bind_name x, %x.loc212_10.1
+// CHECK:STDOUT:     %.loc212_78.2: type = converted %.loc212_78.1, constants.%.27 [template = constants.%.27]
+// CHECK:STDOUT:     %x.loc212_10.1: %.27 = param x
+// CHECK:STDOUT:     %x.loc212_10.2: %.27 = bind_name x, %x.loc212_10.1
 // CHECK:STDOUT:     %SelfNestedBadParam.ref: type = name_ref SelfNestedBadParam, file.%SelfNestedBadParam.decl [template = constants.%SelfNestedBadParam]
 // CHECK:STDOUT:     %.loc212_105: i32 = int_literal 4 [template = constants.%.14]
-// CHECK:STDOUT:     %.loc212_106: type = array_type %.loc212_105, %SelfNestedBadParam [template = constants.%.21]
-// CHECK:STDOUT:     %return.var: ref %.21 = var <return slot>
+// CHECK:STDOUT:     %.loc212_106: type = array_type %.loc212_105, %SelfNestedBadParam [template = constants.%.22]
+// CHECK:STDOUT:     %return.var: ref %.22 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.1: <witness> = interface_witness (<error>) [template = <error>]
 // CHECK:STDOUT:
@@ -856,8 +857,10 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT:   .Self = constants.%SelfNestedBadReturnType
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.1()
-// CHECK:STDOUT:     generic [@I.%Self: %.1];
+// CHECK:STDOUT: generic fn @F.1(@I.%Self: %.1) {
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn();
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @PossiblyF();
 // CHECK:STDOUT:
@@ -869,8 +872,10 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.4() -> bool;
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.5[@J.%self.loc93_20.2: bool](@J.%b.loc93_32.2: bool) -> bool
-// CHECK:STDOUT:     generic [@J.%Self: %.6];
+// CHECK:STDOUT: generic fn @F.5(@J.%Self: %.6) {
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn[@J.%self.loc93_20.2: bool](@J.%b.loc93_32.2: bool) -> bool;
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.6[@impl.7.%self.loc104_10.2: bool]() -> bool;
 // CHECK:STDOUT:
@@ -888,28 +893,29 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.13(@SelfNested.%x.loc188_8.2: @SelfNested.%.loc188_38.2 (%.13)) -> %.15
-// CHECK:STDOUT:     generic [@SelfNested.%Self: %.9];
+// CHECK:STDOUT: generic fn @F.13(@SelfNested.%Self: %.9) {
+// CHECK:STDOUT:   %Self: %.9 = bind_symbolic_name Self 0 [symbolic = %Self (constants.%Self.3)]
+// CHECK:STDOUT:   %.1: type = ptr_type @F.13.%Self (%Self.3) [symbolic = %.1 (constants.%.10)]
+// CHECK:STDOUT:   %.2: type = struct_type {.x: @F.13.%Self (%Self.3), .y: i32} [symbolic = %.2 (constants.%.11)]
+// CHECK:STDOUT:   %.3: type = tuple_type (@F.13.%.1 (%.10), @F.13.%.2 (%.11)) [symbolic = %.3 (constants.%.13)]
+// CHECK:STDOUT:   %.4: type = array_type constants.%.14, @F.13.%Self (%Self.3) [symbolic = %.4 (constants.%.15)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.14(@impl.14.%x.loc200_10.2: %.20) -> %.21;
+// CHECK:STDOUT:   fn(@SelfNested.%x.loc188_8.2: @F.13.%.3 (%.13)) -> %.15;
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.15(@impl.15.%x.loc212_10.2: %.26) -> %.21;
+// CHECK:STDOUT: fn @F.14(@impl.14.%x.loc200_10.2: %.21) -> %.22;
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @I.%F.decl(constants.%Self.1) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT: }
+// CHECK:STDOUT: fn @F.15(@impl.15.%x.loc212_10.2: %.27) -> %.22;
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @J.%F.decl(constants.%Self.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT: }
+// CHECK:STDOUT: specific @F.1(constants.%Self.1) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F.5(constants.%Self.2) {}
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @SelfNested.%F.decl(constants.%Self.3) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @SelfNested.%Self.ref.loc188_12 => constants.%Self.3
-// CHECK:STDOUT:   @SelfNested.%.loc188_16.3 => constants.%.10
-// CHECK:STDOUT:   <unexpected>.inst+267.loc188_21 => <unexpected>.inst+268
-// CHECK:STDOUT:   @SelfNested.%.loc188_37 => constants.%.11
-// CHECK:STDOUT:   @SelfNested.%.loc188_38.2 => constants.%.13
-// CHECK:STDOUT:   @SelfNested.%.loc188_52 => constants.%.15
+// CHECK:STDOUT: specific @F.13(constants.%Self.3) {
+// CHECK:STDOUT:   %Self => constants.%Self.3
+// CHECK:STDOUT:   %.1 => constants.%.10
+// CHECK:STDOUT:   %.2 => constants.%.11
+// CHECK:STDOUT:   %.3 => constants.%.16
+// CHECK:STDOUT:   %.4 => constants.%.15
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

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

@@ -89,8 +89,10 @@ class C {
 // CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.1()
-// CHECK:STDOUT:     generic [@Simple.%Self: %.1];
+// CHECK:STDOUT: generic fn @F.1(@Simple.%Self: %.1) {
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn();
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.2() {
 // CHECK:STDOUT: !entry:
@@ -104,7 +106,5 @@ class C {
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Simple.%F.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT: }
+// CHECK:STDOUT: specific @F.1(constants.%Self) {}
 // CHECK:STDOUT:

+ 12 - 11
toolchain/check/testdata/impl/impl_forall.carbon

@@ -76,20 +76,21 @@ impl forall [T:! type] T as Simple {
 // CHECK:STDOUT:   witness = %.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.1()
-// CHECK:STDOUT:     generic [@Simple.%Self: %.1];
+// CHECK:STDOUT: generic fn @F.1(@Simple.%Self: %.1) {
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.2()
-// CHECK:STDOUT:     generic [file.%T.loc15_14.2: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   return
+// CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Simple.%F.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT: }
+// CHECK:STDOUT: generic fn @F.2(file.%T.loc15_14.2: type) {
+// CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @impl.%F.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
+// CHECK:STDOUT:   fn() {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @F.1(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F.2(constants.%T) {}
+// CHECK:STDOUT:

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

@@ -105,8 +105,10 @@ fn G(c: C) {
 // CHECK:STDOUT:   .G = %G
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.1()
-// CHECK:STDOUT:     generic [@HasF.%Self: %.1];
+// CHECK:STDOUT: generic fn @F.1(@HasF.%Self: %.1) {
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn();
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.2() {
 // CHECK:STDOUT: !entry:
@@ -126,7 +128,5 @@ fn G(c: C) {
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @HasF.%F.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT: }
+// CHECK:STDOUT: specific @F.1(constants.%Self) {}
 // CHECK:STDOUT:

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

@@ -92,8 +92,10 @@ fn F(c: C) {
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.1()
-// CHECK:STDOUT:     generic [@I.%Self: %.1];
+// CHECK:STDOUT: generic fn @F.1(@I.%Self: %.1) {
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn();
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.2(%c: %C) {
 // CHECK:STDOUT: !entry:
@@ -104,7 +106,5 @@ fn F(c: C) {
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @I.%F.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT: }
+// CHECK:STDOUT: specific @F.1(constants.%Self) {}
 // CHECK:STDOUT:

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

@@ -115,8 +115,10 @@ impl C as I {
 // CHECK:STDOUT:   extend name_scope2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.1()
-// CHECK:STDOUT:     generic [@I.%Self: %.1];
+// CHECK:STDOUT: generic fn @F.1(@I.%Self: %.1) {
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn();
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
@@ -132,7 +134,5 @@ impl C as I {
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @I.%F.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT: }
+// CHECK:STDOUT: specific @F.1(constants.%Self) {}
 // CHECK:STDOUT:

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

@@ -96,17 +96,17 @@ fn G(c: Impl.C) {
 // CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.1()
-// CHECK:STDOUT:     generic [@HasF.%Self: %.1];
+// CHECK:STDOUT: generic fn @F.1(@HasF.%Self: %.1) {
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn();
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.2() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @HasF.%F.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT: }
+// CHECK:STDOUT: specific @F.1(constants.%Self) {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- use.carbon
 // CHECK:STDOUT:

+ 12 - 10
toolchain/check/testdata/impl/lookup/instance_method.carbon

@@ -86,11 +86,11 @@ fn F(c: C) -> i32 {
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %.1 = bind_symbolic_name Self 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type.1 = fn_decl @F.1 [template = constants.%F.1] {
-// CHECK:STDOUT:     %Self.ref: %.1 = name_ref Self, %Self [symbolic = %Self.ref (constants.%Self)]
-// CHECK:STDOUT:     %.loc14_14.1: type = facet_type_access %Self.ref [symbolic = %Self.ref (constants.%Self)]
-// CHECK:STDOUT:     %.loc14_14.2: type = converted %Self.ref, %.loc14_14.1 [symbolic = %Self.ref (constants.%Self)]
-// CHECK:STDOUT:     %self.loc14_8.1: @I.%Self.ref (%Self) = param self
-// CHECK:STDOUT:     %self.loc14_8.2: @I.%Self.ref (%Self) = bind_name self, %self.loc14_8.1
+// CHECK:STDOUT:     %Self.ref: %.1 = name_ref Self, %Self [symbolic = @F.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc14_14.1: type = facet_type_access %Self.ref [symbolic = @F.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc14_14.2: type = converted %Self.ref, %.loc14_14.1 [symbolic = @F.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %self.loc14_8.1: @F.1.%Self (%Self) = param self
+// CHECK:STDOUT:     %self.loc14_8.2: @F.1.%Self (%Self) = bind_name self, %self.loc14_8.1
 // CHECK:STDOUT:     %int.make_type_32: init type = call constants.%Int32() [template = i32]
 // CHECK:STDOUT:     %.loc14_25.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:     %.loc14_25.2: type = converted %int.make_type_32, %.loc14_25.1 [template = i32]
@@ -133,8 +133,11 @@ fn F(c: C) -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.1[@I.%self.loc14_8.2: @I.%Self.ref (%Self)]() -> i32
-// CHECK:STDOUT:     generic [@I.%Self: %.1];
+// CHECK:STDOUT: generic fn @F.1(@I.%Self: %.1) {
+// CHECK:STDOUT:   %Self: %.1 = bind_symbolic_name Self 0 [symbolic = %Self (constants.%Self)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn[@I.%self.loc14_8.2: @F.1.%Self (%Self)]() -> i32;
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.2[@impl.%self.loc19_10.2: %C]() -> i32;
 // CHECK:STDOUT:
@@ -150,8 +153,7 @@ fn F(c: C) -> i32 {
 // CHECK:STDOUT:   return %.loc24_15.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @I.%F.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @I.%Self.ref => constants.%Self
+// CHECK:STDOUT: specific @F.1(constants.%Self) {
+// CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

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

@@ -85,17 +85,17 @@ fn G(c: Impl.C) {
 // CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.1()
-// CHECK:STDOUT:     generic [@HasF.%Self: %.1];
+// CHECK:STDOUT: generic fn @F.1(@HasF.%Self: %.1) {
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn();
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.2() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @HasF.%F.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT: }
+// CHECK:STDOUT: specific @F.1(constants.%Self) {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- use.carbon
 // CHECK:STDOUT:

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

@@ -73,15 +73,15 @@ impl C as Simple {
 // CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.1()
-// CHECK:STDOUT:     generic [@Simple.%Self: %.1];
+// CHECK:STDOUT: generic fn @F.1(@Simple.%Self: %.1) {
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn();
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.2() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Simple.%F.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT: }
+// CHECK:STDOUT: specific @F.1(constants.%Self) {}
 // CHECK:STDOUT:

+ 21 - 19
toolchain/check/testdata/impl/no_prelude/import_self.carbon

@@ -52,19 +52,19 @@ fn F(x: (), y: ()) -> () {
 // CHECK:STDOUT: interface @Add {
 // CHECK:STDOUT:   %Self: %.1 = bind_symbolic_name Self 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %Op.decl: %Op.type = fn_decl @Op [template = constants.%Op] {
-// CHECK:STDOUT:     %Self.ref.loc5_15: %.1 = name_ref Self, %Self [symbolic = %Self.ref.loc5_15 (constants.%Self)]
-// CHECK:STDOUT:     %.loc5_15.1: type = facet_type_access %Self.ref.loc5_15 [symbolic = %Self.ref.loc5_15 (constants.%Self)]
-// CHECK:STDOUT:     %.loc5_15.2: type = converted %Self.ref.loc5_15, %.loc5_15.1 [symbolic = %Self.ref.loc5_15 (constants.%Self)]
-// CHECK:STDOUT:     %self.loc5_9.1: @Add.%Self.ref.loc5_15 (%Self) = param self
-// CHECK:STDOUT:     %self.loc5_9.2: @Add.%Self.ref.loc5_15 (%Self) = bind_name self, %self.loc5_9.1
-// CHECK:STDOUT:     %Self.ref.loc5_28: %.1 = name_ref Self, %Self [symbolic = %Self.ref.loc5_15 (constants.%Self)]
-// CHECK:STDOUT:     %.loc5_28.1: type = facet_type_access %Self.ref.loc5_28 [symbolic = %Self.ref.loc5_15 (constants.%Self)]
-// CHECK:STDOUT:     %.loc5_28.2: type = converted %Self.ref.loc5_28, %.loc5_28.1 [symbolic = %Self.ref.loc5_15 (constants.%Self)]
-// CHECK:STDOUT:     %other.loc5_21.1: @Add.%Self.ref.loc5_15 (%Self) = param other
-// CHECK:STDOUT:     %other.loc5_21.2: @Add.%Self.ref.loc5_15 (%Self) = bind_name other, %other.loc5_21.1
-// CHECK:STDOUT:     %Self.ref.loc5_37: %.1 = name_ref Self, %Self [symbolic = %Self.ref.loc5_15 (constants.%Self)]
-// CHECK:STDOUT:     %.loc5_37.1: type = facet_type_access %Self.ref.loc5_37 [symbolic = %Self.ref.loc5_15 (constants.%Self)]
-// CHECK:STDOUT:     %.loc5_37.2: type = converted %Self.ref.loc5_37, %.loc5_37.1 [symbolic = %Self.ref.loc5_15 (constants.%Self)]
+// CHECK:STDOUT:     %Self.ref.loc5_15: %.1 = name_ref Self, %Self [symbolic = @Op.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc5_15.1: type = facet_type_access %Self.ref.loc5_15 [symbolic = @Op.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc5_15.2: type = converted %Self.ref.loc5_15, %.loc5_15.1 [symbolic = @Op.%Self (constants.%Self)]
+// CHECK:STDOUT:     %self.loc5_9.1: @Op.%Self (%Self) = param self
+// CHECK:STDOUT:     %self.loc5_9.2: @Op.%Self (%Self) = bind_name self, %self.loc5_9.1
+// CHECK:STDOUT:     %Self.ref.loc5_28: %.1 = name_ref Self, %Self [symbolic = @Op.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc5_28.1: type = facet_type_access %Self.ref.loc5_28 [symbolic = @Op.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc5_28.2: type = converted %Self.ref.loc5_28, %.loc5_28.1 [symbolic = @Op.%Self (constants.%Self)]
+// CHECK:STDOUT:     %other.loc5_21.1: @Op.%Self (%Self) = param other
+// CHECK:STDOUT:     %other.loc5_21.2: @Op.%Self (%Self) = bind_name other, %other.loc5_21.1
+// CHECK:STDOUT:     %Self.ref.loc5_37: %.1 = name_ref Self, %Self [symbolic = @Op.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc5_37.1: type = facet_type_access %Self.ref.loc5_37 [symbolic = @Op.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc5_37.2: type = converted %Self.ref.loc5_37, %.loc5_37.1 [symbolic = @Op.%Self (constants.%Self)]
 // CHECK:STDOUT:     %return.var: ref %Self = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.loc5_41: %.3 = assoc_entity element0, %Op.decl [template = constants.%.4]
@@ -75,12 +75,14 @@ fn F(x: (), y: ()) -> () {
 // CHECK:STDOUT:   witness = (%Op.decl)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @Op[@Add.%self.loc5_9.2: @Add.%Self.ref.loc5_15 (%Self)](@Add.%other.loc5_21.2: @Add.%Self.ref.loc5_15 (%Self)) -> %Self
-// CHECK:STDOUT:     generic [@Add.%Self: %.1];
+// CHECK:STDOUT: generic fn @Op(@Add.%Self: %.1) {
+// CHECK:STDOUT:   %Self: %.1 = bind_symbolic_name Self 0 [symbolic = %Self (constants.%Self)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Add.%Op.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @Add.%Self.ref.loc5_15 => constants.%Self
+// CHECK:STDOUT:   fn[@Add.%self.loc5_9.2: @Op.%Self (%Self)](@Add.%other.loc5_21.2: @Op.%Self (%Self)) -> %Self;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Op(constants.%Self) {
+// CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- b.carbon
@@ -104,7 +106,7 @@ fn F(x: (), y: ()) -> () {
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %import_ref.1: type = import_ref Main//a, inst+1, loaded [template = constants.%.2]
 // CHECK:STDOUT:   %import_ref.2 = import_ref Main//a, inst+3, unloaded
-// CHECK:STDOUT:   %import_ref.3: %.4 = import_ref Main//a, inst+24, loaded [template = constants.%.5]
+// CHECK:STDOUT:   %import_ref.3: %.4 = import_ref Main//a, inst+25, loaded [template = constants.%.5]
 // CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Main//a, inst+19, loaded [template = constants.%Op.2]
 // CHECK:STDOUT:   %import_ref.5 = import_ref Main//a, inst+19, unloaded
 // CHECK:STDOUT: }

+ 10 - 8
toolchain/check/testdata/impl/no_prelude/self_in_class.carbon

@@ -56,9 +56,9 @@ class A {
 // CHECK:STDOUT: interface @DefaultConstructible {
 // CHECK:STDOUT:   %Self: %.1 = bind_symbolic_name Self 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %Make.decl: %Make.type.1 = fn_decl @Make.1 [template = constants.%Make.1] {
-// CHECK:STDOUT:     %Self.ref: %.1 = name_ref Self, %Self [symbolic = %Self.ref (constants.%Self)]
-// CHECK:STDOUT:     %.loc12_16.1: type = facet_type_access %Self.ref [symbolic = %Self.ref (constants.%Self)]
-// CHECK:STDOUT:     %.loc12_16.2: type = converted %Self.ref, %.loc12_16.1 [symbolic = %Self.ref (constants.%Self)]
+// CHECK:STDOUT:     %Self.ref: %.1 = name_ref Self, %Self [symbolic = @Make.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc12_16.1: type = facet_type_access %Self.ref [symbolic = @Make.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc12_16.2: type = converted %Self.ref, %.loc12_16.1 [symbolic = @Make.1.%Self (constants.%Self)]
 // CHECK:STDOUT:     %return.var: ref %Self = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.loc12_20: %.3 = assoc_entity element0, %Make.decl [template = constants.%.4]
@@ -96,8 +96,11 @@ class A {
 // CHECK:STDOUT:   .Self = constants.%A
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @Make.1() -> %Self
-// CHECK:STDOUT:     generic [@DefaultConstructible.%Self: %.1];
+// CHECK:STDOUT: generic fn @Make.1(@DefaultConstructible.%Self: %.1) {
+// CHECK:STDOUT:   %Self: %.1 = bind_symbolic_name Self 0 [symbolic = %Self (constants.%Self)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn() -> %Self;
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Make.2() -> @impl.%return.var: %C {
 // CHECK:STDOUT: !entry:
@@ -107,8 +110,7 @@ class A {
 // CHECK:STDOUT:   return %.loc21_34 to @impl.%return.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @DefaultConstructible.%Make.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @DefaultConstructible.%Self.ref => constants.%Self
+// CHECK:STDOUT: specific @Make.1(constants.%Self) {
+// CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 70 - 63
toolchain/check/testdata/impl/no_prelude/self_in_signature.carbon

@@ -64,22 +64,23 @@ impl D as SelfNested {
 // CHECK:STDOUT:   %.11: type = struct_type {.x: %Self.2, .y: %.2} [symbolic]
 // CHECK:STDOUT:   %.12: type = tuple_type (type, type) [template]
 // CHECK:STDOUT:   %.13: type = tuple_type (%.10, %.11) [symbolic]
+// CHECK:STDOUT:   %.14: type = tuple_type (@F.4.%.1 (%.10), @F.4.%.2 (%.11)) [symbolic]
 // CHECK:STDOUT:   %F.type.4: type = fn_type @F.4 [template]
 // CHECK:STDOUT:   %F.4: %F.type.4 = struct_value () [template]
-// CHECK:STDOUT:   %.14: type = assoc_entity_type @SelfNested, %F.type.4 [template]
-// CHECK:STDOUT:   %.15: %.14 = assoc_entity element0, @SelfNested.%F.decl [template]
-// CHECK:STDOUT:   %.16: type = ptr_type %C [template]
-// CHECK:STDOUT:   %.17: type = struct_type {.x: %C, .y: %.2} [template]
-// CHECK:STDOUT:   %.18: type = tuple_type (%.16, %.17) [template]
+// CHECK:STDOUT:   %.15: type = assoc_entity_type @SelfNested, %F.type.4 [template]
+// CHECK:STDOUT:   %.16: %.15 = assoc_entity element0, @SelfNested.%F.decl [template]
+// CHECK:STDOUT:   %.17: type = ptr_type %C [template]
+// CHECK:STDOUT:   %.18: type = struct_type {.x: %C, .y: %.2} [template]
+// CHECK:STDOUT:   %.19: type = tuple_type (%.17, %.18) [template]
 // CHECK:STDOUT:   %F.type.5: type = fn_type @F.5 [template]
 // CHECK:STDOUT:   %F.5: %F.type.5 = struct_value () [template]
-// CHECK:STDOUT:   %.19: <witness> = interface_witness (%F.5) [template]
-// CHECK:STDOUT:   %.20: type = ptr_type %D [template]
-// CHECK:STDOUT:   %.21: type = struct_type {.x: %D, .y: %.2} [template]
-// CHECK:STDOUT:   %.22: type = tuple_type (%.20, %.21) [template]
+// CHECK:STDOUT:   %.20: <witness> = interface_witness (%F.5) [template]
+// CHECK:STDOUT:   %.21: type = ptr_type %D [template]
+// CHECK:STDOUT:   %.22: type = struct_type {.x: %D, .y: %.2} [template]
+// CHECK:STDOUT:   %.23: type = tuple_type (%.21, %.22) [template]
 // CHECK:STDOUT:   %F.type.6: type = fn_type @F.6 [template]
 // CHECK:STDOUT:   %F.6: %F.type.6 = struct_value () [template]
-// CHECK:STDOUT:   %.23: <witness> = interface_witness (%F.6) [template]
+// CHECK:STDOUT:   %.24: <witness> = interface_witness (%F.6) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -114,19 +115,19 @@ impl D as SelfNested {
 // CHECK:STDOUT: interface @UseSelf {
 // CHECK:STDOUT:   %Self: %.1 = bind_symbolic_name Self 0 [symbolic = constants.%Self.1]
 // CHECK:STDOUT:   %F.decl: %F.type.1 = fn_decl @F.1 [template = constants.%F.1] {
-// CHECK:STDOUT:     %Self.ref.loc12_14: %.1 = name_ref Self, %Self [symbolic = %Self.ref.loc12_14 (constants.%Self.1)]
-// CHECK:STDOUT:     %.loc12_14.1: type = facet_type_access %Self.ref.loc12_14 [symbolic = %Self.ref.loc12_14 (constants.%Self.1)]
-// CHECK:STDOUT:     %.loc12_14.2: type = converted %Self.ref.loc12_14, %.loc12_14.1 [symbolic = %Self.ref.loc12_14 (constants.%Self.1)]
-// CHECK:STDOUT:     %self.loc12_8.1: @UseSelf.%Self.ref.loc12_14 (%Self.1) = param self
-// CHECK:STDOUT:     %self.loc12_8.2: @UseSelf.%Self.ref.loc12_14 (%Self.1) = bind_name self, %self.loc12_8.1
-// CHECK:STDOUT:     %Self.ref.loc12_23: %.1 = name_ref Self, %Self [symbolic = %Self.ref.loc12_14 (constants.%Self.1)]
-// CHECK:STDOUT:     %.loc12_23.1: type = facet_type_access %Self.ref.loc12_23 [symbolic = %Self.ref.loc12_14 (constants.%Self.1)]
-// CHECK:STDOUT:     %.loc12_23.2: type = converted %Self.ref.loc12_23, %.loc12_23.1 [symbolic = %Self.ref.loc12_14 (constants.%Self.1)]
-// CHECK:STDOUT:     %x.loc12_20.1: @UseSelf.%Self.ref.loc12_14 (%Self.1) = param x
-// CHECK:STDOUT:     %x.loc12_20.2: @UseSelf.%Self.ref.loc12_14 (%Self.1) = bind_name x, %x.loc12_20.1
-// CHECK:STDOUT:     %Self.ref.loc12_32: %.1 = name_ref Self, %Self [symbolic = %Self.ref.loc12_14 (constants.%Self.1)]
-// CHECK:STDOUT:     %.loc12_32.1: type = facet_type_access %Self.ref.loc12_32 [symbolic = %Self.ref.loc12_14 (constants.%Self.1)]
-// CHECK:STDOUT:     %.loc12_32.2: type = converted %Self.ref.loc12_32, %.loc12_32.1 [symbolic = %Self.ref.loc12_14 (constants.%Self.1)]
+// CHECK:STDOUT:     %Self.ref.loc12_14: %.1 = name_ref Self, %Self [symbolic = @F.1.%Self (constants.%Self.1)]
+// CHECK:STDOUT:     %.loc12_14.1: type = facet_type_access %Self.ref.loc12_14 [symbolic = @F.1.%Self (constants.%Self.1)]
+// CHECK:STDOUT:     %.loc12_14.2: type = converted %Self.ref.loc12_14, %.loc12_14.1 [symbolic = @F.1.%Self (constants.%Self.1)]
+// CHECK:STDOUT:     %self.loc12_8.1: @F.1.%Self (%Self.1) = param self
+// CHECK:STDOUT:     %self.loc12_8.2: @F.1.%Self (%Self.1) = bind_name self, %self.loc12_8.1
+// CHECK:STDOUT:     %Self.ref.loc12_23: %.1 = name_ref Self, %Self [symbolic = @F.1.%Self (constants.%Self.1)]
+// CHECK:STDOUT:     %.loc12_23.1: type = facet_type_access %Self.ref.loc12_23 [symbolic = @F.1.%Self (constants.%Self.1)]
+// CHECK:STDOUT:     %.loc12_23.2: type = converted %Self.ref.loc12_23, %.loc12_23.1 [symbolic = @F.1.%Self (constants.%Self.1)]
+// CHECK:STDOUT:     %x.loc12_20.1: @F.1.%Self (%Self.1) = param x
+// CHECK:STDOUT:     %x.loc12_20.2: @F.1.%Self (%Self.1) = bind_name x, %x.loc12_20.1
+// CHECK:STDOUT:     %Self.ref.loc12_32: %.1 = name_ref Self, %Self [symbolic = @F.1.%Self (constants.%Self.1)]
+// CHECK:STDOUT:     %.loc12_32.1: type = facet_type_access %Self.ref.loc12_32 [symbolic = @F.1.%Self (constants.%Self.1)]
+// CHECK:STDOUT:     %.loc12_32.2: type = converted %Self.ref.loc12_32, %.loc12_32.1 [symbolic = @F.1.%Self (constants.%Self.1)]
 // CHECK:STDOUT:     %return.var: ref %Self.1 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.loc12_36: %.3 = assoc_entity element0, %F.decl [template = constants.%.4]
@@ -140,22 +141,22 @@ impl D as SelfNested {
 // CHECK:STDOUT: interface @SelfNested {
 // CHECK:STDOUT:   %Self: %.9 = bind_symbolic_name Self 0 [symbolic = constants.%Self.2]
 // CHECK:STDOUT:   %F.decl: %F.type.4 = fn_decl @F.4 [template = constants.%F.4] {
-// CHECK:STDOUT:     %Self.ref.loc28_12: %.9 = name_ref Self, %Self [symbolic = %Self.ref.loc28_12 (constants.%Self.2)]
-// CHECK:STDOUT:     %.loc28_16.1: type = facet_type_access %Self.ref.loc28_12 [symbolic = %Self.ref.loc28_12 (constants.%Self.2)]
-// CHECK:STDOUT:     %.loc28_16.2: type = converted %Self.ref.loc28_12, %.loc28_16.1 [symbolic = %Self.ref.loc28_12 (constants.%Self.2)]
-// CHECK:STDOUT:     %.loc28_16.3: type = ptr_type %Self.2 [symbolic = %.loc28_16.3 (constants.%.10)]
-// CHECK:STDOUT:     %Self.ref.loc28_24: %.9 = name_ref Self, %Self [symbolic = %Self.ref.loc28_12 (constants.%Self.2)]
-// CHECK:STDOUT:     %.loc28_24.1: type = facet_type_access %Self.ref.loc28_24 [symbolic = %Self.ref.loc28_12 (constants.%Self.2)]
-// CHECK:STDOUT:     %.loc28_24.2: type = converted %Self.ref.loc28_24, %.loc28_24.1 [symbolic = %Self.ref.loc28_12 (constants.%Self.2)]
+// CHECK:STDOUT:     %Self.ref.loc28_12: %.9 = name_ref Self, %Self [symbolic = @F.4.%Self (constants.%Self.2)]
+// CHECK:STDOUT:     %.loc28_16.1: type = facet_type_access %Self.ref.loc28_12 [symbolic = @F.4.%Self (constants.%Self.2)]
+// CHECK:STDOUT:     %.loc28_16.2: type = converted %Self.ref.loc28_12, %.loc28_16.1 [symbolic = @F.4.%Self (constants.%Self.2)]
+// CHECK:STDOUT:     %.loc28_16.3: type = ptr_type %Self.2 [symbolic = @F.4.%.1 (constants.%.10)]
+// CHECK:STDOUT:     %Self.ref.loc28_24: %.9 = name_ref Self, %Self [symbolic = @F.4.%Self (constants.%Self.2)]
+// CHECK:STDOUT:     %.loc28_24.1: type = facet_type_access %Self.ref.loc28_24 [symbolic = @F.4.%Self (constants.%Self.2)]
+// CHECK:STDOUT:     %.loc28_24.2: type = converted %Self.ref.loc28_24, %.loc28_24.1 [symbolic = @F.4.%Self (constants.%Self.2)]
 // CHECK:STDOUT:     %.loc28_35.1: %.2 = tuple_literal ()
 // CHECK:STDOUT:     %.loc28_35.2: type = converted %.loc28_35.1, constants.%.2 [template = constants.%.2]
-// CHECK:STDOUT:     %.loc28_36: type = struct_type {.x: %Self.2, .y: %.2} [symbolic = %.loc28_36 (constants.%.11)]
+// CHECK:STDOUT:     %.loc28_36: type = struct_type {.x: %Self.2, .y: %.2} [symbolic = @F.4.%.2 (constants.%.11)]
 // CHECK:STDOUT:     %.loc28_37.1: %.12 = tuple_literal (%.loc28_16.3, %.loc28_36)
-// CHECK:STDOUT:     %.loc28_37.2: type = converted %.loc28_37.1, constants.%.13 [symbolic = %.loc28_37.2 (constants.%.13)]
-// CHECK:STDOUT:     %x.loc28_8.1: @SelfNested.%.loc28_37.2 (%.13) = param x
-// CHECK:STDOUT:     %x.loc28_8.2: @SelfNested.%.loc28_37.2 (%.13) = bind_name x, %x.loc28_8.1
+// CHECK:STDOUT:     %.loc28_37.2: type = converted %.loc28_37.1, constants.%.13 [symbolic = @F.4.%.3 (constants.%.13)]
+// CHECK:STDOUT:     %x.loc28_8.1: @F.4.%.3 (%.13) = param x
+// CHECK:STDOUT:     %x.loc28_8.2: @F.4.%.3 (%.13) = bind_name x, %x.loc28_8.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %.loc28_39: %.14 = assoc_entity element0, %F.decl [template = constants.%.15]
+// CHECK:STDOUT:   %.loc28_39: %.15 = assoc_entity element0, %F.decl [template = constants.%.16]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -202,17 +203,17 @@ impl D as SelfNested {
 // CHECK:STDOUT: impl @impl.3: %C as %.9 {
 // CHECK:STDOUT:   %F.decl: %F.type.5 = fn_decl @F.5 [template = constants.%F.5] {
 // CHECK:STDOUT:     %C.ref.loc32_12: type = name_ref C, file.%C.decl [template = constants.%C]
-// CHECK:STDOUT:     %.loc32_13: type = ptr_type %C [template = constants.%.16]
+// CHECK:STDOUT:     %.loc32_13: type = ptr_type %C [template = constants.%.17]
 // CHECK:STDOUT:     %C.ref.loc32_21: type = name_ref C, file.%C.decl [template = constants.%C]
 // CHECK:STDOUT:     %.loc32_29.1: %.2 = tuple_literal ()
 // CHECK:STDOUT:     %.loc32_29.2: type = converted %.loc32_29.1, constants.%.2 [template = constants.%.2]
-// CHECK:STDOUT:     %.loc32_30: type = struct_type {.x: %C, .y: %.2} [template = constants.%.17]
+// CHECK:STDOUT:     %.loc32_30: type = struct_type {.x: %C, .y: %.2} [template = constants.%.18]
 // CHECK:STDOUT:     %.loc32_31.1: %.12 = tuple_literal (%.loc32_13, %.loc32_30)
-// CHECK:STDOUT:     %.loc32_31.2: type = converted %.loc32_31.1, constants.%.18 [template = constants.%.18]
-// CHECK:STDOUT:     %x.loc32_8.1: %.18 = param x
-// CHECK:STDOUT:     %x.loc32_8.2: %.18 = bind_name x, %x.loc32_8.1
+// CHECK:STDOUT:     %.loc32_31.2: type = converted %.loc32_31.1, constants.%.19 [template = constants.%.19]
+// CHECK:STDOUT:     %x.loc32_8.1: %.19 = param x
+// CHECK:STDOUT:     %x.loc32_8.2: %.19 = bind_name x, %x.loc32_8.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %.1: <witness> = interface_witness (%F.decl) [template = constants.%.19]
+// CHECK:STDOUT:   %.1: <witness> = interface_witness (%F.decl) [template = constants.%.20]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F.decl
@@ -222,17 +223,17 @@ impl D as SelfNested {
 // CHECK:STDOUT: impl @impl.4: %D as %.9 {
 // CHECK:STDOUT:   %F.decl: %F.type.6 = fn_decl @F.6 [template = constants.%F.6] {
 // CHECK:STDOUT:     %Self.ref.loc36_12: type = name_ref Self, constants.%D [template = constants.%D]
-// CHECK:STDOUT:     %.loc36_16: type = ptr_type %D [template = constants.%.20]
+// CHECK:STDOUT:     %.loc36_16: type = ptr_type %D [template = constants.%.21]
 // CHECK:STDOUT:     %Self.ref.loc36_24: type = name_ref Self, constants.%D [template = constants.%D]
 // CHECK:STDOUT:     %.loc36_35.1: %.2 = tuple_literal ()
 // CHECK:STDOUT:     %.loc36_35.2: type = converted %.loc36_35.1, constants.%.2 [template = constants.%.2]
-// CHECK:STDOUT:     %.loc36_36: type = struct_type {.x: %D, .y: %.2} [template = constants.%.21]
+// CHECK:STDOUT:     %.loc36_36: type = struct_type {.x: %D, .y: %.2} [template = constants.%.22]
 // CHECK:STDOUT:     %.loc36_37.1: %.12 = tuple_literal (%.loc36_16, %.loc36_36)
-// CHECK:STDOUT:     %.loc36_37.2: type = converted %.loc36_37.1, constants.%.22 [template = constants.%.22]
-// CHECK:STDOUT:     %x.loc36_8.1: %.22 = param x
-// CHECK:STDOUT:     %x.loc36_8.2: %.22 = bind_name x, %x.loc36_8.1
+// CHECK:STDOUT:     %.loc36_37.2: type = converted %.loc36_37.1, constants.%.23 [template = constants.%.23]
+// CHECK:STDOUT:     %x.loc36_8.1: %.23 = param x
+// CHECK:STDOUT:     %x.loc36_8.2: %.23 = bind_name x, %x.loc36_8.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %.1: <witness> = interface_witness (%F.decl) [template = constants.%.23]
+// CHECK:STDOUT:   %.1: <witness> = interface_witness (%F.decl) [template = constants.%.24]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F.decl
@@ -249,8 +250,11 @@ impl D as SelfNested {
 // CHECK:STDOUT:   .Self = constants.%D
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.1[@UseSelf.%self.loc12_8.2: @UseSelf.%Self.ref.loc12_14 (%Self.1)](@UseSelf.%x.loc12_20.2: @UseSelf.%Self.ref.loc12_14 (%Self.1)) -> %Self.1
-// CHECK:STDOUT:     generic [@UseSelf.%Self: %.1];
+// CHECK:STDOUT: generic fn @F.1(@UseSelf.%Self: %.1) {
+// CHECK:STDOUT:   %Self: %.1 = bind_symbolic_name Self 0 [symbolic = %Self (constants.%Self.1)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn[@UseSelf.%self.loc12_8.2: @F.1.%Self (%Self.1)](@UseSelf.%x.loc12_20.2: @F.1.%Self (%Self.1)) -> %Self.1;
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.2[@impl.1.%self.loc20_8.2: %C](@impl.1.%x.loc20_17.2: %C) -> @impl.1.%return.var: %C {
 // CHECK:STDOUT: !entry:
@@ -268,24 +272,27 @@ impl D as SelfNested {
 // CHECK:STDOUT:   return %.loc24_48 to @impl.2.%return.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.4(@SelfNested.%x.loc28_8.2: @SelfNested.%.loc28_37.2 (%.13))
-// CHECK:STDOUT:     generic [@SelfNested.%Self: %.9];
+// CHECK:STDOUT: generic fn @F.4(@SelfNested.%Self: %.9) {
+// CHECK:STDOUT:   %Self: %.9 = bind_symbolic_name Self 0 [symbolic = %Self (constants.%Self.2)]
+// CHECK:STDOUT:   %.1: type = ptr_type @F.4.%Self (%Self.2) [symbolic = %.1 (constants.%.10)]
+// CHECK:STDOUT:   %.2: type = struct_type {.x: @F.4.%Self (%Self.2), .y: %.2} [symbolic = %.2 (constants.%.11)]
+// CHECK:STDOUT:   %.3: type = tuple_type (@F.4.%.1 (%.10), @F.4.%.2 (%.11)) [symbolic = %.3 (constants.%.13)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(@SelfNested.%x.loc28_8.2: @F.4.%.3 (%.13));
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.5(@impl.3.%x.loc32_8.2: %.18);
+// CHECK:STDOUT: fn @F.5(@impl.3.%x.loc32_8.2: %.19);
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.6(@impl.4.%x.loc36_8.2: %.22);
+// CHECK:STDOUT: fn @F.6(@impl.4.%x.loc36_8.2: %.23);
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @UseSelf.%F.decl(constants.%Self.1) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @UseSelf.%Self.ref.loc12_14 => constants.%Self.1
+// CHECK:STDOUT: specific @F.1(constants.%Self.1) {
+// CHECK:STDOUT:   %Self => constants.%Self.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @SelfNested.%F.decl(constants.%Self.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @SelfNested.%Self.ref.loc28_12 => constants.%Self.2
-// CHECK:STDOUT:   @SelfNested.%.loc28_16.3 => constants.%.10
-// CHECK:STDOUT:   <unexpected>.inst+86.loc28_21 => <unexpected>.inst+87
-// CHECK:STDOUT:   @SelfNested.%.loc28_36 => constants.%.11
-// CHECK:STDOUT:   @SelfNested.%.loc28_37.2 => constants.%.13
+// CHECK:STDOUT: specific @F.4(constants.%Self.2) {
+// CHECK:STDOUT:   %Self => constants.%Self.2
+// CHECK:STDOUT:   %.1 => constants.%.10
+// CHECK:STDOUT:   %.2 => constants.%.11
+// CHECK:STDOUT:   %.3 => constants.%.14
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

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

@@ -39,11 +39,11 @@ var b: i32 = a[-10];
 // CHECK:STDOUT:   %import_ref.1: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
 // CHECK:STDOUT:   %import_ref.2: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
 // CHECK:STDOUT:   %import_ref.3: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
-// CHECK:STDOUT:   %import_ref.4: type = import_ref Core//prelude/operators/arithmetic, inst+67, loaded [template = constants.%.8]
-// CHECK:STDOUT:   %import_ref.5 = import_ref Core//prelude/operators/arithmetic, inst+69, unloaded
-// CHECK:STDOUT:   %import_ref.6: %.9 = import_ref Core//prelude/operators/arithmetic, inst+84, loaded [template = constants.%.10]
-// CHECK:STDOUT:   %import_ref.7 = import_ref Core//prelude/operators/arithmetic, inst+80, unloaded
-// CHECK:STDOUT:   %import_ref.8 = import_ref Core//prelude/operators/arithmetic, inst+80, unloaded
+// CHECK:STDOUT:   %import_ref.4: type = import_ref Core//prelude/operators/arithmetic, inst+72, loaded [template = constants.%.8]
+// CHECK:STDOUT:   %import_ref.5 = import_ref Core//prelude/operators/arithmetic, inst+74, unloaded
+// CHECK:STDOUT:   %import_ref.6: %.9 = import_ref Core//prelude/operators/arithmetic, inst+90, loaded [template = constants.%.10]
+// CHECK:STDOUT:   %import_ref.7 = import_ref Core//prelude/operators/arithmetic, inst+85, unloaded
+// CHECK:STDOUT:   %import_ref.8 = import_ref Core//prelude/operators/arithmetic, inst+85, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {

+ 12 - 11
toolchain/check/testdata/interface/fail_todo_define_default_fn_inline.carbon

@@ -92,22 +92,23 @@ interface Interface {
 // CHECK:STDOUT:   witness = (%F.decl, %G.decl)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F()
-// CHECK:STDOUT:     generic [@Interface.%Self: %.1] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   return
+// CHECK:STDOUT: generic fn @F(@Interface.%Self: %.1) {
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn() {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @G(@Interface.%a.loc21_16.2: i32, @Interface.%b.loc21_24.2: i32) -> i32 = "int.sadd"
-// CHECK:STDOUT:     generic [@Interface.%Self: %.1];
+// CHECK:STDOUT: generic fn @G(@Interface.%Self: %.1) {
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Interface.%F.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
+// CHECK:STDOUT:   fn(@Interface.%a.loc21_16.2: i32, @Interface.%b.loc21_24.2: i32) -> i32 = "int.sadd";
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Interface.%G.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT: }
+// CHECK:STDOUT: specific @F(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @G(constants.%Self) {}
 // CHECK:STDOUT:

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

@@ -134,13 +134,17 @@ fn Interface.G(a: i32, b: i32) -> i32 = "int.sadd";
 // CHECK:STDOUT:   witness = (%F.decl, %G.decl)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F()
-// CHECK:STDOUT:     generic [@Interface.%Self: %.1];
+// CHECK:STDOUT: generic fn @F(@Interface.%Self: %.1) {
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn();
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @G(@Interface.%a.loc22_16.2: i32, @Interface.%b.loc22_24.2: i32) -> i32
-// CHECK:STDOUT:     generic [@Interface.%Self: %.1];
+// CHECK:STDOUT: generic fn @G(@Interface.%Self: %.1) {
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(@Interface.%a.loc22_16.2: i32, @Interface.%b.loc22_24.2: i32) -> i32;
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @.1() {
 // CHECK:STDOUT: !entry:
@@ -149,11 +153,7 @@ fn Interface.G(a: i32, b: i32) -> i32 = "int.sadd";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @.2(%a: i32, %b: i32) -> i32 = "int.sadd";
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Interface.%F.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT: }
+// CHECK:STDOUT: specific @F(constants.%Self) {}
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Interface.%G.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT: }
+// CHECK:STDOUT: specific @G(constants.%Self) {}
 // CHECK:STDOUT:

+ 17 - 13
toolchain/check/testdata/interface/no_prelude/as_type_of_type.carbon

@@ -34,7 +34,7 @@ fn F(T:! Empty) {
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
 // CHECK:STDOUT:     %Empty.ref: type = name_ref Empty, %Empty.decl [template = constants.%.1]
 // CHECK:STDOUT:     %T.loc13_6.1: %.1 = param T
-// CHECK:STDOUT:     @F.%T: %.1 = bind_symbolic_name T 0, %T.loc13_6.1 [symbolic = @F.%T (constants.%T)]
+// CHECK:STDOUT:     @F.%T.loc13: %.1 = bind_symbolic_name T 0, %T.loc13_6.1 [symbolic = @F.%T.1 (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -46,19 +46,23 @@ fn F(T:! Empty) {
 // CHECK:STDOUT:   witness = ()
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F(%T: %.1)
-// CHECK:STDOUT:     generic [%T: %.1] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %T.ref: %.1 = name_ref T, %T [symbolic = %T (constants.%T)]
-// CHECK:STDOUT:   %.loc14_10.1: type = facet_type_access %T.ref [symbolic = %T (constants.%T)]
-// CHECK:STDOUT:   %.loc14_10.2: type = converted %T.ref, %.loc14_10.1 [symbolic = %T (constants.%T)]
-// CHECK:STDOUT:   %x.var: ref @F.%T (%T) = var x
-// CHECK:STDOUT:   %x: ref @F.%T (%T) = bind_name x, %x.var
-// CHECK:STDOUT:   return
+// CHECK:STDOUT: generic fn @F(%T.loc13: %.1) {
+// CHECK:STDOUT:   %T.1: %.1 = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%T.loc13: %.1) {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %T.ref: %.1 = name_ref T, %T.loc13 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:     %.loc14_10.1: type = facet_type_access %T.ref [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:     %.loc14_10.2: type = converted %T.ref, %.loc14_10.1 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:     %x.var: ref @F.%T.1 (%T) = var x
+// CHECK:STDOUT:     %x: ref @F.%T.1 (%T) = bind_name x, %x.var
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%F.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @F.%T => constants.%T
+// CHECK:STDOUT: specific @F(constants.%T) {
+// CHECK:STDOUT:   %T.1 => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

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

@@ -60,10 +60,10 @@ interface ForwardDeclared {
 // CHECK:STDOUT:   witness = (%F.decl)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F()
-// CHECK:STDOUT:     generic [@ForwardDeclared.%Self: %.2];
+// CHECK:STDOUT: generic fn @F(@ForwardDeclared.%Self: %.2) {
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @ForwardDeclared.%F.decl(constants.%Self.2) {
-// CHECK:STDOUT: declaration:
+// CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @F(constants.%Self.2) {}
+// CHECK:STDOUT:

+ 20 - 19
toolchain/check/testdata/interface/no_prelude/default_fn.carbon

@@ -81,22 +81,25 @@ class C {
 // CHECK:STDOUT:   .I = %I.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.1()
-// CHECK:STDOUT:     generic [@I.%Self: %.1] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %C.ref: type = name_ref C, file.%C.decl [template = constants.%C]
-// CHECK:STDOUT:   %c.var: ref %C = var c
-// CHECK:STDOUT:   %c: ref %C = bind_name c, %c.var
-// CHECK:STDOUT:   %.loc16_19.1: %.6 = struct_literal ()
-// CHECK:STDOUT:   %.loc16_19.2: init %C = class_init (), %c.var [template = constants.%struct]
-// CHECK:STDOUT:   %.loc16_20: init %C = converted %.loc16_19.1, %.loc16_19.2 [template = constants.%struct]
-// CHECK:STDOUT:   assign %c.var, %.loc16_20
-// CHECK:STDOUT:   %c.ref: ref %C = name_ref c, %c
-// CHECK:STDOUT:   %I.ref: type = name_ref I, @C.%I.decl [template = constants.%.1]
-// CHECK:STDOUT:   %F.ref: %.3 = name_ref F, @I.%.loc14 [template = constants.%.4]
-// CHECK:STDOUT:   %.1: %F.type.1 = interface_witness_access @impl.%.1, element0 [template = constants.%F.2]
-// CHECK:STDOUT:   %F.call: init %.2 = call %.1()
-// CHECK:STDOUT:   return
+// CHECK:STDOUT: generic fn @F.1(@I.%Self: %.1) {
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn() {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %C.ref: type = name_ref C, file.%C.decl [template = constants.%C]
+// CHECK:STDOUT:     %c.var: ref %C = var c
+// CHECK:STDOUT:     %c: ref %C = bind_name c, %c.var
+// CHECK:STDOUT:     %.loc16_19.1: %.6 = struct_literal ()
+// CHECK:STDOUT:     %.loc16_19.2: init %C = class_init (), %c.var [template = constants.%struct]
+// CHECK:STDOUT:     %.loc16_20: init %C = converted %.loc16_19.1, %.loc16_19.2 [template = constants.%struct]
+// CHECK:STDOUT:     assign %c.var, %.loc16_20
+// CHECK:STDOUT:     %c.ref: ref %C = name_ref c, %c
+// CHECK:STDOUT:     %I.ref: type = name_ref I, @C.%I.decl [template = constants.%.1]
+// CHECK:STDOUT:     %F.ref: %.3 = name_ref F, @I.%.loc14 [template = constants.%.4]
+// CHECK:STDOUT:     %.1: %F.type.1 = interface_witness_access @impl.%.1, element0 [template = constants.%F.2]
+// CHECK:STDOUT:     %F.call: init %.2 = call %.1()
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.2() {
@@ -104,7 +107,5 @@ class C {
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @I.%F.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT: }
+// CHECK:STDOUT: specific @F.1(constants.%Self) {}
 // CHECK:STDOUT:

+ 24 - 22
toolchain/check/testdata/interface/no_prelude/fail_add_member_outside_definition.carbon

@@ -79,15 +79,19 @@ interface Outer {
 // CHECK:STDOUT:   witness = ()
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: interface @Inner
-// CHECK:STDOUT:     generic [@Outer.%Self: %.3] {
-// CHECK:STDOUT:   %Self: %.4 = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self.3)]
-// CHECK:STDOUT:   %.decl: %.type = fn_decl @.1 [template = constants.%.5] {}
-// CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .F = @Outer.%F.decl
-// CHECK:STDOUT:   witness = ()
+// CHECK:STDOUT: generic interface @Inner(@Outer.%Self: %.3) {
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Self.2: %.4 = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self.3)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   interface {
+// CHECK:STDOUT:     %Self.1: %.4 = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self.3)]
+// CHECK:STDOUT:     %.decl: %.type = fn_decl @.1 [template = constants.%.5] {}
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = %Self.1
+// CHECK:STDOUT:     .F = @Outer.%F.decl
+// CHECK:STDOUT:     witness = ()
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.1() {
@@ -95,24 +99,22 @@ interface Outer {
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @.1()
-// CHECK:STDOUT:     generic [@Outer.%Self: %.3, @Inner.%Self: %.4];
+// CHECK:STDOUT: generic fn @.1(@Outer.%Self: %.3, @Inner.%Self.1: %.4) {
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.2()
-// CHECK:STDOUT:     generic [@Outer.%Self: %.3];
+// CHECK:STDOUT:   fn();
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Outer.%Inner.decl(constants.%Self.2) {
-// CHECK:STDOUT: declaration:
+// CHECK:STDOUT: generic fn @F.2(@Outer.%Self: %.3) {
 // CHECK:STDOUT:
-// CHECK:STDOUT: definition:
-// CHECK:STDOUT:   @Inner.%Self => constants.%Self.3
+// CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Inner.%.decl(constants.%Self.2, constants.%Self.3) {
-// CHECK:STDOUT: declaration:
+// CHECK:STDOUT: specific @Inner(constants.%Self.2) {
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Self.2 => constants.%Self.3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Outer.%F.decl(constants.%Self.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT: }
+// CHECK:STDOUT: specific @.1(constants.%Self.2, constants.%Self.3) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F.2(constants.%Self.2) {}
 // CHECK:STDOUT:

+ 54 - 40
toolchain/check/testdata/interface/no_prelude/fail_generic_redeclaration.carbon

@@ -45,7 +45,7 @@ interface DifferentParams(T:! ()) {}
 // CHECK:STDOUT:   %.type.1: type = generic_interface_type @.1 [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %.3: %.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %.4: type = interface_type @.1, file.%.decl.loc19(%T.1) [symbolic]
+// CHECK:STDOUT:   %.4: type = interface_type @.1, @.1(%T.1) [symbolic]
 // CHECK:STDOUT:   %Self.1: %.4 = bind_symbolic_name Self 1 [symbolic]
 // CHECK:STDOUT:   %Generic.type: type = generic_interface_type @Generic [template]
 // CHECK:STDOUT:   %Generic: %Generic.type = struct_value () [template]
@@ -56,7 +56,7 @@ interface DifferentParams(T:! ()) {}
 // CHECK:STDOUT:   %T.2: %.2 = bind_symbolic_name T 0 [symbolic]
 // CHECK:STDOUT:   %.type.2: type = generic_interface_type @.3 [template]
 // CHECK:STDOUT:   %.6: %.type.2 = struct_value () [template]
-// CHECK:STDOUT:   %.7: type = interface_type @.3, file.%.decl.loc38(%T.2) [symbolic]
+// CHECK:STDOUT:   %.7: type = interface_type @.3, @.3(%T.2) [symbolic]
 // CHECK:STDOUT:   %Self.3: %.7 = bind_symbolic_name Self 1 [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -69,38 +69,48 @@ interface DifferentParams(T:! ()) {}
 // CHECK:STDOUT:   %NotGeneric.decl: type = interface_decl @NotGeneric [template = constants.%.1] {}
 // CHECK:STDOUT:   %.decl.loc19: %.type.1 = interface_decl @.1 [template = constants.%.3] {
 // CHECK:STDOUT:     %T.loc19_22.1: type = param T
-// CHECK:STDOUT:     %T.loc19_22.2: type = bind_symbolic_name T 0, %T.loc19_22.1 [symbolic = %T.loc19_22.2 (constants.%T.1)]
+// CHECK:STDOUT:     %T.loc19_22.2: type = bind_symbolic_name T 0, %T.loc19_22.1 [symbolic = @.1.%T (constants.%T.1)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Generic.decl: %Generic.type = interface_decl @Generic [template = constants.%Generic] {
 // CHECK:STDOUT:     %T.loc21_19.1: type = param T
-// CHECK:STDOUT:     %T.loc21_19.2: type = bind_symbolic_name T 0, %T.loc21_19.1 [symbolic = %T.loc21_19.2 (constants.%T.1)]
+// CHECK:STDOUT:     %T.loc21_19.2: type = bind_symbolic_name T 0, %T.loc21_19.1 [symbolic = @Generic.%T (constants.%T.1)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.decl.loc29: type = interface_decl @.2 [template = constants.%.5] {}
 // CHECK:STDOUT:   %DifferentParams.decl: %DifferentParams.type = interface_decl @DifferentParams [template = constants.%DifferentParams] {
 // CHECK:STDOUT:     %T.loc31_27.1: type = param T
-// CHECK:STDOUT:     %T.loc31_27.2: type = bind_symbolic_name T 0, %T.loc31_27.1 [symbolic = %T.loc31_27.2 (constants.%T.1)]
+// CHECK:STDOUT:     %T.loc31_27.2: type = bind_symbolic_name T 0, %T.loc31_27.1 [symbolic = @DifferentParams.%T (constants.%T.1)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.decl.loc38: %.type.2 = interface_decl @.3 [template = constants.%.6] {
 // CHECK:STDOUT:     %.loc38_32.1: %.2 = tuple_literal ()
 // CHECK:STDOUT:     %.loc38_32.2: type = converted %.loc38_32.1, constants.%.2 [template = constants.%.2]
 // CHECK:STDOUT:     %T.loc38_27.1: %.2 = param T
-// CHECK:STDOUT:     %T.loc38_27.2: %.2 = bind_symbolic_name T 0, %T.loc38_27.1 [symbolic = %T.loc38_27.2 (constants.%T.2)]
+// CHECK:STDOUT:     %T.loc38_27.2: %.2 = bind_symbolic_name T 0, %T.loc38_27.1 [symbolic = @.3.%T (constants.%T.2)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @NotGeneric;
 // CHECK:STDOUT:
-// CHECK:STDOUT: interface @.1
-// CHECK:STDOUT:     generic [file.%T.loc19_22.2: type] {
-// CHECK:STDOUT:   %Self: <unexpected>.inst+13 (%.4) = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self.1)]
+// CHECK:STDOUT: generic interface @.1(file.%T.loc19_22.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T.1)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   witness = ()
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1: type = interface_type @.1, @.1(%T) [symbolic = %.1 (constants.%.4)]
+// CHECK:STDOUT:   %Self.2: %.4 = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self.1)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   interface {
+// CHECK:STDOUT:     %Self.1: @.1.%.1 (%.4) = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self.1)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = %Self.1
+// CHECK:STDOUT:     witness = ()
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: interface @Generic
-// CHECK:STDOUT:     generic [file.%T.loc21_19.2: type];
+// CHECK:STDOUT: generic interface @Generic(file.%T.loc21_19.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T.1)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   interface;
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @.2 {
 // CHECK:STDOUT:   %Self: %.5 = bind_symbolic_name Self 0 [symbolic = constants.%Self.2]
@@ -110,45 +120,49 @@ interface DifferentParams(T:! ()) {}
 // CHECK:STDOUT:   witness = ()
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: interface @DifferentParams
-// CHECK:STDOUT:     generic [file.%T.loc31_27.2: type];
+// CHECK:STDOUT: generic interface @DifferentParams(file.%T.loc31_27.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T.1)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: interface @.3
-// CHECK:STDOUT:     generic [file.%T.loc38_27.2: %.2] {
-// CHECK:STDOUT:   %Self: <unexpected>.inst+39 (%.7) = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self.3)]
+// CHECK:STDOUT:   interface;
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   witness = ()
+// CHECK:STDOUT: generic interface @.3(file.%T.loc38_27.2: %.2) {
+// CHECK:STDOUT:   %T: %.2 = bind_symbolic_name T 0 [symbolic = %T (constants.%T.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1: type = interface_type @.3, @.3(%T) [symbolic = %.1 (constants.%.7)]
+// CHECK:STDOUT:   %Self.2: %.7 = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self.3)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   interface {
+// CHECK:STDOUT:     %Self.1: @.3.%.1 (%.7) = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self.3)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = %Self.1
+// CHECK:STDOUT:     witness = ()
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%.decl.loc19(constants.%T.1) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc19_22.2 => constants.%T.1
+// CHECK:STDOUT: specific @.1(constants.%T.1) {
+// CHECK:STDOUT:   %T => constants.%T.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%.decl.loc19(file.%T.loc19_22.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc19_22.2 => constants.%T.1
+// CHECK:STDOUT: specific @.1(@.1.%T) {
+// CHECK:STDOUT:   %T => constants.%T.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Generic.decl(constants.%T.1) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc21_19.2 => constants.%T.1
+// CHECK:STDOUT: specific @Generic(constants.%T.1) {
+// CHECK:STDOUT:   %T => constants.%T.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%DifferentParams.decl(constants.%T.1) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc31_27.2 => constants.%T.1
+// CHECK:STDOUT: specific @DifferentParams(constants.%T.1) {
+// CHECK:STDOUT:   %T => constants.%T.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%.decl.loc38(constants.%T.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc38_27.2 => constants.%T.2
+// CHECK:STDOUT: specific @.3(constants.%T.2) {
+// CHECK:STDOUT:   %T => constants.%T.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%.decl.loc38(file.%T.loc38_27.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc38_27.2 => constants.%T.2
+// CHECK:STDOUT: specific @.3(@.3.%T) {
+// CHECK:STDOUT:   %T => constants.%T.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

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

@@ -107,17 +107,17 @@ interface BeingDefined {
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @H() -> <error>
-// CHECK:STDOUT:     generic [@BeingDefined.%Self: %.4];
+// CHECK:STDOUT: generic fn @H(@BeingDefined.%Self: %.4) {
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @.2()
-// CHECK:STDOUT:     generic [@BeingDefined.%Self: %.4];
-// CHECK:STDOUT:
-// CHECK:STDOUT: specific @BeingDefined.%H.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
+// CHECK:STDOUT:   fn() -> <error>;
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @BeingDefined.%.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
+// CHECK:STDOUT: generic fn @.2(@BeingDefined.%Self: %.4) {
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @H(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @.2(constants.%Self) {}
+// CHECK:STDOUT:

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

@@ -66,8 +66,10 @@ fn F() {
 // CHECK:STDOUT:   witness = (%F.decl, %T)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.1()
-// CHECK:STDOUT:     generic [@Interface.%Self: %.1];
+// CHECK:STDOUT: generic fn @F.1(@Interface.%Self: %.1) {
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn();
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.2() {
 // CHECK:STDOUT: !entry:
@@ -80,7 +82,5 @@ fn F() {
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Interface.%F.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT: }
+// CHECK:STDOUT: specific @F.1(constants.%Self) {}
 // CHECK:STDOUT:

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

@@ -52,17 +52,17 @@ interface Interface {
 // CHECK:STDOUT:   witness = (%F.decl)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F()
-// CHECK:STDOUT:     generic [@Interface.%Self: %.1];
+// CHECK:STDOUT: generic fn @F(@Interface.%Self: %.1) {
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @.1()
-// CHECK:STDOUT:     generic [@Interface.%Self: %.1];
-// CHECK:STDOUT:
-// CHECK:STDOUT: specific @Interface.%F.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
+// CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Interface.%.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
+// CHECK:STDOUT: generic fn @.1(@Interface.%Self: %.1) {
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @F(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @.1(constants.%Self) {}
+// CHECK:STDOUT:

+ 36 - 28
toolchain/check/testdata/interface/no_prelude/fail_todo_facet_lookup.carbon

@@ -52,17 +52,17 @@ fn CallFacet(T:! Interface, x: T) {
 // CHECK:STDOUT:   %CallStatic.decl: %CallStatic.type = fn_decl @CallStatic [template = constants.%CallStatic] {
 // CHECK:STDOUT:     %Interface.ref.loc13: type = name_ref Interface, %Interface.decl [template = constants.%.1]
 // CHECK:STDOUT:     %T.loc13_15.1: %.1 = param T
-// CHECK:STDOUT:     @CallStatic.%T: %.1 = bind_symbolic_name T 0, %T.loc13_15.1 [symbolic = @CallStatic.%T (constants.%T)]
+// CHECK:STDOUT:     @CallStatic.%T.loc13: %.1 = bind_symbolic_name T 0, %T.loc13_15.1 [symbolic = @CallStatic.%T.1 (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %CallFacet.decl: %CallFacet.type = fn_decl @CallFacet [template = constants.%CallFacet] {
 // CHECK:STDOUT:     %Interface.ref.loc21: type = name_ref Interface, %Interface.decl [template = constants.%.1]
 // CHECK:STDOUT:     %T.loc21_14.1: %.1 = param T
-// CHECK:STDOUT:     @CallFacet.%T: %.1 = bind_symbolic_name T 0, %T.loc21_14.1 [symbolic = @CallFacet.%T (constants.%T)]
-// CHECK:STDOUT:     %T.ref: %.1 = name_ref T, @CallFacet.%T [symbolic = @CallFacet.%T (constants.%T)]
-// CHECK:STDOUT:     %.loc21_32.1: type = facet_type_access %T.ref [symbolic = @CallFacet.%T (constants.%T)]
-// CHECK:STDOUT:     %.loc21_32.2: type = converted %T.ref, %.loc21_32.1 [symbolic = @CallFacet.%T (constants.%T)]
-// CHECK:STDOUT:     %x.loc21_29.1: @CallFacet.%T (%T) = param x
-// CHECK:STDOUT:     @CallFacet.%x: @CallFacet.%T (%T) = bind_name x, %x.loc21_29.1
+// CHECK:STDOUT:     @CallFacet.%T.loc21: %.1 = bind_symbolic_name T 0, %T.loc21_14.1 [symbolic = @CallFacet.%T.1 (constants.%T)]
+// CHECK:STDOUT:     %T.ref: %.1 = name_ref T, @CallFacet.%T.loc21 [symbolic = @CallFacet.%T.1 (constants.%T)]
+// CHECK:STDOUT:     %.loc21_32.1: type = facet_type_access %T.ref [symbolic = @CallFacet.%T.1 (constants.%T)]
+// CHECK:STDOUT:     %.loc21_32.2: type = converted %T.ref, %.loc21_32.1 [symbolic = @CallFacet.%T.1 (constants.%T)]
+// CHECK:STDOUT:     %x.loc21_29.1: @CallFacet.%T.1 (%T) = param x
+// CHECK:STDOUT:     @CallFacet.%x: @CallFacet.%T.1 (%T) = bind_name x, %x.loc21_29.1
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -77,35 +77,43 @@ fn CallFacet(T:! Interface, x: T) {
 // CHECK:STDOUT:   witness = (%F.decl)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F()
-// CHECK:STDOUT:     generic [@Interface.%Self: %.1];
+// CHECK:STDOUT: generic fn @F(@Interface.%Self: %.1) {
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @CallStatic(%T: %.1)
-// CHECK:STDOUT:     generic [%T: %.1] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %T.ref: %.1 = name_ref T, %T [symbolic = %T (constants.%T)]
-// CHECK:STDOUT:   %F.ref: %.3 = name_ref F, @Interface.%.loc11 [template = constants.%.4]
-// CHECK:STDOUT:   return
+// CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @CallFacet(%T: %.1, %x: @CallFacet.%T (%T))
-// CHECK:STDOUT:     generic [%T: %.1] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %x.ref: @CallFacet.%T (%T) = name_ref x, %x
-// CHECK:STDOUT:   return
+// CHECK:STDOUT: generic fn @CallStatic(%T.loc13: %.1) {
+// CHECK:STDOUT:   %T.1: %.1 = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%T.loc13: %.1) {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %T.ref: %.1 = name_ref T, %T.loc13 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:     %F.ref: %.3 = name_ref F, @Interface.%.loc11 [template = constants.%.4]
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Interface.%F.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
+// CHECK:STDOUT: generic fn @CallFacet(%T.loc21: %.1) {
+// CHECK:STDOUT:   %T.1: %.1 = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%T.loc21: %.1, %x: @CallFacet.%T.1 (%T)) {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %x.ref: @CallFacet.%T.1 (%T) = name_ref x, %x
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%CallStatic.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @CallStatic.%T => constants.%T
+// CHECK:STDOUT: specific @F(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @CallStatic(constants.%T) {
+// CHECK:STDOUT:   %T.1 => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%CallFacet.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @CallFacet.%T => constants.%T
+// CHECK:STDOUT: specific @CallFacet(constants.%T) {
+// CHECK:STDOUT:   %T.1 => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 82 - 63
toolchain/check/testdata/interface/no_prelude/fail_todo_generic_default_fn.carbon

@@ -28,13 +28,12 @@ fn I(T:! type).F[self: Self]() -> Self { return self; }
 // CHECK:STDOUT:   %I.type: type = generic_interface_type @I [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %I: %I.type = struct_value () [template]
-// CHECK:STDOUT:   %.2: type = interface_type @I, file.%I.decl(%T) [symbolic]
-// CHECK:STDOUT:   %Self.1: %.2 = bind_symbolic_name Self 1 [symbolic]
+// CHECK:STDOUT:   %.2: type = interface_type @I, @I(%T) [symbolic]
+// CHECK:STDOUT:   %Self: %.2 = bind_symbolic_name Self 1 [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT:   %.3: type = assoc_entity_type @I, %F.type [template]
 // CHECK:STDOUT:   %.4: %.3 = assoc_entity element0, @I.%F.decl [template]
-// CHECK:STDOUT:   %Self.2: <unexpected>.inst+28 (%.2) = bind_symbolic_name Self 1 [symbolic]
 // CHECK:STDOUT:   %.type: type = fn_type @.1 [template]
 // CHECK:STDOUT:   %.5: %.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -45,87 +44,107 @@ fn I(T:! type).F[self: Self]() -> Self { return self; }
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %I.decl: %I.type = interface_decl @I [template = constants.%I] {
 // CHECK:STDOUT:     %T.loc11_13.1: type = param T
-// CHECK:STDOUT:     %T.loc11_13.2: type = bind_symbolic_name T 0, %T.loc11_13.1 [symbolic = %T.loc11_13.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc11_13.2: type = bind_symbolic_name T 0, %T.loc11_13.1 [symbolic = @I.%T (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.decl: %.type = fn_decl @.1 [template = constants.%.5] {
 // CHECK:STDOUT:     %T.loc22_6.1: type = param T
-// CHECK:STDOUT:     %T.loc22_6.2: type = bind_symbolic_name T 0, %T.loc22_6.1 [symbolic = %T.loc22_6.2 (constants.%T)]
-// CHECK:STDOUT:     %.loc22_24.1: <unexpected>.inst+44 (%.2) = specific_constant @I.%Self, %I.decl(constants.%T) [symbolic = %.loc22_24.1 (constants.%Self.2)]
-// CHECK:STDOUT:     %Self.ref.loc22_24: <unexpected>.inst+44 (%.2) = name_ref Self, %.loc22_24.1 [symbolic = %.loc22_24.1 (constants.%Self.2)]
-// CHECK:STDOUT:     %.loc22_24.2: type = facet_type_access %Self.ref.loc22_24 [symbolic = %.loc22_24.1 (constants.%Self.2)]
-// CHECK:STDOUT:     %.loc22_24.3: type = converted %Self.ref.loc22_24, %.loc22_24.2 [symbolic = %.loc22_24.1 (constants.%Self.2)]
-// CHECK:STDOUT:     %self.loc22_18.1: file.%.loc22_24.1 (%Self.2) = param self
-// CHECK:STDOUT:     @.1.%self: file.%.loc22_24.1 (%Self.2) = bind_name self, %self.loc22_18.1
-// CHECK:STDOUT:     %.loc22_35.1: <unexpected>.inst+44 (%.2) = specific_constant @I.%Self, %I.decl(constants.%T) [symbolic = %.loc22_24.1 (constants.%Self.2)]
-// CHECK:STDOUT:     %Self.ref.loc22_35: <unexpected>.inst+44 (%.2) = name_ref Self, %.loc22_35.1 [symbolic = %.loc22_24.1 (constants.%Self.2)]
-// CHECK:STDOUT:     %.loc22_35.2: type = facet_type_access %Self.ref.loc22_35 [symbolic = %.loc22_24.1 (constants.%Self.2)]
-// CHECK:STDOUT:     %.loc22_35.3: type = converted %Self.ref.loc22_35, %.loc22_35.2 [symbolic = %.loc22_24.1 (constants.%Self.2)]
-// CHECK:STDOUT:     @.1.%return: ref %Self.2 = var <return slot>
+// CHECK:STDOUT:     %T.loc22_6.2: type = bind_symbolic_name T 0, %T.loc22_6.1 [symbolic = @.1.%T (constants.%T)]
+// CHECK:STDOUT:     %.loc22_24.1: @.1.%.1 (%.2) = specific_constant @I.%Self.1, @I(constants.%T) [symbolic = @.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %Self.ref.loc22_24: @.1.%.1 (%.2) = name_ref Self, %.loc22_24.1 [symbolic = @.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc22_24.2: type = facet_type_access %Self.ref.loc22_24 [symbolic = @.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc22_24.3: type = converted %Self.ref.loc22_24, %.loc22_24.2 [symbolic = @.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %self.loc22_18.1: @.1.%Self (%Self) = param self
+// CHECK:STDOUT:     @.1.%self: @.1.%Self (%Self) = bind_name self, %self.loc22_18.1
+// CHECK:STDOUT:     %.loc22_35.1: @.1.%.1 (%.2) = specific_constant @I.%Self.1, @I(constants.%T) [symbolic = @.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %Self.ref.loc22_35: @.1.%.1 (%.2) = name_ref Self, %.loc22_35.1 [symbolic = @.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc22_35.2: type = facet_type_access %Self.ref.loc22_35 [symbolic = @.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc22_35.3: type = converted %Self.ref.loc22_35, %.loc22_35.2 [symbolic = @.1.%Self (constants.%Self)]
+// CHECK:STDOUT:     @.1.%return: ref %Self = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: interface @I
-// CHECK:STDOUT:     generic [file.%T.loc11_13.2: type] {
-// CHECK:STDOUT:   %Self: <unexpected>.inst+28 (%.2) = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self.1)]
-// CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
-// CHECK:STDOUT:     %.loc13_14.1: %.2 = specific_constant %Self, file.%I.decl(constants.%T) [symbolic = %.loc13_14.1 (constants.%Self.1)]
-// CHECK:STDOUT:     %Self.ref.loc13_14: %.2 = name_ref Self, %.loc13_14.1 [symbolic = %.loc13_14.1 (constants.%Self.1)]
-// CHECK:STDOUT:     %.loc13_14.2: type = facet_type_access %Self.ref.loc13_14 [symbolic = %.loc13_14.1 (constants.%Self.1)]
-// CHECK:STDOUT:     %.loc13_14.3: type = converted %Self.ref.loc13_14, %.loc13_14.2 [symbolic = %.loc13_14.1 (constants.%Self.1)]
-// CHECK:STDOUT:     %self.loc13_8.1: @I.%.loc13_14.1 (%Self.1) = param self
-// CHECK:STDOUT:     %self.loc13_8.2: @I.%.loc13_14.1 (%Self.1) = bind_name self, %self.loc13_8.1
-// CHECK:STDOUT:     %.loc13_25.1: %.2 = specific_constant %Self, file.%I.decl(constants.%T) [symbolic = %.loc13_14.1 (constants.%Self.1)]
-// CHECK:STDOUT:     %Self.ref.loc13_25: %.2 = name_ref Self, %.loc13_25.1 [symbolic = %.loc13_14.1 (constants.%Self.1)]
-// CHECK:STDOUT:     %.loc13_25.2: type = facet_type_access %Self.ref.loc13_25 [symbolic = %.loc13_14.1 (constants.%Self.1)]
-// CHECK:STDOUT:     %.loc13_25.3: type = converted %Self.ref.loc13_25, %.loc13_25.2 [symbolic = %.loc13_14.1 (constants.%Self.1)]
-// CHECK:STDOUT:     %return.var: ref %Self.1 = var <return slot>
+// CHECK:STDOUT: generic interface @I(file.%T.loc11_13.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1: type = interface_type @I, @I(%T) [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:   %Self.2: %.2 = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   interface {
+// CHECK:STDOUT:     %Self.1: @I.%.1 (%.2) = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self)]
+// CHECK:STDOUT:     %F.decl: %F.type = fn_decl @F [template = constants.%F] {
+// CHECK:STDOUT:       %.loc13_14.1: @F.%.1 (%.2) = specific_constant %Self.1, @I(constants.%T) [symbolic = @F.%Self (constants.%Self)]
+// CHECK:STDOUT:       %Self.ref.loc13_14: @F.%.1 (%.2) = name_ref Self, %.loc13_14.1 [symbolic = @F.%Self (constants.%Self)]
+// CHECK:STDOUT:       %.loc13_14.2: type = facet_type_access %Self.ref.loc13_14 [symbolic = @F.%Self (constants.%Self)]
+// CHECK:STDOUT:       %.loc13_14.3: type = converted %Self.ref.loc13_14, %.loc13_14.2 [symbolic = @F.%Self (constants.%Self)]
+// CHECK:STDOUT:       %self.loc13_8.1: @F.%Self (%Self) = param self
+// CHECK:STDOUT:       %self.loc13_8.2: @F.%Self (%Self) = bind_name self, %self.loc13_8.1
+// CHECK:STDOUT:       %.loc13_25.1: @F.%.1 (%.2) = specific_constant %Self.1, @I(constants.%T) [symbolic = @F.%Self (constants.%Self)]
+// CHECK:STDOUT:       %Self.ref.loc13_25: @F.%.1 (%.2) = name_ref Self, %.loc13_25.1 [symbolic = @F.%Self (constants.%Self)]
+// CHECK:STDOUT:       %.loc13_25.2: type = facet_type_access %Self.ref.loc13_25 [symbolic = @F.%Self (constants.%Self)]
+// CHECK:STDOUT:       %.loc13_25.3: type = converted %Self.ref.loc13_25, %.loc13_25.2 [symbolic = @F.%Self (constants.%Self)]
+// CHECK:STDOUT:       %return.var: ref %Self = var <return slot>
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %.loc13_29: %.3 = assoc_entity element0, %F.decl [template = constants.%.4]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = %Self.1
+// CHECK:STDOUT:     .F = %.loc13_29
+// CHECK:STDOUT:     witness = (%F.decl)
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %.loc13_29: %.3 = assoc_entity element0, %F.decl [template = constants.%.4]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @F(file.%T.loc11_13.2: type, @I.%Self.1: @I.%.1 (%.2)) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %.1: type = interface_type @I, @I(%T) [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:   %Self: %.2 = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .F = %.loc13_29
-// CHECK:STDOUT:   witness = (%F.decl)
+// CHECK:STDOUT:   fn[@I.%self.loc13_8.2: @F.%Self (%Self)]() -> %Self;
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F[@I.%self.loc13_8.2: @I.%.loc13_14.1 (%Self.1)]() -> %Self.1
-// CHECK:STDOUT:     generic [file.%T.loc11_13.2: type, @I.%Self: <unexpected>.inst+28 (%.2)];
+// CHECK:STDOUT: generic fn @.1(file.%T.loc22_6.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %.1: type = interface_type @I, @I(%T) [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:   %Self: %.2 = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @.1[%self: file.%.loc22_24.1 (%Self.2)]() -> %Self.2
-// CHECK:STDOUT:     generic [file.%T.loc22_6.2: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %self.ref: file.%.loc22_24.1 (%Self.2) = name_ref self, %self
-// CHECK:STDOUT:   return %self.ref
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn[%self: @.1.%Self (%Self)]() -> %Self {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %self.ref: @.1.%Self (%Self) = name_ref self, %self
+// CHECK:STDOUT:     return %self.ref
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%I.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc11_13.2 => constants.%T
+// CHECK:STDOUT: specific @I(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1 => constants.%.2
+// CHECK:STDOUT:   %Self.2 => constants.%Self
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: definition:
-// CHECK:STDOUT:   <unexpected>.inst+28 => constants.%.2
-// CHECK:STDOUT:   @I.%Self => constants.%Self.2
+// CHECK:STDOUT: specific @I(@F.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @I.%F.decl(constants.%T, constants.%Self.1) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @I.%.loc13_14.1 => constants.%Self.1
+// CHECK:STDOUT: specific @F(constants.%T, constants.%Self) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %.1 => constants.%.2
+// CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%I.decl(file.%T.loc11_13.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc11_13.2 => constants.%T
+// CHECK:STDOUT: specific @I(@I.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%I.decl(file.%T.loc22_6.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc11_13.2 => constants.%T
+// CHECK:STDOUT: specific @I(@.1.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc22_6.2 => constants.%T
-// CHECK:STDOUT:   <unexpected>.inst+44 => constants.%.2
-// CHECK:STDOUT:   file.%.loc22_24.1 => constants.%Self.2
+// CHECK:STDOUT: specific @.1(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %.1 => constants.%.2
+// CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 16 - 14
toolchain/check/testdata/interface/no_prelude/fail_todo_modifiers.carbon

@@ -57,23 +57,25 @@ interface Modifiers {
 // CHECK:STDOUT:   witness = (%Final.decl, %Default.decl)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @Final()
-// CHECK:STDOUT:     generic [@Modifiers.%Self: %.1] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   return
-// CHECK:STDOUT: }
+// CHECK:STDOUT: generic fn @Final(@Modifiers.%Self: %.1) {
+// CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @Default()
-// CHECK:STDOUT:     generic [@Modifiers.%Self: %.1] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   return
+// CHECK:STDOUT:   fn() {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Modifiers.%Final.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT: }
+// CHECK:STDOUT: generic fn @Default(@Modifiers.%Self: %.1) {
+// CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Modifiers.%Default.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
+// CHECK:STDOUT:   fn() {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @Final(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Default(constants.%Self) {}
+// CHECK:STDOUT:

+ 138 - 112
toolchain/check/testdata/interface/no_prelude/generic.carbon

@@ -65,22 +65,22 @@ fn G(T:! Generic(B)) {
 // CHECK:STDOUT:   %Simple.type: type = generic_interface_type @Simple [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %Simple: %Simple.type = struct_value () [template]
-// CHECK:STDOUT:   %.2: type = interface_type @Simple, file.%Simple.decl(%T.1) [symbolic]
+// CHECK:STDOUT:   %.2: type = interface_type @Simple, @Simple(%T.1) [symbolic]
 // CHECK:STDOUT:   %Self.1: %.2 = bind_symbolic_name Self 1 [symbolic]
 // CHECK:STDOUT:   %X: type = class_type @X [template]
 // CHECK:STDOUT:   %.3: type = struct_type {} [template]
 // CHECK:STDOUT:   %WithAssocFn.type: type = generic_interface_type @WithAssocFn [template]
 // CHECK:STDOUT:   %WithAssocFn: %WithAssocFn.type = struct_value () [template]
-// CHECK:STDOUT:   %.4: type = interface_type @WithAssocFn, file.%WithAssocFn.decl(%T.1) [symbolic]
+// CHECK:STDOUT:   %.4: type = interface_type @WithAssocFn, @WithAssocFn(%T.1) [symbolic]
 // CHECK:STDOUT:   %Self.2: %.4 = bind_symbolic_name Self 1 [symbolic]
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
 // CHECK:STDOUT:   %.5: type = assoc_entity_type @WithAssocFn, %F.type.1 [template]
 // CHECK:STDOUT:   %.6: %.5 = assoc_entity element0, @WithAssocFn.%F.decl [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
-// CHECK:STDOUT:   %.7: type = interface_type @Simple, file.%Simple.decl(%C) [template]
+// CHECK:STDOUT:   %.7: type = interface_type @Simple, @Simple(%C) [template]
 // CHECK:STDOUT:   %.8: <witness> = interface_witness () [template]
-// CHECK:STDOUT:   %.9: type = interface_type @WithAssocFn, file.%WithAssocFn.decl(%C) [template]
+// CHECK:STDOUT:   %.9: type = interface_type @WithAssocFn, @WithAssocFn(%C) [template]
 // CHECK:STDOUT:   %F.type.2: type = fn_type @F.2 [template]
 // CHECK:STDOUT:   %F.2: %F.type.2 = struct_value () [template]
 // CHECK:STDOUT:   %.10: <witness> = interface_witness (%F.2) [template]
@@ -108,20 +108,20 @@ fn G(T:! Generic(B)) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Simple.decl: %Simple.type = interface_decl @Simple [template = constants.%Simple] {
 // CHECK:STDOUT:     %T.loc4_18.1: type = param T
-// CHECK:STDOUT:     %T.loc4_18.2: type = bind_symbolic_name T 0, %T.loc4_18.1 [symbolic = %T.loc4_18.2 (constants.%T.1)]
+// CHECK:STDOUT:     %T.loc4_18.2: type = bind_symbolic_name T 0, %T.loc4_18.1 [symbolic = @Simple.%T (constants.%T.1)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %X.decl: type = class_decl @X [template = constants.%X] {}
 // CHECK:STDOUT:   %WithAssocFn.decl: %WithAssocFn.type = interface_decl @WithAssocFn [template = constants.%WithAssocFn] {
 // CHECK:STDOUT:     %T.loc8_23.1: type = param T
-// CHECK:STDOUT:     %T.loc8_23.2: type = bind_symbolic_name T 0, %T.loc8_23.1 [symbolic = %T.loc8_23.2 (constants.%T.1)]
+// CHECK:STDOUT:     %T.loc8_23.2: type = bind_symbolic_name T 0, %T.loc8_23.1 [symbolic = @WithAssocFn.%T (constants.%T.1)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
 // CHECK:STDOUT:   %WithImplicitArgs.decl: %WithImplicitArgs.type = interface_decl @WithImplicitArgs [template = constants.%WithImplicitArgs] {
 // CHECK:STDOUT:     %T.loc22_28.1: type = param T
-// CHECK:STDOUT:     %T.loc22_28.2: type = bind_symbolic_name T 0, %T.loc22_28.1 [symbolic = %T.loc22_28.2 (constants.%T.1)]
-// CHECK:STDOUT:     %T.ref: type = name_ref T, %T.loc22_28.2 [symbolic = %T.loc22_28.2 (constants.%T.1)]
-// CHECK:STDOUT:     %N.loc22_38.1: file.%T.loc22_28.2 (%T.1) = param N
-// CHECK:STDOUT:     %N.loc22_38.2: file.%T.loc22_28.2 (%T.1) = bind_symbolic_name N 1, %N.loc22_38.1 [symbolic = %N.loc22_38.2 (constants.%N)]
+// CHECK:STDOUT:     %T.loc22_28.2: type = bind_symbolic_name T 0, %T.loc22_28.1 [symbolic = @WithImplicitArgs.%T (constants.%T.1)]
+// CHECK:STDOUT:     %T.ref: type = name_ref T, %T.loc22_28.2 [symbolic = @WithImplicitArgs.%T (constants.%T.1)]
+// CHECK:STDOUT:     %N.loc22_38.1: @WithImplicitArgs.%T (%T.1) = param N
+// CHECK:STDOUT:     %N.loc22_38.2: @WithImplicitArgs.%T (%T.1) = bind_symbolic_name N 1, %N.loc22_38.1 [symbolic = @WithImplicitArgs.%N (constants.%N)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Receive.decl: %Receive.type = fn_decl @Receive [template = constants.%Receive] {
 // CHECK:STDOUT:     %Simple.ref.loc24: %Simple.type = name_ref Simple, %Simple.decl [template = constants.%Simple]
@@ -130,7 +130,7 @@ fn G(T:! Generic(B)) {
 // CHECK:STDOUT:     %.loc24_24.1: type = value_of_initializer %.loc24_22 [template = constants.%.7]
 // CHECK:STDOUT:     %.loc24_24.2: type = converted %.loc24_22, %.loc24_24.1 [template = constants.%.7]
 // CHECK:STDOUT:     %T.loc24_12.1: %.7 = param T
-// CHECK:STDOUT:     @Receive.%T: %.7 = bind_symbolic_name T 0, %T.loc24_12.1 [symbolic = @Receive.%T (constants.%T.2)]
+// CHECK:STDOUT:     @Receive.%T.loc24: %.7 = bind_symbolic_name T 0, %T.loc24_12.1 [symbolic = @Receive.%T.1 (constants.%T.2)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Pass.decl: %Pass.type = fn_decl @Pass [template = constants.%Pass] {
 // CHECK:STDOUT:     %Simple.ref.loc25: %Simple.type = name_ref Simple, %Simple.decl [template = constants.%Simple]
@@ -139,36 +139,54 @@ fn G(T:! Generic(B)) {
 // CHECK:STDOUT:     %.loc25_21.1: type = value_of_initializer %.loc25_19 [template = constants.%.7]
 // CHECK:STDOUT:     %.loc25_21.2: type = converted %.loc25_19, %.loc25_21.1 [template = constants.%.7]
 // CHECK:STDOUT:     %T.loc25_9.1: %.7 = param T
-// CHECK:STDOUT:     @Pass.%T: %.7 = bind_symbolic_name T 0, %T.loc25_9.1 [symbolic = @Pass.%T (constants.%T.2)]
+// CHECK:STDOUT:     @Pass.%T.loc25: %.7 = bind_symbolic_name T 0, %T.loc25_9.1 [symbolic = @Pass.%T.1 (constants.%T.2)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: interface @Simple
-// CHECK:STDOUT:     generic [file.%T.loc4_18.2: type] {
-// CHECK:STDOUT:   %Self: <unexpected>.inst+11 (%.2) = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self.1)]
+// CHECK:STDOUT: generic interface @Simple(file.%T.loc4_18.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T.1)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   witness = ()
-// CHECK:STDOUT: }
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1: type = interface_type @Simple, @Simple(%T) [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:   %Self.2: %.2 = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self.1)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: interface @WithAssocFn
-// CHECK:STDOUT:     generic [file.%T.loc8_23.2: type] {
-// CHECK:STDOUT:   %Self: <unexpected>.inst+31 (%.4) = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self.2)]
-// CHECK:STDOUT:   %F.decl: %F.type.1 = fn_decl @F.1 [template = constants.%F.1] {
-// CHECK:STDOUT:     %X.ref: type = name_ref X, file.%X.decl [template = constants.%X]
-// CHECK:STDOUT:     %return.var: ref %X = var <return slot>
+// CHECK:STDOUT:   interface {
+// CHECK:STDOUT:     %Self.1: @Simple.%.1 (%.2) = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self.1)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = %Self.1
+// CHECK:STDOUT:     witness = ()
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %.loc10: %.5 = assoc_entity element0, %F.decl [template = constants.%.6]
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .F = %.loc10
-// CHECK:STDOUT:   witness = (%F.decl)
+// CHECK:STDOUT: generic interface @WithAssocFn(file.%T.loc8_23.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T.1)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1: type = interface_type @WithAssocFn, @WithAssocFn(%T) [symbolic = %.1 (constants.%.4)]
+// CHECK:STDOUT:   %Self.2: %.4 = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   interface {
+// CHECK:STDOUT:     %Self.1: @WithAssocFn.%.1 (%.4) = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self.2)]
+// CHECK:STDOUT:     %F.decl: %F.type.1 = fn_decl @F.1 [template = constants.%F.1] {
+// CHECK:STDOUT:       %X.ref: type = name_ref X, file.%X.decl [template = constants.%X]
+// CHECK:STDOUT:       %return.var: ref %X = var <return slot>
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %.loc10: %.5 = assoc_entity element0, %F.decl [template = constants.%.6]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = %Self.1
+// CHECK:STDOUT:     .F = %.loc10
+// CHECK:STDOUT:     witness = (%F.decl)
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: interface @WithImplicitArgs
-// CHECK:STDOUT:     generic [file.%T.loc22_28.2: type, file.%N.loc22_38.2: file.%T.loc22_28.2 (%T.1)];
+// CHECK:STDOUT: generic interface @WithImplicitArgs(file.%T.loc22_28.2: type, file.%N.loc22_38.2: @WithImplicitArgs.%T (%T.1)) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T.1)]
+// CHECK:STDOUT:   %N: %T.1 = bind_symbolic_name N 1 [symbolic = %N (constants.%N)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   interface;
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl.1: %C as %.7 {
 // CHECK:STDOUT:   %.1: <witness> = interface_witness () [template = constants.%.8]
@@ -214,8 +232,10 @@ fn G(T:! Generic(B)) {
 // CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.1() -> %X
-// CHECK:STDOUT:     generic [file.%T.loc8_23.2: type, @WithAssocFn.%Self: <unexpected>.inst+31 (%.4)];
+// CHECK:STDOUT: generic fn @F.1(file.%T.loc8_23.2: type, @WithAssocFn.%Self.1: @WithAssocFn.%.1 (%.4)) {
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn() -> %X;
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.2() -> @impl.2.%return.var: %X {
 // CHECK:STDOUT: !entry:
@@ -225,66 +245,63 @@ fn G(T:! Generic(B)) {
 // CHECK:STDOUT:   return %.loc17_16 to @impl.2.%return.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @Receive(%T: %.7)
-// CHECK:STDOUT:     generic [%T: %.7];
+// CHECK:STDOUT: generic fn @Receive(%T.loc24: %.7) {
+// CHECK:STDOUT:   %T.1: %.7 = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T.2)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @Pass(%T: %.7)
-// CHECK:STDOUT:     generic [%T: %.7] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Receive.ref: %Receive.type = name_ref Receive, file.%Receive.decl [template = constants.%Receive]
-// CHECK:STDOUT:   %T.ref: %.7 = name_ref T, %T [symbolic = %T (constants.%T.2)]
-// CHECK:STDOUT:   %Receive.call: init %.1 = call %Receive.ref(%T.ref)
-// CHECK:STDOUT:   return
+// CHECK:STDOUT:   fn(%T.loc24: %.7);
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Simple.decl(constants.%T.1) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_18.2 => constants.%T.1
+// CHECK:STDOUT: generic fn @Pass(%T.loc25: %.7) {
+// CHECK:STDOUT:   %T.1: %.7 = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T.2)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%T.loc25: %.7) {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %Receive.ref: %Receive.type = name_ref Receive, file.%Receive.decl [template = constants.%Receive]
+// CHECK:STDOUT:     %T.ref: %.7 = name_ref T, %T.loc25 [symbolic = %T.1 (constants.%T.2)]
+// CHECK:STDOUT:     %Receive.call: init %.1 = call %Receive.ref(%T.ref)
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Simple.decl(file.%T.loc4_18.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_18.2 => constants.%T.1
+// CHECK:STDOUT: specific @Simple(constants.%T.1) {
+// CHECK:STDOUT:   %T => constants.%T.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%WithAssocFn.decl(constants.%T.1) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc8_23.2 => constants.%T.1
+// CHECK:STDOUT: specific @Simple(@Simple.%T) {
+// CHECK:STDOUT:   %T => constants.%T.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @WithAssocFn.%F.decl(constants.%T.1, constants.%Self.2) {
-// CHECK:STDOUT: declaration:
+// CHECK:STDOUT: specific @WithAssocFn(constants.%T.1) {
+// CHECK:STDOUT:   %T => constants.%T.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%WithAssocFn.decl(file.%T.loc8_23.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc8_23.2 => constants.%T.1
+// CHECK:STDOUT: specific @F.1(constants.%T.1, constants.%Self.2) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @WithAssocFn(@WithAssocFn.%T) {
+// CHECK:STDOUT:   %T => constants.%T.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Simple.decl(constants.%C) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_18.2 => constants.%C
+// CHECK:STDOUT: specific @Simple(constants.%C) {
+// CHECK:STDOUT:   %T => constants.%C
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%WithAssocFn.decl(constants.%C) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc8_23.2 => constants.%C
+// CHECK:STDOUT: specific @WithAssocFn(constants.%C) {
+// CHECK:STDOUT:   %T => constants.%C
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%WithImplicitArgs.decl(constants.%T.1, constants.%N) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc22_28.2 => constants.%T.1
-// CHECK:STDOUT:   file.%N.loc22_38.2 => constants.%N
+// CHECK:STDOUT: specific @WithImplicitArgs(constants.%T.1, constants.%N) {
+// CHECK:STDOUT:   %T => constants.%T.1
+// CHECK:STDOUT:   %N => constants.%N
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Receive.decl(constants.%T.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @Receive.%T => constants.%T.2
+// CHECK:STDOUT: specific @Receive(constants.%T.2) {
+// CHECK:STDOUT:   %T.1 => constants.%T.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Pass.decl(constants.%T.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @Pass.%T => constants.%T.2
+// CHECK:STDOUT: specific @Pass(constants.%T.2) {
+// CHECK:STDOUT:   %T.1 => constants.%T.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_mismatched_args.carbon
@@ -294,16 +311,16 @@ fn G(T:! Generic(B)) {
 // CHECK:STDOUT:   %Generic.type: type = generic_interface_type @Generic [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %Generic: %Generic.type = struct_value () [template]
-// CHECK:STDOUT:   %.2: type = interface_type @Generic, file.%Generic.decl(%T.1) [symbolic]
+// CHECK:STDOUT:   %.2: type = interface_type @Generic, @Generic(%T.1) [symbolic]
 // CHECK:STDOUT:   %Self: %.2 = bind_symbolic_name Self 1 [symbolic]
 // CHECK:STDOUT:   %A: type = class_type @A [template]
 // CHECK:STDOUT:   %.3: type = struct_type {} [template]
 // CHECK:STDOUT:   %B: type = class_type @B [template]
-// CHECK:STDOUT:   %.4: type = interface_type @Generic, file.%Generic.decl(%A) [template]
+// CHECK:STDOUT:   %.4: type = interface_type @Generic, @Generic(%A) [template]
 // CHECK:STDOUT:   %T.2: %.4 = bind_symbolic_name T 0 [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
-// CHECK:STDOUT:   %.5: type = interface_type @Generic, file.%Generic.decl(%B) [template]
+// CHECK:STDOUT:   %.5: type = interface_type @Generic, @Generic(%B) [template]
 // CHECK:STDOUT:   %T.3: %.5 = bind_symbolic_name T 0 [symbolic]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [template]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [template]
@@ -319,7 +336,7 @@ fn G(T:! Generic(B)) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Generic.decl: %Generic.type = interface_decl @Generic [template = constants.%Generic] {
 // CHECK:STDOUT:     %T.loc4_19.1: type = param T
-// CHECK:STDOUT:     %T.loc4_19.2: type = bind_symbolic_name T 0, %T.loc4_19.1 [symbolic = %T.loc4_19.2 (constants.%T.1)]
+// CHECK:STDOUT:     %T.loc4_19.2: type = bind_symbolic_name T 0, %T.loc4_19.1 [symbolic = @Generic.%T (constants.%T.1)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %A.decl: type = class_decl @A [template = constants.%A] {}
 // CHECK:STDOUT:   %B.decl: type = class_decl @B [template = constants.%B] {}
@@ -330,7 +347,7 @@ fn G(T:! Generic(B)) {
 // CHECK:STDOUT:     %.loc9_19.1: type = value_of_initializer %.loc9_17 [template = constants.%.4]
 // CHECK:STDOUT:     %.loc9_19.2: type = converted %.loc9_17, %.loc9_19.1 [template = constants.%.4]
 // CHECK:STDOUT:     %T.loc9_6.1: %.4 = param T
-// CHECK:STDOUT:     @F.%T: %.4 = bind_symbolic_name T 0, %T.loc9_6.1 [symbolic = @F.%T (constants.%T.2)]
+// CHECK:STDOUT:     @F.%T.loc9: %.4 = bind_symbolic_name T 0, %T.loc9_6.1 [symbolic = @F.%T.1 (constants.%T.2)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [template = constants.%G] {
 // CHECK:STDOUT:     %Generic.ref.loc10: %Generic.type = name_ref Generic, %Generic.decl [template = constants.%Generic]
@@ -339,17 +356,24 @@ fn G(T:! Generic(B)) {
 // CHECK:STDOUT:     %.loc10_19.1: type = value_of_initializer %.loc10_17 [template = constants.%.5]
 // CHECK:STDOUT:     %.loc10_19.2: type = converted %.loc10_17, %.loc10_19.1 [template = constants.%.5]
 // CHECK:STDOUT:     %T.loc10_6.1: %.5 = param T
-// CHECK:STDOUT:     @G.%T: %.5 = bind_symbolic_name T 0, %T.loc10_6.1 [symbolic = @G.%T (constants.%T.3)]
+// CHECK:STDOUT:     @G.%T.loc10: %.5 = bind_symbolic_name T 0, %T.loc10_6.1 [symbolic = @G.%T.1 (constants.%T.3)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: interface @Generic
-// CHECK:STDOUT:     generic [file.%T.loc4_19.2: type] {
-// CHECK:STDOUT:   %Self: <unexpected>.inst+11 (%.2) = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self)]
+// CHECK:STDOUT: generic interface @Generic(file.%T.loc4_19.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T.1)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   witness = ()
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1: type = interface_type @Generic, @Generic(%T) [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:   %Self.2: %.2 = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   interface {
+// CHECK:STDOUT:     %Self.1: @Generic.%.1 (%.2) = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = %Self.1
+// CHECK:STDOUT:     witness = ()
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @A {
@@ -362,45 +386,47 @@ fn G(T:! Generic(B)) {
 // CHECK:STDOUT:   .Self = constants.%B
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F(%T: %.4)
-// CHECK:STDOUT:     generic [%T: %.4];
+// CHECK:STDOUT: generic fn @F(%T.loc9: %.4) {
+// CHECK:STDOUT:   %T.1: %.4 = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T.2)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @G(%T: %.5)
-// CHECK:STDOUT:     generic [%T: %.5] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
-// CHECK:STDOUT:   %T.ref: %.5 = name_ref T, %T [symbolic = %T (constants.%T.3)]
-// CHECK:STDOUT:   %F.call: init %.1 = call %F.ref(<invalid>) [template = <error>]
-// CHECK:STDOUT:   return
+// CHECK:STDOUT:   fn(%T.loc9: %.4);
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @G(%T.loc10: %.5) {
+// CHECK:STDOUT:   %T.1: %.5 = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T.3)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%T.loc10: %.5) {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
+// CHECK:STDOUT:     %T.ref: %.5 = name_ref T, %T.loc10 [symbolic = %T.1 (constants.%T.3)]
+// CHECK:STDOUT:     %F.call: init %.1 = call %F.ref(<invalid>) [template = <error>]
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Generic.decl(constants.%T.1) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_19.2 => constants.%T.1
+// CHECK:STDOUT: specific @Generic(constants.%T.1) {
+// CHECK:STDOUT:   %T => constants.%T.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Generic.decl(file.%T.loc4_19.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_19.2 => constants.%T.1
+// CHECK:STDOUT: specific @Generic(@Generic.%T) {
+// CHECK:STDOUT:   %T => constants.%T.1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Generic.decl(constants.%A) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_19.2 => constants.%A
+// CHECK:STDOUT: specific @Generic(constants.%A) {
+// CHECK:STDOUT:   %T => constants.%A
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%F.decl(constants.%T.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @F.%T => constants.%T.2
+// CHECK:STDOUT: specific @F(constants.%T.2) {
+// CHECK:STDOUT:   %T.1 => constants.%T.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%Generic.decl(constants.%B) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_19.2 => constants.%B
+// CHECK:STDOUT: specific @Generic(constants.%B) {
+// CHECK:STDOUT:   %T => constants.%B
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%G.decl(constants.%T.3) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @G.%T => constants.%T.3
+// CHECK:STDOUT: specific @G(constants.%T.3) {
+// CHECK:STDOUT:   %T.1 => constants.%T.3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

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

@@ -46,14 +46,14 @@ interface I {
 // CHECK:STDOUT:   %Self: %.1 = bind_symbolic_name Self 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
 // CHECK:STDOUT:     %T.loc12_8.1: type = param T
-// CHECK:STDOUT:     %T.loc12_8.2: type = bind_symbolic_name T 1, %T.loc12_8.1 [symbolic = %T.loc12_8.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc12_8.2: type = bind_symbolic_name T 1, %T.loc12_8.1 [symbolic = @F.%T.1 (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.loc12: %.3 = assoc_entity element0, %F.decl [template = constants.%.4]
 // CHECK:STDOUT:   %U: type = assoc_const_decl U [template]
 // CHECK:STDOUT:   %.loc13: %.5 = assoc_entity element1, %U [template = constants.%.6]
 // CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [template = constants.%G] {
 // CHECK:STDOUT:     %T.loc16_8.1: type = param T
-// CHECK:STDOUT:     %T.loc16_8.2: type = bind_symbolic_name T 1, %T.loc16_8.1 [symbolic = %T.loc16_8.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc16_8.2: type = bind_symbolic_name T 1, %T.loc16_8.1 [symbolic = @G.%T.1 (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.loc16: %.7 = assoc_entity element2, %G.decl [template = constants.%.8]
 // CHECK:STDOUT:
@@ -65,19 +65,23 @@ interface I {
 // CHECK:STDOUT:   witness = (%F.decl, %U, %G.decl)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F(@I.%T.loc12_8.2: type)
-// CHECK:STDOUT:     generic [@I.%Self: %.1, @I.%T.loc12_8.2: type];
+// CHECK:STDOUT: generic fn @F(@I.%Self: %.1, @I.%T.loc12_8.2: type) {
+// CHECK:STDOUT:   %T.1: type = bind_symbolic_name T 1 [symbolic = %T.1 (constants.%T)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @G(@I.%T.loc16_8.2: type)
-// CHECK:STDOUT:     generic [@I.%Self: %.1, @I.%T.loc16_8.2: type];
+// CHECK:STDOUT:   fn(@I.%T.loc12_8.2: type);
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @G(@I.%Self: %.1, @I.%T.loc16_8.2: type) {
+// CHECK:STDOUT:   %T.1: type = bind_symbolic_name T 1 [symbolic = %T.1 (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(@I.%T.loc16_8.2: type);
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @I.%F.decl(constants.%Self, constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @I.%T.loc12_8.2 => constants.%T
+// CHECK:STDOUT: specific @F(constants.%Self, constants.%T) {
+// CHECK:STDOUT:   %T.1 => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @I.%G.decl(constants.%Self, constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @I.%T.loc16_8.2 => constants.%T
+// CHECK:STDOUT: specific @G(constants.%Self, constants.%T) {
+// CHECK:STDOUT:   %T.1 => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 33 - 28
toolchain/check/testdata/interface/no_prelude/generic_import.carbon

@@ -34,7 +34,7 @@ impl C as AddWith(C) {
 // CHECK:STDOUT:   %AddWith.type: type = generic_interface_type @AddWith [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %AddWith: %AddWith.type = struct_value () [template]
-// CHECK:STDOUT:   %.2: type = interface_type @AddWith, file.%AddWith.decl(%T) [symbolic]
+// CHECK:STDOUT:   %.2: type = interface_type @AddWith, @AddWith(%T) [symbolic]
 // CHECK:STDOUT:   %Self: %.2 = bind_symbolic_name Self 1 [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
@@ -48,37 +48,42 @@ impl C as AddWith(C) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %AddWith.decl: %AddWith.type = interface_decl @AddWith [template = constants.%AddWith] {
 // CHECK:STDOUT:     %T.loc4_19.1: type = param T
-// CHECK:STDOUT:     %T.loc4_19.2: type = bind_symbolic_name T 0, %T.loc4_19.1 [symbolic = %T.loc4_19.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc4_19.2: type = bind_symbolic_name T 0, %T.loc4_19.1 [symbolic = @AddWith.%T (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: interface @AddWith
-// CHECK:STDOUT:     generic [file.%T.loc4_19.2: type] {
-// CHECK:STDOUT:   %Self: <unexpected>.inst+17 (%.2) = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self)]
-// CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {}
-// CHECK:STDOUT:   %.loc5: %.3 = assoc_entity element0, %F.decl [template = constants.%.4]
+// CHECK:STDOUT: generic interface @AddWith(file.%T.loc4_19.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = %Self
-// CHECK:STDOUT:   .F = %.loc5
-// CHECK:STDOUT:   witness = (%F.decl)
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %.1: type = interface_type @AddWith, @AddWith(%T) [symbolic = %.1 (constants.%.2)]
+// CHECK:STDOUT:   %Self.2: %.2 = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   interface {
+// CHECK:STDOUT:     %Self.1: @AddWith.%.1 (%.2) = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self)]
+// CHECK:STDOUT:     %F.decl: %F.type = fn_decl @F [template = constants.%F] {}
+// CHECK:STDOUT:     %.loc5: %.3 = assoc_entity element0, %F.decl [template = constants.%.4]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = %Self.1
+// CHECK:STDOUT:     .F = %.loc5
+// CHECK:STDOUT:     witness = (%F.decl)
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F()
-// CHECK:STDOUT:     generic [file.%T.loc4_19.2: type, @AddWith.%Self: <unexpected>.inst+17 (%.2)];
+// CHECK:STDOUT: generic fn @F(file.%T.loc4_19.2: type, @AddWith.%Self.1: @AddWith.%.1 (%.2)) {
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%AddWith.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_19.2 => constants.%T
+// CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @AddWith.%F.decl(constants.%T, constants.%Self) {
-// CHECK:STDOUT: declaration:
+// CHECK:STDOUT: specific @AddWith(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%AddWith.decl(file.%T.loc4_19.2) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_19.2 => constants.%T
+// CHECK:STDOUT: specific @F(constants.%T, constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @AddWith(@AddWith.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- b.carbon
@@ -90,9 +95,9 @@ impl C as AddWith(C) {
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %AddWith: %AddWith.type = struct_value () [template]
 // CHECK:STDOUT:   %T: type = bind_symbolic_name T 0, <unexpected>.inst+14 [symbolic]
-// CHECK:STDOUT:   %.3: type = interface_type @AddWith, <invalid>(%T) [symbolic]
+// CHECK:STDOUT:   %.3: type = interface_type @AddWith, invalid(%T) [symbolic]
 // CHECK:STDOUT:   %Self: %.3 = bind_symbolic_name Self 1 [symbolic]
-// CHECK:STDOUT:   %.4: type = interface_type @AddWith, <invalid>(%C) [template]
+// CHECK:STDOUT:   %.4: type = interface_type @AddWith, invalid(%C) [template]
 // CHECK:STDOUT:   %F.type.1: type = fn_type @F.1 [template]
 // CHECK:STDOUT:   %F.1: %F.type.1 = struct_value () [template]
 // CHECK:STDOUT:   %F.type.2: type = fn_type @F.2 [template]
@@ -102,9 +107,9 @@ impl C as AddWith(C) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %import_ref.1: %AddWith.type = import_ref Main//a, inst+4, loaded [template = constants.%AddWith]
-// CHECK:STDOUT:   %import_ref.2 = import_ref Main//a, inst+9, unloaded
-// CHECK:STDOUT:   %import_ref.3 = import_ref Main//a, inst+15, unloaded
-// CHECK:STDOUT:   %import_ref.4: %F.type.2 = import_ref Main//a, inst+11, loaded [template = constants.%F.2]
+// CHECK:STDOUT:   %import_ref.2 = import_ref Main//a, inst+10, unloaded
+// CHECK:STDOUT:   %import_ref.3 = import_ref Main//a, inst+16, unloaded
+// CHECK:STDOUT:   %import_ref.4: %F.type.2 = import_ref Main//a, inst+12, loaded [template = constants.%F.2]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -152,7 +157,7 @@ impl C as AddWith(C) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.2();
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%T);
+// CHECK:STDOUT: specific invalid(constants.%T);
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%C);
+// CHECK:STDOUT: specific invalid(constants.%C);
 // CHECK:STDOUT:

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

@@ -126,20 +126,20 @@ var f: ForwardDeclared* = &f_ref.f;
 // CHECK:STDOUT:   witness = (%T, %F.decl)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.1()
-// CHECK:STDOUT:     generic [@Basic.%Self: %.2];
+// CHECK:STDOUT: generic fn @F.1(@Basic.%Self: %.2) {
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.2()
-// CHECK:STDOUT:     generic [@ForwardDeclared.%Self: %.8];
-// CHECK:STDOUT:
-// CHECK:STDOUT: specific @Basic.%F.decl(constants.%Self.2) {
-// CHECK:STDOUT: declaration:
+// CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @ForwardDeclared.%F.decl(constants.%Self.3) {
-// CHECK:STDOUT: declaration:
+// CHECK:STDOUT: generic fn @F.2(@ForwardDeclared.%Self: %.8) {
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @F.1(constants.%Self.2) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F.2(constants.%Self.3) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: --- b.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {

+ 15 - 13
toolchain/check/testdata/interface/no_prelude/self.carbon

@@ -34,14 +34,14 @@ interface UseSelf {
 // CHECK:STDOUT: interface @UseSelf {
 // CHECK:STDOUT:   %Self: %.1 = bind_symbolic_name Self 0 [symbolic = constants.%Self]
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
-// CHECK:STDOUT:     %Self.ref.loc12_14: %.1 = name_ref Self, %Self [symbolic = %Self.ref.loc12_14 (constants.%Self)]
-// CHECK:STDOUT:     %.loc12_14.1: type = facet_type_access %Self.ref.loc12_14 [symbolic = %Self.ref.loc12_14 (constants.%Self)]
-// CHECK:STDOUT:     %.loc12_14.2: type = converted %Self.ref.loc12_14, %.loc12_14.1 [symbolic = %Self.ref.loc12_14 (constants.%Self)]
-// CHECK:STDOUT:     %self.loc12_8.1: @UseSelf.%Self.ref.loc12_14 (%Self) = param self
-// CHECK:STDOUT:     %self.loc12_8.2: @UseSelf.%Self.ref.loc12_14 (%Self) = bind_name self, %self.loc12_8.1
-// CHECK:STDOUT:     %Self.ref.loc12_25: %.1 = name_ref Self, %Self [symbolic = %Self.ref.loc12_14 (constants.%Self)]
-// CHECK:STDOUT:     %.loc12_25.1: type = facet_type_access %Self.ref.loc12_25 [symbolic = %Self.ref.loc12_14 (constants.%Self)]
-// CHECK:STDOUT:     %.loc12_25.2: type = converted %Self.ref.loc12_25, %.loc12_25.1 [symbolic = %Self.ref.loc12_14 (constants.%Self)]
+// CHECK:STDOUT:     %Self.ref.loc12_14: %.1 = name_ref Self, %Self [symbolic = @F.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc12_14.1: type = facet_type_access %Self.ref.loc12_14 [symbolic = @F.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc12_14.2: type = converted %Self.ref.loc12_14, %.loc12_14.1 [symbolic = @F.%Self (constants.%Self)]
+// CHECK:STDOUT:     %self.loc12_8.1: @F.%Self (%Self) = param self
+// CHECK:STDOUT:     %self.loc12_8.2: @F.%Self (%Self) = bind_name self, %self.loc12_8.1
+// CHECK:STDOUT:     %Self.ref.loc12_25: %.1 = name_ref Self, %Self [symbolic = @F.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc12_25.1: type = facet_type_access %Self.ref.loc12_25 [symbolic = @F.%Self (constants.%Self)]
+// CHECK:STDOUT:     %.loc12_25.2: type = converted %Self.ref.loc12_25, %.loc12_25.1 [symbolic = @F.%Self (constants.%Self)]
 // CHECK:STDOUT:     %return.var: ref %Self = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.loc12_29: %.3 = assoc_entity element0, %F.decl [template = constants.%.4]
@@ -52,11 +52,13 @@ interface UseSelf {
 // CHECK:STDOUT:   witness = (%F.decl)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F[@UseSelf.%self.loc12_8.2: @UseSelf.%Self.ref.loc12_14 (%Self)]() -> %Self
-// CHECK:STDOUT:     generic [@UseSelf.%Self: %.1];
+// CHECK:STDOUT: generic fn @F(@UseSelf.%Self: %.1) {
+// CHECK:STDOUT:   %Self: %.1 = bind_symbolic_name Self 0 [symbolic = %Self (constants.%Self)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @UseSelf.%F.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   @UseSelf.%Self.ref.loc12_14 => constants.%Self
+// CHECK:STDOUT:   fn[@UseSelf.%self.loc12_8.2: @F.%Self (%Self)]() -> %Self;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F(constants.%Self) {
+// CHECK:STDOUT:   %Self => constants.%Self
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 12 - 11
toolchain/check/testdata/interface/todo_define_not_default.carbon

@@ -118,22 +118,23 @@ interface I {
 // CHECK:STDOUT:   witness = (%F.decl, %G.decl, %T, %N)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F()
-// CHECK:STDOUT:     generic [@I.%Self: %.1] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   return
+// CHECK:STDOUT: generic fn @F(@I.%Self: %.1) {
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn() {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @G(@I.%a.loc14_8.2: i32, @I.%b.loc14_16.2: i32) -> i32 = "int.sadd"
-// CHECK:STDOUT:     generic [@I.%Self: %.1];
+// CHECK:STDOUT: generic fn @G(@I.%Self: %.1) {
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @I.%F.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
+// CHECK:STDOUT:   fn(@I.%a.loc14_8.2: i32, @I.%b.loc14_16.2: i32) -> i32 = "int.sadd";
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @I.%G.decl(constants.%Self) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT: }
+// CHECK:STDOUT: specific @F(constants.%Self) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @G(constants.%Self) {}
 // CHECK:STDOUT:

+ 12 - 8
toolchain/check/testdata/namespace/fail_params.carbon

@@ -92,7 +92,7 @@ fn D(T:! type).F() {}
 // CHECK:STDOUT:   %D: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %.decl: %.type = fn_decl @.1 [template = constants.%.2] {
 // CHECK:STDOUT:     %T.loc39_6.1: type = param T
-// CHECK:STDOUT:     %T.loc39_6.2: type = bind_symbolic_name T 0, %T.loc39_6.1 [symbolic = %T.loc39_6.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc39_6.2: type = bind_symbolic_name T 0, %T.loc39_6.1 [symbolic = @.1.%T (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -103,14 +103,18 @@ fn D(T:! type).F() {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @.1()
-// CHECK:STDOUT:     generic [file.%T.loc39_6.2: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   return
+// CHECK:STDOUT: generic fn @.1(file.%T.loc39_6.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn() {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     return
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc39_6.2 => constants.%T
+// CHECK:STDOUT: specific @.1(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

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

@@ -43,7 +43,7 @@ fn Main() -> i32 {
 // CHECK:STDOUT:   %import_ref.1: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
 // CHECK:STDOUT:   %import_ref.2: type = import_ref Core//prelude/operators/arithmetic, inst+1, loaded [template = constants.%.4]
 // CHECK:STDOUT:   %import_ref.3 = import_ref Core//prelude/operators/arithmetic, inst+3, unloaded
-// CHECK:STDOUT:   %import_ref.4: %.5 = import_ref Core//prelude/operators/arithmetic, inst+24, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.4: %.5 = import_ref Core//prelude/operators/arithmetic, inst+25, loaded [template = constants.%.6]
 // CHECK:STDOUT:   %import_ref.5 = import_ref Core//prelude/operators/arithmetic, inst+19, unloaded
 // CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/arithmetic, inst+19, unloaded
 // CHECK:STDOUT:   %import_ref.7: type = import_ref Core//prelude/operators/arithmetic, inst+1, loaded [template = constants.%.4]

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

@@ -37,7 +37,7 @@ fn Main() -> i32 {
 // CHECK:STDOUT:   %import_ref.1: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
 // CHECK:STDOUT:   %import_ref.2: type = import_ref Core//prelude/operators/arithmetic, inst+1, loaded [template = constants.%.4]
 // CHECK:STDOUT:   %import_ref.3 = import_ref Core//prelude/operators/arithmetic, inst+3, unloaded
-// CHECK:STDOUT:   %import_ref.4: %.5 = import_ref Core//prelude/operators/arithmetic, inst+24, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.4: %.5 = import_ref Core//prelude/operators/arithmetic, inst+25, loaded [template = constants.%.6]
 // CHECK:STDOUT:   %import_ref.5 = import_ref Core//prelude/operators/arithmetic, inst+19, unloaded
 // CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/arithmetic, inst+19, unloaded
 // CHECK:STDOUT: }

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

@@ -68,16 +68,16 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/arithmetic, inst+1, loaded [template = constants.%.2]
 // CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/arithmetic, inst+3, unloaded
-// CHECK:STDOUT:   %import_ref.3: %.10 = import_ref Core//prelude/operators/arithmetic, inst+24, loaded [template = constants.%.11]
+// CHECK:STDOUT:   %import_ref.3: %.10 = import_ref Core//prelude/operators/arithmetic, inst+25, loaded [template = constants.%.11]
 // CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/arithmetic, inst+19, loaded [template = constants.%Op.2]
-// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/arithmetic, inst+26, loaded [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/arithmetic, inst+28, unloaded
-// CHECK:STDOUT:   %import_ref.7: %.12 = import_ref Core//prelude/operators/arithmetic, inst+47, loaded [template = constants.%.13]
-// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/arithmetic, inst+43, loaded [template = constants.%Op.4]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/arithmetic, inst+27, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/arithmetic, inst+29, unloaded
+// CHECK:STDOUT:   %import_ref.7: %.12 = import_ref Core//prelude/operators/arithmetic, inst+50, loaded [template = constants.%.13]
+// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/arithmetic, inst+44, loaded [template = constants.%Op.4]
 // CHECK:STDOUT:   %import_ref.9: type = import_ref Core//prelude/operators/arithmetic, inst+1, loaded [template = constants.%.2]
 // CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/arithmetic, inst+19, unloaded
-// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/arithmetic, inst+26, loaded [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/arithmetic, inst+43, unloaded
+// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/arithmetic, inst+27, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/arithmetic, inst+44, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {

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

@@ -66,18 +66,18 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
-// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/bitwise, inst+21, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/bitwise, inst+23, unloaded
-// CHECK:STDOUT:   %import_ref.3: %.10 = import_ref Core//prelude/operators/bitwise, inst+43, loaded [template = constants.%.11]
-// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/bitwise, inst+39, loaded [template = constants.%Op.2]
-// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/bitwise, inst+45, loaded [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/bitwise, inst+47, unloaded
-// CHECK:STDOUT:   %import_ref.7: %.12 = import_ref Core//prelude/operators/bitwise, inst+66, loaded [template = constants.%.13]
-// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/bitwise, inst+62, loaded [template = constants.%Op.4]
-// CHECK:STDOUT:   %import_ref.9: type = import_ref Core//prelude/operators/bitwise, inst+21, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/bitwise, inst+39, unloaded
-// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/bitwise, inst+45, loaded [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/bitwise, inst+62, unloaded
+// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/bitwise, inst+22, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/bitwise, inst+24, unloaded
+// CHECK:STDOUT:   %import_ref.3: %.10 = import_ref Core//prelude/operators/bitwise, inst+45, loaded [template = constants.%.11]
+// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/bitwise, inst+40, loaded [template = constants.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/bitwise, inst+47, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/bitwise, inst+49, unloaded
+// CHECK:STDOUT:   %import_ref.7: %.12 = import_ref Core//prelude/operators/bitwise, inst+70, loaded [template = constants.%.13]
+// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/bitwise, inst+64, loaded [template = constants.%Op.4]
+// CHECK:STDOUT:   %import_ref.9: type = import_ref Core//prelude/operators/bitwise, inst+22, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/bitwise, inst+40, unloaded
+// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/bitwise, inst+47, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/bitwise, inst+64, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {

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

@@ -48,7 +48,7 @@ fn TestOp(a: C) -> C {
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/bitwise, inst+1, loaded [template = constants.%.2]
 // CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/bitwise, inst+3, unloaded
-// CHECK:STDOUT:   %import_ref.3: %.6 = import_ref Core//prelude/operators/bitwise, inst+19, loaded [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.3: %.6 = import_ref Core//prelude/operators/bitwise, inst+20, loaded [template = constants.%.7]
 // CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/bitwise, inst+14, loaded [template = constants.%Op.2]
 // CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/bitwise, inst+1, loaded [template = constants.%.2]
 // CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/bitwise, inst+14, unloaded

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

@@ -66,18 +66,18 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
-// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/bitwise, inst+68, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/bitwise, inst+70, unloaded
-// CHECK:STDOUT:   %import_ref.3: %.10 = import_ref Core//prelude/operators/bitwise, inst+90, loaded [template = constants.%.11]
-// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/bitwise, inst+86, loaded [template = constants.%Op.2]
-// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/bitwise, inst+92, loaded [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/bitwise, inst+94, unloaded
-// CHECK:STDOUT:   %import_ref.7: %.12 = import_ref Core//prelude/operators/bitwise, inst+113, loaded [template = constants.%.13]
-// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/bitwise, inst+109, loaded [template = constants.%Op.4]
-// CHECK:STDOUT:   %import_ref.9: type = import_ref Core//prelude/operators/bitwise, inst+68, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/bitwise, inst+86, unloaded
-// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/bitwise, inst+92, loaded [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/bitwise, inst+109, unloaded
+// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/bitwise, inst+72, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/bitwise, inst+74, unloaded
+// CHECK:STDOUT:   %import_ref.3: %.10 = import_ref Core//prelude/operators/bitwise, inst+95, loaded [template = constants.%.11]
+// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/bitwise, inst+90, loaded [template = constants.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/bitwise, inst+97, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/bitwise, inst+99, unloaded
+// CHECK:STDOUT:   %import_ref.7: %.12 = import_ref Core//prelude/operators/bitwise, inst+120, loaded [template = constants.%.13]
+// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/bitwise, inst+114, loaded [template = constants.%Op.4]
+// CHECK:STDOUT:   %import_ref.9: type = import_ref Core//prelude/operators/bitwise, inst+72, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/bitwise, inst+90, unloaded
+// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/bitwise, inst+97, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/bitwise, inst+114, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {

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

@@ -66,18 +66,18 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
-// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/bitwise, inst+115, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/bitwise, inst+117, unloaded
-// CHECK:STDOUT:   %import_ref.3: %.10 = import_ref Core//prelude/operators/bitwise, inst+137, loaded [template = constants.%.11]
-// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/bitwise, inst+133, loaded [template = constants.%Op.2]
-// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/bitwise, inst+139, loaded [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/bitwise, inst+141, unloaded
-// CHECK:STDOUT:   %import_ref.7: %.12 = import_ref Core//prelude/operators/bitwise, inst+160, loaded [template = constants.%.13]
-// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/bitwise, inst+156, loaded [template = constants.%Op.4]
-// CHECK:STDOUT:   %import_ref.9: type = import_ref Core//prelude/operators/bitwise, inst+115, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/bitwise, inst+133, unloaded
-// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/bitwise, inst+139, loaded [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/bitwise, inst+156, unloaded
+// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/bitwise, inst+122, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/bitwise, inst+124, unloaded
+// CHECK:STDOUT:   %import_ref.3: %.10 = import_ref Core//prelude/operators/bitwise, inst+145, loaded [template = constants.%.11]
+// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/bitwise, inst+140, loaded [template = constants.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/bitwise, inst+147, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/bitwise, inst+149, unloaded
+// CHECK:STDOUT:   %import_ref.7: %.12 = import_ref Core//prelude/operators/bitwise, inst+170, loaded [template = constants.%.13]
+// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/bitwise, inst+164, loaded [template = constants.%Op.4]
+// CHECK:STDOUT:   %import_ref.9: type = import_ref Core//prelude/operators/bitwise, inst+122, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/bitwise, inst+140, unloaded
+// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/bitwise, inst+147, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/bitwise, inst+164, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {

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

@@ -47,12 +47,12 @@ fn TestOp() {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
-// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/arithmetic, inst+133, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/arithmetic, inst+135, unloaded
-// CHECK:STDOUT:   %import_ref.3: %.8 = import_ref Core//prelude/operators/arithmetic, inst+149, loaded [template = constants.%.9]
-// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/arithmetic, inst+145, loaded [template = constants.%Op.2]
-// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/arithmetic, inst+133, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/arithmetic, inst+145, unloaded
+// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/arithmetic, inst+142, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/arithmetic, inst+144, unloaded
+// CHECK:STDOUT:   %import_ref.3: %.8 = import_ref Core//prelude/operators/arithmetic, inst+160, loaded [template = constants.%.9]
+// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/arithmetic, inst+154, loaded [template = constants.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/arithmetic, inst+142, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/arithmetic, inst+154, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {

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

@@ -66,18 +66,18 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
-// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/arithmetic, inst+198, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/arithmetic, inst+200, unloaded
-// CHECK:STDOUT:   %import_ref.3: %.10 = import_ref Core//prelude/operators/arithmetic, inst+220, loaded [template = constants.%.11]
-// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/arithmetic, inst+216, loaded [template = constants.%Op.2]
-// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/arithmetic, inst+222, loaded [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/arithmetic, inst+224, unloaded
-// CHECK:STDOUT:   %import_ref.7: %.12 = import_ref Core//prelude/operators/arithmetic, inst+243, loaded [template = constants.%.13]
-// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/arithmetic, inst+239, loaded [template = constants.%Op.4]
-// CHECK:STDOUT:   %import_ref.9: type = import_ref Core//prelude/operators/arithmetic, inst+198, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/arithmetic, inst+216, unloaded
-// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/arithmetic, inst+222, loaded [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/arithmetic, inst+239, unloaded
+// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/arithmetic, inst+212, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/arithmetic, inst+214, unloaded
+// CHECK:STDOUT:   %import_ref.3: %.10 = import_ref Core//prelude/operators/arithmetic, inst+235, loaded [template = constants.%.11]
+// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/arithmetic, inst+230, loaded [template = constants.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/arithmetic, inst+237, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/arithmetic, inst+239, unloaded
+// CHECK:STDOUT:   %import_ref.7: %.12 = import_ref Core//prelude/operators/arithmetic, inst+260, loaded [template = constants.%.13]
+// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/arithmetic, inst+254, loaded [template = constants.%Op.4]
+// CHECK:STDOUT:   %import_ref.9: type = import_ref Core//prelude/operators/arithmetic, inst+212, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/arithmetic, inst+230, unloaded
+// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/arithmetic, inst+237, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/arithmetic, inst+254, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {

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

@@ -112,10 +112,10 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/comparison, inst+3, loaded [template = constants.%.2]
 // CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/comparison, inst+5, unloaded
-// CHECK:STDOUT:   %import_ref.3: %.6 = import_ref Core//prelude/operators/comparison, inst+30, loaded [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.4: %.8 = import_ref Core//prelude/operators/comparison, inst+50, loaded [template = constants.%.9]
+// CHECK:STDOUT:   %import_ref.3: %.6 = import_ref Core//prelude/operators/comparison, inst+31, loaded [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.4: %.8 = import_ref Core//prelude/operators/comparison, inst+52, loaded [template = constants.%.9]
 // CHECK:STDOUT:   %import_ref.5: %Equal.type.2 = import_ref Core//prelude/operators/comparison, inst+26, loaded [template = constants.%Equal.2]
-// CHECK:STDOUT:   %import_ref.6: %NotEqual.type.2 = import_ref Core//prelude/operators/comparison, inst+46, loaded [template = constants.%NotEqual.2]
+// CHECK:STDOUT:   %import_ref.6: %NotEqual.type.2 = import_ref Core//prelude/operators/comparison, inst+47, loaded [template = constants.%NotEqual.2]
 // CHECK:STDOUT:   %import_ref.7: %Bool.type = import_ref Core//prelude/types/bool, inst+2, loaded [template = constants.%Bool]
 // CHECK:STDOUT:   %import_ref.8: %Bool.type = import_ref Core//prelude/types/bool, inst+2, loaded [template = constants.%Bool]
 // CHECK:STDOUT:   %import_ref.9: %Bool.type = import_ref Core//prelude/types/bool, inst+2, loaded [template = constants.%Bool]
@@ -123,7 +123,7 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT:   %import_ref.11 = import_ref Core//prelude/operators/comparison, inst+26, unloaded
 // CHECK:STDOUT:   %import_ref.12: %Bool.type = import_ref Core//prelude/types/bool, inst+2, loaded [template = constants.%Bool]
 // CHECK:STDOUT:   %import_ref.13: type = import_ref Core//prelude/operators/comparison, inst+3, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.14 = import_ref Core//prelude/operators/comparison, inst+46, unloaded
+// CHECK:STDOUT:   %import_ref.14 = import_ref Core//prelude/operators/comparison, inst+47, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -284,14 +284,14 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT:   %import_ref.1: %Bool.type = import_ref Core//prelude/types/bool, inst+2, loaded [template = constants.%Bool]
 // CHECK:STDOUT:   %import_ref.2: type = import_ref Core//prelude/operators/comparison, inst+3, loaded [template = constants.%.4]
 // CHECK:STDOUT:   %import_ref.3 = import_ref Core//prelude/operators/comparison, inst+5, unloaded
-// CHECK:STDOUT:   %import_ref.4: %.5 = import_ref Core//prelude/operators/comparison, inst+30, loaded [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.5: %.7 = import_ref Core//prelude/operators/comparison, inst+50, loaded [template = constants.%.8]
+// CHECK:STDOUT:   %import_ref.4: %.5 = import_ref Core//prelude/operators/comparison, inst+31, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.5: %.7 = import_ref Core//prelude/operators/comparison, inst+52, loaded [template = constants.%.8]
 // CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/comparison, inst+26, unloaded
-// CHECK:STDOUT:   %import_ref.7 = import_ref Core//prelude/operators/comparison, inst+46, unloaded
+// CHECK:STDOUT:   %import_ref.7 = import_ref Core//prelude/operators/comparison, inst+47, unloaded
 // CHECK:STDOUT:   %import_ref.8 = import_ref Core//prelude/operators/comparison, inst+26, unloaded
 // CHECK:STDOUT:   %import_ref.9: %Bool.type = import_ref Core//prelude/types/bool, inst+2, loaded [template = constants.%Bool]
 // CHECK:STDOUT:   %import_ref.10: type = import_ref Core//prelude/operators/comparison, inst+3, loaded [template = constants.%.4]
-// CHECK:STDOUT:   %import_ref.11 = import_ref Core//prelude/operators/comparison, inst+46, unloaded
+// CHECK:STDOUT:   %import_ref.11 = import_ref Core//prelude/operators/comparison, inst+47, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -405,10 +405,10 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/comparison, inst+3, loaded [template = constants.%.2]
 // CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/comparison, inst+5, unloaded
-// CHECK:STDOUT:   %import_ref.3: %.6 = import_ref Core//prelude/operators/comparison, inst+30, loaded [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.4: %.8 = import_ref Core//prelude/operators/comparison, inst+50, loaded [template = constants.%.9]
+// CHECK:STDOUT:   %import_ref.3: %.6 = import_ref Core//prelude/operators/comparison, inst+31, loaded [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.4: %.8 = import_ref Core//prelude/operators/comparison, inst+52, loaded [template = constants.%.9]
 // CHECK:STDOUT:   %import_ref.5: %Equal.type.2 = import_ref Core//prelude/operators/comparison, inst+26, loaded [template = constants.%Equal.2]
-// CHECK:STDOUT:   %import_ref.6: %NotEqual.type.2 = import_ref Core//prelude/operators/comparison, inst+46, loaded [template = constants.%NotEqual.2]
+// CHECK:STDOUT:   %import_ref.6: %NotEqual.type.2 = import_ref Core//prelude/operators/comparison, inst+47, loaded [template = constants.%NotEqual.2]
 // CHECK:STDOUT:   %import_ref.7: %Bool.type = import_ref Core//prelude/types/bool, inst+2, loaded [template = constants.%Bool]
 // CHECK:STDOUT:   %import_ref.8: %Bool.type = import_ref Core//prelude/types/bool, inst+2, loaded [template = constants.%Bool]
 // CHECK:STDOUT:   %import_ref.9: %Bool.type = import_ref Core//prelude/types/bool, inst+2, loaded [template = constants.%Bool]
@@ -416,7 +416,7 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT:   %import_ref.11 = import_ref Core//prelude/operators/comparison, inst+26, unloaded
 // CHECK:STDOUT:   %import_ref.12: %Bool.type = import_ref Core//prelude/types/bool, inst+2, loaded [template = constants.%Bool]
 // CHECK:STDOUT:   %import_ref.13: type = import_ref Core//prelude/operators/comparison, inst+3, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.14 = import_ref Core//prelude/operators/comparison, inst+46, unloaded
+// CHECK:STDOUT:   %import_ref.14 = import_ref Core//prelude/operators/comparison, inst+47, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {

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

@@ -75,18 +75,18 @@ fn TestAddAssignNonRef(a: C, b: C) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
-// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/arithmetic, inst+49, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/arithmetic, inst+51, unloaded
-// CHECK:STDOUT:   %import_ref.3: %.11 = import_ref Core//prelude/operators/arithmetic, inst+65, loaded [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/arithmetic, inst+61, loaded [template = constants.%Op.2]
-// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/arithmetic, inst+26, loaded [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/arithmetic, inst+28, unloaded
-// CHECK:STDOUT:   %import_ref.7: %.13 = import_ref Core//prelude/operators/arithmetic, inst+47, loaded [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/arithmetic, inst+43, loaded [template = constants.%Op.4]
-// CHECK:STDOUT:   %import_ref.9: type = import_ref Core//prelude/operators/arithmetic, inst+49, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/arithmetic, inst+61, unloaded
-// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/arithmetic, inst+26, loaded [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/arithmetic, inst+43, unloaded
+// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/arithmetic, inst+52, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/arithmetic, inst+54, unloaded
+// CHECK:STDOUT:   %import_ref.3: %.11 = import_ref Core//prelude/operators/arithmetic, inst+70, loaded [template = constants.%.12]
+// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/arithmetic, inst+64, loaded [template = constants.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/arithmetic, inst+27, loaded [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/arithmetic, inst+29, unloaded
+// CHECK:STDOUT:   %import_ref.7: %.13 = import_ref Core//prelude/operators/arithmetic, inst+50, loaded [template = constants.%.14]
+// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/arithmetic, inst+44, loaded [template = constants.%Op.4]
+// CHECK:STDOUT:   %import_ref.9: type = import_ref Core//prelude/operators/arithmetic, inst+52, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/arithmetic, inst+64, unloaded
+// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/arithmetic, inst+27, loaded [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/arithmetic, inst+44, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {

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

@@ -84,26 +84,26 @@ fn TestRef(b: C) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
-// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/arithmetic, inst+67, loaded [template = constants.%.4]
-// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/arithmetic, inst+69, unloaded
-// CHECK:STDOUT:   %import_ref.3: %.5 = import_ref Core//prelude/operators/arithmetic, inst+84, loaded [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.4 = import_ref Core//prelude/operators/arithmetic, inst+80, unloaded
-// CHECK:STDOUT:   %import_ref.5 = import_ref Core//prelude/operators/arithmetic, inst+80, unloaded
+// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/arithmetic, inst+72, loaded [template = constants.%.4]
+// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/arithmetic, inst+74, unloaded
+// CHECK:STDOUT:   %import_ref.3: %.5 = import_ref Core//prelude/operators/arithmetic, inst+90, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.4 = import_ref Core//prelude/operators/arithmetic, inst+85, unloaded
+// CHECK:STDOUT:   %import_ref.5 = import_ref Core//prelude/operators/arithmetic, inst+85, unloaded
 // CHECK:STDOUT:   %import_ref.6: type = import_ref Core//prelude/operators/arithmetic, inst+1, loaded [template = constants.%.7]
 // CHECK:STDOUT:   %import_ref.7 = import_ref Core//prelude/operators/arithmetic, inst+3, unloaded
-// CHECK:STDOUT:   %import_ref.8: %.8 = import_ref Core//prelude/operators/arithmetic, inst+24, loaded [template = constants.%.9]
+// CHECK:STDOUT:   %import_ref.8: %.8 = import_ref Core//prelude/operators/arithmetic, inst+25, loaded [template = constants.%.9]
 // CHECK:STDOUT:   %import_ref.9 = import_ref Core//prelude/operators/arithmetic, inst+19, unloaded
 // CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/arithmetic, inst+19, unloaded
-// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/arithmetic, inst+26, loaded [template = constants.%.10]
-// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/arithmetic, inst+28, unloaded
-// CHECK:STDOUT:   %import_ref.13: %.12 = import_ref Core//prelude/operators/arithmetic, inst+47, loaded [template = constants.%.13]
-// CHECK:STDOUT:   %import_ref.14 = import_ref Core//prelude/operators/arithmetic, inst+43, unloaded
-// CHECK:STDOUT:   %import_ref.15 = import_ref Core//prelude/operators/arithmetic, inst+43, unloaded
-// CHECK:STDOUT:   %import_ref.16: type = import_ref Core//prelude/operators/arithmetic, inst+49, loaded [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.17 = import_ref Core//prelude/operators/arithmetic, inst+51, unloaded
-// CHECK:STDOUT:   %import_ref.18: %.16 = import_ref Core//prelude/operators/arithmetic, inst+65, loaded [template = constants.%.17]
-// CHECK:STDOUT:   %import_ref.19 = import_ref Core//prelude/operators/arithmetic, inst+61, unloaded
-// CHECK:STDOUT:   %import_ref.20 = import_ref Core//prelude/operators/arithmetic, inst+61, unloaded
+// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/arithmetic, inst+27, loaded [template = constants.%.10]
+// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/arithmetic, inst+29, unloaded
+// CHECK:STDOUT:   %import_ref.13: %.12 = import_ref Core//prelude/operators/arithmetic, inst+50, loaded [template = constants.%.13]
+// CHECK:STDOUT:   %import_ref.14 = import_ref Core//prelude/operators/arithmetic, inst+44, unloaded
+// CHECK:STDOUT:   %import_ref.15 = import_ref Core//prelude/operators/arithmetic, inst+44, unloaded
+// CHECK:STDOUT:   %import_ref.16: type = import_ref Core//prelude/operators/arithmetic, inst+52, loaded [template = constants.%.14]
+// CHECK:STDOUT:   %import_ref.17 = import_ref Core//prelude/operators/arithmetic, inst+54, unloaded
+// CHECK:STDOUT:   %import_ref.18: %.16 = import_ref Core//prelude/operators/arithmetic, inst+70, loaded [template = constants.%.17]
+// CHECK:STDOUT:   %import_ref.19 = import_ref Core//prelude/operators/arithmetic, inst+64, unloaded
+// CHECK:STDOUT:   %import_ref.20 = import_ref Core//prelude/operators/arithmetic, inst+64, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {

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

@@ -80,16 +80,16 @@ fn TestAssign(b: D) {
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/arithmetic, inst+1, loaded [template = constants.%.2]
 // CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/arithmetic, inst+3, unloaded
-// CHECK:STDOUT:   %import_ref.3: %.10 = import_ref Core//prelude/operators/arithmetic, inst+24, loaded [template = constants.%.11]
+// CHECK:STDOUT:   %import_ref.3: %.10 = import_ref Core//prelude/operators/arithmetic, inst+25, loaded [template = constants.%.11]
 // CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/arithmetic, inst+19, loaded [template = constants.%Op.2]
-// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/arithmetic, inst+26, loaded [template = constants.%.5]
-// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/arithmetic, inst+28, unloaded
-// CHECK:STDOUT:   %import_ref.7: %.12 = import_ref Core//prelude/operators/arithmetic, inst+47, loaded [template = constants.%.13]
-// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/arithmetic, inst+43, loaded [template = constants.%Op.4]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/arithmetic, inst+27, loaded [template = constants.%.5]
+// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/arithmetic, inst+29, unloaded
+// CHECK:STDOUT:   %import_ref.7: %.12 = import_ref Core//prelude/operators/arithmetic, inst+50, loaded [template = constants.%.13]
+// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/arithmetic, inst+44, loaded [template = constants.%Op.4]
 // CHECK:STDOUT:   %import_ref.9: type = import_ref Core//prelude/operators/arithmetic, inst+1, loaded [template = constants.%.2]
 // CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/arithmetic, inst+19, unloaded
-// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/arithmetic, inst+26, loaded [template = constants.%.5]
-// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/arithmetic, inst+43, unloaded
+// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/arithmetic, inst+27, loaded [template = constants.%.5]
+// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/arithmetic, inst+44, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {

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

@@ -47,12 +47,12 @@ fn TestOp() {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
-// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/arithmetic, inst+49, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/arithmetic, inst+51, unloaded
-// CHECK:STDOUT:   %import_ref.3: %.8 = import_ref Core//prelude/operators/arithmetic, inst+65, loaded [template = constants.%.9]
-// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/arithmetic, inst+61, loaded [template = constants.%Op.2]
-// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/arithmetic, inst+49, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/arithmetic, inst+61, unloaded
+// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/arithmetic, inst+52, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/arithmetic, inst+54, unloaded
+// CHECK:STDOUT:   %import_ref.3: %.8 = import_ref Core//prelude/operators/arithmetic, inst+70, loaded [template = constants.%.9]
+// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/arithmetic, inst+64, loaded [template = constants.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/arithmetic, inst+52, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/arithmetic, inst+64, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {

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

@@ -66,18 +66,18 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
-// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/bitwise, inst+162, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/bitwise, inst+164, unloaded
-// CHECK:STDOUT:   %import_ref.3: %.10 = import_ref Core//prelude/operators/bitwise, inst+184, loaded [template = constants.%.11]
-// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/bitwise, inst+180, loaded [template = constants.%Op.2]
-// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/bitwise, inst+186, loaded [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/bitwise, inst+188, unloaded
-// CHECK:STDOUT:   %import_ref.7: %.12 = import_ref Core//prelude/operators/bitwise, inst+207, loaded [template = constants.%.13]
-// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/bitwise, inst+203, loaded [template = constants.%Op.4]
-// CHECK:STDOUT:   %import_ref.9: type = import_ref Core//prelude/operators/bitwise, inst+162, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/bitwise, inst+180, unloaded
-// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/bitwise, inst+186, loaded [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/bitwise, inst+203, unloaded
+// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/bitwise, inst+172, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/bitwise, inst+174, unloaded
+// CHECK:STDOUT:   %import_ref.3: %.10 = import_ref Core//prelude/operators/bitwise, inst+195, loaded [template = constants.%.11]
+// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/bitwise, inst+190, loaded [template = constants.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/bitwise, inst+197, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/bitwise, inst+199, unloaded
+// CHECK:STDOUT:   %import_ref.7: %.12 = import_ref Core//prelude/operators/bitwise, inst+220, loaded [template = constants.%.13]
+// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/bitwise, inst+214, loaded [template = constants.%Op.4]
+// CHECK:STDOUT:   %import_ref.9: type = import_ref Core//prelude/operators/bitwise, inst+172, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/bitwise, inst+190, unloaded
+// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/bitwise, inst+197, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/bitwise, inst+214, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {

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

@@ -66,18 +66,18 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
-// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/arithmetic, inst+245, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/arithmetic, inst+247, unloaded
-// CHECK:STDOUT:   %import_ref.3: %.10 = import_ref Core//prelude/operators/arithmetic, inst+267, loaded [template = constants.%.11]
-// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/arithmetic, inst+263, loaded [template = constants.%Op.2]
-// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/arithmetic, inst+269, loaded [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/arithmetic, inst+271, unloaded
-// CHECK:STDOUT:   %import_ref.7: %.12 = import_ref Core//prelude/operators/arithmetic, inst+290, loaded [template = constants.%.13]
-// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/arithmetic, inst+286, loaded [template = constants.%Op.4]
-// CHECK:STDOUT:   %import_ref.9: type = import_ref Core//prelude/operators/arithmetic, inst+245, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/arithmetic, inst+263, unloaded
-// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/arithmetic, inst+269, loaded [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/arithmetic, inst+286, unloaded
+// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/arithmetic, inst+262, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/arithmetic, inst+264, unloaded
+// CHECK:STDOUT:   %import_ref.3: %.10 = import_ref Core//prelude/operators/arithmetic, inst+285, loaded [template = constants.%.11]
+// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/arithmetic, inst+280, loaded [template = constants.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/arithmetic, inst+287, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/arithmetic, inst+289, unloaded
+// CHECK:STDOUT:   %import_ref.7: %.12 = import_ref Core//prelude/operators/arithmetic, inst+310, loaded [template = constants.%.13]
+// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/arithmetic, inst+304, loaded [template = constants.%Op.4]
+// CHECK:STDOUT:   %import_ref.9: type = import_ref Core//prelude/operators/arithmetic, inst+262, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/arithmetic, inst+280, unloaded
+// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/arithmetic, inst+287, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/arithmetic, inst+304, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {

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

@@ -66,18 +66,18 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
-// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/arithmetic, inst+151, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/arithmetic, inst+153, unloaded
-// CHECK:STDOUT:   %import_ref.3: %.10 = import_ref Core//prelude/operators/arithmetic, inst+173, loaded [template = constants.%.11]
-// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/arithmetic, inst+169, loaded [template = constants.%Op.2]
-// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/arithmetic, inst+175, loaded [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/arithmetic, inst+177, unloaded
-// CHECK:STDOUT:   %import_ref.7: %.12 = import_ref Core//prelude/operators/arithmetic, inst+196, loaded [template = constants.%.13]
-// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/arithmetic, inst+192, loaded [template = constants.%Op.4]
-// CHECK:STDOUT:   %import_ref.9: type = import_ref Core//prelude/operators/arithmetic, inst+151, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/arithmetic, inst+169, unloaded
-// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/arithmetic, inst+175, loaded [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/arithmetic, inst+192, unloaded
+// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/arithmetic, inst+162, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/arithmetic, inst+164, unloaded
+// CHECK:STDOUT:   %import_ref.3: %.10 = import_ref Core//prelude/operators/arithmetic, inst+185, loaded [template = constants.%.11]
+// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/arithmetic, inst+180, loaded [template = constants.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/arithmetic, inst+187, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/arithmetic, inst+189, unloaded
+// CHECK:STDOUT:   %import_ref.7: %.12 = import_ref Core//prelude/operators/arithmetic, inst+210, loaded [template = constants.%.13]
+// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/arithmetic, inst+204, loaded [template = constants.%Op.4]
+// CHECK:STDOUT:   %import_ref.9: type = import_ref Core//prelude/operators/arithmetic, inst+162, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/arithmetic, inst+180, unloaded
+// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/arithmetic, inst+187, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/arithmetic, inst+204, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {

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

@@ -46,12 +46,12 @@ fn TestOp(a: C) -> C {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
-// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/arithmetic, inst+67, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/arithmetic, inst+69, unloaded
-// CHECK:STDOUT:   %import_ref.3: %.6 = import_ref Core//prelude/operators/arithmetic, inst+84, loaded [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/arithmetic, inst+80, loaded [template = constants.%Op.2]
-// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/arithmetic, inst+67, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/arithmetic, inst+80, unloaded
+// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/arithmetic, inst+72, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/arithmetic, inst+74, unloaded
+// CHECK:STDOUT:   %import_ref.3: %.6 = import_ref Core//prelude/operators/arithmetic, inst+90, loaded [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/arithmetic, inst+85, loaded [template = constants.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/arithmetic, inst+72, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/arithmetic, inst+85, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {

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

@@ -121,32 +121,32 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
-// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/comparison, inst+52, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/comparison, inst+54, unloaded
-// CHECK:STDOUT:   %import_ref.3: %.6 = import_ref Core//prelude/operators/comparison, inst+74, loaded [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.4: %.8 = import_ref Core//prelude/operators/comparison, inst+94, loaded [template = constants.%.9]
-// CHECK:STDOUT:   %import_ref.5: %.10 = import_ref Core//prelude/operators/comparison, inst+114, loaded [template = constants.%.11]
-// CHECK:STDOUT:   %import_ref.6: %.12 = import_ref Core//prelude/operators/comparison, inst+134, loaded [template = constants.%.13]
-// CHECK:STDOUT:   %import_ref.7: %Less.type.2 = import_ref Core//prelude/operators/comparison, inst+70, loaded [template = constants.%Less.2]
-// CHECK:STDOUT:   %import_ref.8: %LessOrEquivalent.type.2 = import_ref Core//prelude/operators/comparison, inst+90, loaded [template = constants.%LessOrEquivalent.2]
-// CHECK:STDOUT:   %import_ref.9: %Greater.type.2 = import_ref Core//prelude/operators/comparison, inst+110, loaded [template = constants.%Greater.2]
-// CHECK:STDOUT:   %import_ref.10: %GreaterOrEquivalent.type.2 = import_ref Core//prelude/operators/comparison, inst+130, loaded [template = constants.%GreaterOrEquivalent.2]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/comparison, inst+54, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/comparison, inst+56, unloaded
+// CHECK:STDOUT:   %import_ref.3: %.6 = import_ref Core//prelude/operators/comparison, inst+77, loaded [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.4: %.8 = import_ref Core//prelude/operators/comparison, inst+98, loaded [template = constants.%.9]
+// CHECK:STDOUT:   %import_ref.5: %.10 = import_ref Core//prelude/operators/comparison, inst+119, loaded [template = constants.%.11]
+// CHECK:STDOUT:   %import_ref.6: %.12 = import_ref Core//prelude/operators/comparison, inst+140, loaded [template = constants.%.13]
+// CHECK:STDOUT:   %import_ref.7: %Less.type.2 = import_ref Core//prelude/operators/comparison, inst+72, loaded [template = constants.%Less.2]
+// CHECK:STDOUT:   %import_ref.8: %LessOrEquivalent.type.2 = import_ref Core//prelude/operators/comparison, inst+93, loaded [template = constants.%LessOrEquivalent.2]
+// CHECK:STDOUT:   %import_ref.9: %Greater.type.2 = import_ref Core//prelude/operators/comparison, inst+114, loaded [template = constants.%Greater.2]
+// CHECK:STDOUT:   %import_ref.10: %GreaterOrEquivalent.type.2 = import_ref Core//prelude/operators/comparison, inst+135, loaded [template = constants.%GreaterOrEquivalent.2]
 // CHECK:STDOUT:   %import_ref.11: %Bool.type = import_ref Core//prelude/types/bool, inst+2, loaded [template = constants.%Bool]
 // CHECK:STDOUT:   %import_ref.12: %Bool.type = import_ref Core//prelude/types/bool, inst+2, loaded [template = constants.%Bool]
 // CHECK:STDOUT:   %import_ref.13: %Bool.type = import_ref Core//prelude/types/bool, inst+2, loaded [template = constants.%Bool]
 // CHECK:STDOUT:   %import_ref.14: %Bool.type = import_ref Core//prelude/types/bool, inst+2, loaded [template = constants.%Bool]
 // CHECK:STDOUT:   %import_ref.15: %Bool.type = import_ref Core//prelude/types/bool, inst+2, loaded [template = constants.%Bool]
-// CHECK:STDOUT:   %import_ref.16: type = import_ref Core//prelude/operators/comparison, inst+52, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.17 = import_ref Core//prelude/operators/comparison, inst+70, unloaded
+// CHECK:STDOUT:   %import_ref.16: type = import_ref Core//prelude/operators/comparison, inst+54, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.17 = import_ref Core//prelude/operators/comparison, inst+72, unloaded
 // CHECK:STDOUT:   %import_ref.18: %Bool.type = import_ref Core//prelude/types/bool, inst+2, loaded [template = constants.%Bool]
-// CHECK:STDOUT:   %import_ref.19: type = import_ref Core//prelude/operators/comparison, inst+52, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.20 = import_ref Core//prelude/operators/comparison, inst+90, unloaded
+// CHECK:STDOUT:   %import_ref.19: type = import_ref Core//prelude/operators/comparison, inst+54, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.20 = import_ref Core//prelude/operators/comparison, inst+93, unloaded
 // CHECK:STDOUT:   %import_ref.21: %Bool.type = import_ref Core//prelude/types/bool, inst+2, loaded [template = constants.%Bool]
-// CHECK:STDOUT:   %import_ref.22: type = import_ref Core//prelude/operators/comparison, inst+52, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.23 = import_ref Core//prelude/operators/comparison, inst+110, unloaded
+// CHECK:STDOUT:   %import_ref.22: type = import_ref Core//prelude/operators/comparison, inst+54, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.23 = import_ref Core//prelude/operators/comparison, inst+114, unloaded
 // CHECK:STDOUT:   %import_ref.24: %Bool.type = import_ref Core//prelude/types/bool, inst+2, loaded [template = constants.%Bool]
-// CHECK:STDOUT:   %import_ref.25: type = import_ref Core//prelude/operators/comparison, inst+52, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.26 = import_ref Core//prelude/operators/comparison, inst+130, unloaded
+// CHECK:STDOUT:   %import_ref.25: type = import_ref Core//prelude/operators/comparison, inst+54, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.26 = import_ref Core//prelude/operators/comparison, inst+135, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -403,26 +403,26 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %import_ref.1: %Bool.type = import_ref Core//prelude/types/bool, inst+2, loaded [template = constants.%Bool]
-// CHECK:STDOUT:   %import_ref.2: type = import_ref Core//prelude/operators/comparison, inst+52, loaded [template = constants.%.4]
-// CHECK:STDOUT:   %import_ref.3 = import_ref Core//prelude/operators/comparison, inst+54, unloaded
-// CHECK:STDOUT:   %import_ref.4: %.5 = import_ref Core//prelude/operators/comparison, inst+74, loaded [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.5: %.7 = import_ref Core//prelude/operators/comparison, inst+94, loaded [template = constants.%.8]
-// CHECK:STDOUT:   %import_ref.6: %.9 = import_ref Core//prelude/operators/comparison, inst+114, loaded [template = constants.%.10]
-// CHECK:STDOUT:   %import_ref.7: %.11 = import_ref Core//prelude/operators/comparison, inst+134, loaded [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.8 = import_ref Core//prelude/operators/comparison, inst+70, unloaded
-// CHECK:STDOUT:   %import_ref.9 = import_ref Core//prelude/operators/comparison, inst+90, unloaded
-// CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/comparison, inst+110, unloaded
-// CHECK:STDOUT:   %import_ref.11 = import_ref Core//prelude/operators/comparison, inst+130, unloaded
-// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/comparison, inst+70, unloaded
+// CHECK:STDOUT:   %import_ref.2: type = import_ref Core//prelude/operators/comparison, inst+54, loaded [template = constants.%.4]
+// CHECK:STDOUT:   %import_ref.3 = import_ref Core//prelude/operators/comparison, inst+56, unloaded
+// CHECK:STDOUT:   %import_ref.4: %.5 = import_ref Core//prelude/operators/comparison, inst+77, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.5: %.7 = import_ref Core//prelude/operators/comparison, inst+98, loaded [template = constants.%.8]
+// CHECK:STDOUT:   %import_ref.6: %.9 = import_ref Core//prelude/operators/comparison, inst+119, loaded [template = constants.%.10]
+// CHECK:STDOUT:   %import_ref.7: %.11 = import_ref Core//prelude/operators/comparison, inst+140, loaded [template = constants.%.12]
+// CHECK:STDOUT:   %import_ref.8 = import_ref Core//prelude/operators/comparison, inst+72, unloaded
+// CHECK:STDOUT:   %import_ref.9 = import_ref Core//prelude/operators/comparison, inst+93, unloaded
+// CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/comparison, inst+114, unloaded
+// CHECK:STDOUT:   %import_ref.11 = import_ref Core//prelude/operators/comparison, inst+135, unloaded
+// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/comparison, inst+72, unloaded
 // CHECK:STDOUT:   %import_ref.13: %Bool.type = import_ref Core//prelude/types/bool, inst+2, loaded [template = constants.%Bool]
-// CHECK:STDOUT:   %import_ref.14: type = import_ref Core//prelude/operators/comparison, inst+52, loaded [template = constants.%.4]
-// CHECK:STDOUT:   %import_ref.15 = import_ref Core//prelude/operators/comparison, inst+90, unloaded
+// CHECK:STDOUT:   %import_ref.14: type = import_ref Core//prelude/operators/comparison, inst+54, loaded [template = constants.%.4]
+// CHECK:STDOUT:   %import_ref.15 = import_ref Core//prelude/operators/comparison, inst+93, unloaded
 // CHECK:STDOUT:   %import_ref.16: %Bool.type = import_ref Core//prelude/types/bool, inst+2, loaded [template = constants.%Bool]
-// CHECK:STDOUT:   %import_ref.17: type = import_ref Core//prelude/operators/comparison, inst+52, loaded [template = constants.%.4]
-// CHECK:STDOUT:   %import_ref.18 = import_ref Core//prelude/operators/comparison, inst+110, unloaded
+// CHECK:STDOUT:   %import_ref.17: type = import_ref Core//prelude/operators/comparison, inst+54, loaded [template = constants.%.4]
+// CHECK:STDOUT:   %import_ref.18 = import_ref Core//prelude/operators/comparison, inst+114, unloaded
 // CHECK:STDOUT:   %import_ref.19: %Bool.type = import_ref Core//prelude/types/bool, inst+2, loaded [template = constants.%Bool]
-// CHECK:STDOUT:   %import_ref.20: type = import_ref Core//prelude/operators/comparison, inst+52, loaded [template = constants.%.4]
-// CHECK:STDOUT:   %import_ref.21 = import_ref Core//prelude/operators/comparison, inst+130, unloaded
+// CHECK:STDOUT:   %import_ref.20: type = import_ref Core//prelude/operators/comparison, inst+54, loaded [template = constants.%.4]
+// CHECK:STDOUT:   %import_ref.21 = import_ref Core//prelude/operators/comparison, inst+135, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {

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

@@ -66,18 +66,18 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
-// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/bitwise, inst+209, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/bitwise, inst+211, unloaded
-// CHECK:STDOUT:   %import_ref.3: %.10 = import_ref Core//prelude/operators/bitwise, inst+231, loaded [template = constants.%.11]
-// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/bitwise, inst+227, loaded [template = constants.%Op.2]
-// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/bitwise, inst+233, loaded [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/bitwise, inst+235, unloaded
-// CHECK:STDOUT:   %import_ref.7: %.12 = import_ref Core//prelude/operators/bitwise, inst+254, loaded [template = constants.%.13]
-// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/bitwise, inst+250, loaded [template = constants.%Op.4]
-// CHECK:STDOUT:   %import_ref.9: type = import_ref Core//prelude/operators/bitwise, inst+209, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/bitwise, inst+227, unloaded
-// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/bitwise, inst+233, loaded [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/bitwise, inst+250, unloaded
+// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/bitwise, inst+222, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/bitwise, inst+224, unloaded
+// CHECK:STDOUT:   %import_ref.3: %.10 = import_ref Core//prelude/operators/bitwise, inst+245, loaded [template = constants.%.11]
+// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/bitwise, inst+240, loaded [template = constants.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/bitwise, inst+247, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/bitwise, inst+249, unloaded
+// CHECK:STDOUT:   %import_ref.7: %.12 = import_ref Core//prelude/operators/bitwise, inst+270, loaded [template = constants.%.13]
+// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/bitwise, inst+264, loaded [template = constants.%Op.4]
+// CHECK:STDOUT:   %import_ref.9: type = import_ref Core//prelude/operators/bitwise, inst+222, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/bitwise, inst+240, unloaded
+// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/bitwise, inst+247, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/bitwise, inst+264, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {

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

@@ -66,18 +66,18 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
-// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/arithmetic, inst+86, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/arithmetic, inst+88, unloaded
-// CHECK:STDOUT:   %import_ref.3: %.10 = import_ref Core//prelude/operators/arithmetic, inst+108, loaded [template = constants.%.11]
-// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/arithmetic, inst+104, loaded [template = constants.%Op.2]
-// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/arithmetic, inst+110, loaded [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/arithmetic, inst+112, unloaded
-// CHECK:STDOUT:   %import_ref.7: %.12 = import_ref Core//prelude/operators/arithmetic, inst+131, loaded [template = constants.%.13]
-// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/arithmetic, inst+127, loaded [template = constants.%Op.4]
-// CHECK:STDOUT:   %import_ref.9: type = import_ref Core//prelude/operators/arithmetic, inst+86, loaded [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/arithmetic, inst+104, unloaded
-// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/arithmetic, inst+110, loaded [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/arithmetic, inst+127, unloaded
+// CHECK:STDOUT:   %import_ref.1: type = import_ref Core//prelude/operators/arithmetic, inst+92, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2 = import_ref Core//prelude/operators/arithmetic, inst+94, unloaded
+// CHECK:STDOUT:   %import_ref.3: %.10 = import_ref Core//prelude/operators/arithmetic, inst+115, loaded [template = constants.%.11]
+// CHECK:STDOUT:   %import_ref.4: %Op.type.2 = import_ref Core//prelude/operators/arithmetic, inst+110, loaded [template = constants.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref Core//prelude/operators/arithmetic, inst+117, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.6 = import_ref Core//prelude/operators/arithmetic, inst+119, unloaded
+// CHECK:STDOUT:   %import_ref.7: %.12 = import_ref Core//prelude/operators/arithmetic, inst+140, loaded [template = constants.%.13]
+// CHECK:STDOUT:   %import_ref.8: %Op.type.4 = import_ref Core//prelude/operators/arithmetic, inst+134, loaded [template = constants.%Op.4]
+// CHECK:STDOUT:   %import_ref.9: type = import_ref Core//prelude/operators/arithmetic, inst+92, loaded [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref Core//prelude/operators/arithmetic, inst+110, unloaded
+// CHECK:STDOUT:   %import_ref.11: type = import_ref Core//prelude/operators/arithmetic, inst+117, loaded [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.12 = import_ref Core//prelude/operators/arithmetic, inst+134, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {

+ 22 - 18
toolchain/check/testdata/packages/no_prelude/fail_export_name_params.carbon

@@ -35,10 +35,10 @@ export C2(T:! type);
 // CHECK:STDOUT:   %C1.type: type = generic_class_type @C1 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %C1.1: %C1.type = struct_value () [template]
-// CHECK:STDOUT:   %C1.2: type = class_type @C1, file.%C1.decl(%T) [symbolic]
+// CHECK:STDOUT:   %C1.2: type = class_type @C1, @C1(%T) [symbolic]
 // CHECK:STDOUT:   %C2.type: type = generic_class_type @C2 [template]
 // CHECK:STDOUT:   %C2.1: %C2.type = struct_value () [template]
-// CHECK:STDOUT:   %C2.2: type = class_type @C2, file.%C2.decl(%T) [symbolic]
+// CHECK:STDOUT:   %C2.2: type = class_type @C2, @C2(%T) [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -48,28 +48,32 @@ export C2(T:! type);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %C1.decl: %C1.type = class_decl @C1 [template = constants.%C1.1] {
 // CHECK:STDOUT:     %T.loc4_10.1: type = param T
-// CHECK:STDOUT:     %T.loc4_10.2: type = bind_symbolic_name T 0, %T.loc4_10.1 [symbolic = %T.loc4_10.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc4_10.2: type = bind_symbolic_name T 0, %T.loc4_10.1 [symbolic = @C1.%T (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %C2.decl: %C2.type = class_decl @C2 [template = constants.%C2.1] {
 // CHECK:STDOUT:     %T.loc5_10.1: type = param T
-// CHECK:STDOUT:     %T.loc5_10.2: type = bind_symbolic_name T 0, %T.loc5_10.1 [symbolic = %T.loc5_10.2 (constants.%T)]
+// CHECK:STDOUT:     %T.loc5_10.2: type = bind_symbolic_name T 0, %T.loc5_10.1 [symbolic = @C2.%T (constants.%T)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @C1
-// CHECK:STDOUT:     generic [file.%T.loc4_10.2: type];
+// CHECK:STDOUT: generic class @C1(file.%T.loc4_10.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @C2
-// CHECK:STDOUT:     generic [file.%T.loc5_10.2: type];
+// CHECK:STDOUT:   class;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic class @C2(file.%T.loc5_10.2: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class;
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%C1.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc4_10.2 => constants.%T
+// CHECK:STDOUT: specific @C1(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%C2.decl(constants.%T) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%T.loc5_10.2 => constants.%T
+// CHECK:STDOUT: specific @C2(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_b.carbon
@@ -79,15 +83,15 @@ export C2(T:! type);
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %C1.1: %C1.type = struct_value () [template]
 // CHECK:STDOUT:   %T: type = bind_symbolic_name T 0, <unexpected>.inst+18 [symbolic]
-// CHECK:STDOUT:   %C1.2: type = class_type @C1, <invalid>(%T) [symbolic]
+// CHECK:STDOUT:   %C1.2: type = class_type @C1, invalid(%T) [symbolic]
 // CHECK:STDOUT:   %C2.type: type = generic_class_type @C2 [template]
 // CHECK:STDOUT:   %C2.1: %C2.type = struct_value () [template]
-// CHECK:STDOUT:   %C2.2: type = class_type @C2, <invalid>(%T) [symbolic]
+// CHECK:STDOUT:   %C2.2: type = class_type @C2, invalid(%T) [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %import_ref.1: %C1.type = import_ref Foo//a, inst+4, loaded [template = constants.%C1.1]
-// CHECK:STDOUT:   %import_ref.2: %C2.type = import_ref Foo//a, inst+11, loaded [template = constants.%C2.1]
+// CHECK:STDOUT:   %import_ref.2: %C2.type = import_ref Foo//a, inst+12, loaded [template = constants.%C2.1]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -106,5 +110,5 @@ export C2(T:! type);
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C2;
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%T);
+// CHECK:STDOUT: specific invalid(constants.%T);
 // CHECK:STDOUT:

+ 12 - 8
toolchain/check/testdata/return/fail_let_in_type.carbon

@@ -54,15 +54,19 @@ fn FirstPerfectNumber() -> z { return 6; }
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @HalfDozen() -> %y
-// CHECK:STDOUT:     generic [<unexpected>.inst+21.loc19_5: type] {
-// CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc24: i32 = int_literal 6 [template = constants.%.2]
-// CHECK:STDOUT:   return <error>
+// CHECK:STDOUT: generic fn @HalfDozen(<unexpected>.inst+21.loc19_5: type) {
+// CHECK:STDOUT:   %y: type = bind_symbolic_name y 0 [symbolic = %y (constants.%y)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn() -> %y {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %.loc24: i32 = int_literal 6 [template = constants.%.2]
+// CHECK:STDOUT:     return <error>
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <unexpected>.inst+29.loc24_21(constants.%y) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   <unexpected>.inst+27.loc24_19 => constants.%y
+// CHECK:STDOUT: specific @HalfDozen(constants.%y) {
+// CHECK:STDOUT:   %y => constants.%y
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 36 - 33
toolchain/check/testdata/struct/import.carbon

@@ -73,13 +73,13 @@ var c_bad: C({.a = 3, .b = 4}) = F();
 // CHECK:STDOUT:   %S: %.11 = bind_symbolic_name S 0 [symbolic]
 // CHECK:STDOUT:   %C.type: type = generic_class_type @C [template]
 // CHECK:STDOUT:   %C.1: %C.type = struct_value () [template]
-// CHECK:STDOUT:   %C.2: type = class_type @C, file.%C.decl(%S) [symbolic]
+// CHECK:STDOUT:   %C.2: type = class_type @C, @C(%S) [symbolic]
 // CHECK:STDOUT:   %.12: type = struct_type {} [template]
 // CHECK:STDOUT:   %.13: i32 = int_literal 1 [template]
 // CHECK:STDOUT:   %.14: i32 = int_literal 2 [template]
 // CHECK:STDOUT:   %.15: type = ptr_type %.11 [template]
 // CHECK:STDOUT:   %struct.4: %.11 = struct_value (%.13, %.14) [template]
-// CHECK:STDOUT:   %C.3: type = class_type @C, file.%C.decl(%struct.4) [template]
+// CHECK:STDOUT:   %C.3: type = class_type @C, @C(%struct.4) [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -141,7 +141,7 @@ var c_bad: C({.a = 3, .b = 4}) = F();
 // CHECK:STDOUT:     %.loc8_27.2: type = converted %int.make_type_32.loc8_27, %.loc8_27.1 [template = i32]
 // CHECK:STDOUT:     %.loc8_30: type = struct_type {.a: i32, .b: i32} [template = constants.%.11]
 // CHECK:STDOUT:     %S.loc8_9.1: %.11 = param S
-// CHECK:STDOUT:     %S.loc8_9.2: %.11 = bind_symbolic_name S 0, %S.loc8_9.1 [symbolic = %S.loc8_9.2 (constants.%S)]
+// CHECK:STDOUT:     %S.loc8_9.2: %.11 = bind_symbolic_name S 0, %S.loc8_9.1 [symbolic = @C.%S (constants.%S)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
 // CHECK:STDOUT:     %C.ref: %C.type = name_ref C, %C.decl [template = constants.%C.1]
@@ -157,10 +157,15 @@ var c_bad: C({.a = 3, .b = 4}) = F();
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @C
-// CHECK:STDOUT:     generic [file.%S.loc8_9.2: %.11] {
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%C.2
+// CHECK:STDOUT: generic class @C(file.%S.loc8_9.2: %.11) {
+// CHECK:STDOUT:   %S: %.11 = bind_symbolic_name S 0 [symbolic = %S (constants.%S)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%C.2
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
@@ -197,14 +202,12 @@ var c_bad: C({.a = 3, .b = 4}) = F();
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%C.decl(constants.%S) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%S.loc8_9.2 => constants.%S
+// CHECK:STDOUT: specific @C(constants.%S) {
+// CHECK:STDOUT:   %S => constants.%S
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%C.decl(constants.%struct.4) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%S.loc8_9.2 => constants.%struct.4
+// CHECK:STDOUT: specific @C(constants.%struct.4) {
+// CHECK:STDOUT:   %S => constants.%struct.4
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- implicit.impl.carbon
@@ -226,12 +229,12 @@ var c_bad: C({.a = 3, .b = 4}) = F();
 // CHECK:STDOUT:   %.10: type = struct_type {} [template]
 // CHECK:STDOUT:   %.11: type = struct_type {.a: i32, .b: i32} [template]
 // CHECK:STDOUT:   %S: %.11 = bind_symbolic_name S 0, <unexpected>.inst+103 [symbolic]
-// CHECK:STDOUT:   %C.2: type = class_type @C, <invalid>(%S) [symbolic]
+// CHECK:STDOUT:   %C.2: type = class_type @C, invalid(%S) [symbolic]
 // CHECK:STDOUT:   %.12: i32 = int_literal 1 [template]
 // CHECK:STDOUT:   %.13: i32 = int_literal 2 [template]
 // CHECK:STDOUT:   %.14: type = ptr_type %.11 [template]
 // CHECK:STDOUT:   %struct: %.11 = struct_value (%.12, %.13) [template]
-// CHECK:STDOUT:   %C.3: type = class_type @C, <invalid>(%struct) [template]
+// CHECK:STDOUT:   %C.3: type = class_type @C, invalid(%struct) [template]
 // CHECK:STDOUT:   %.15: type = ptr_type %.10 [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
@@ -241,12 +244,12 @@ var c_bad: C({.a = 3, .b = 4}) = F();
 // CHECK:STDOUT:   %import_ref.1: ref %.2 = import_ref Implicit//default, inst+17, loaded
 // CHECK:STDOUT:   %import_ref.2: ref %.6 = import_ref Implicit//default, inst+60, loaded
 // CHECK:STDOUT:   %import_ref.3: %C.type = import_ref Implicit//default, inst+104, loaded [template = constants.%C.1]
-// CHECK:STDOUT:   %import_ref.4: %F.type = import_ref Implicit//default, inst+126, loaded [template = constants.%F]
+// CHECK:STDOUT:   %import_ref.4: %F.type = import_ref Implicit//default, inst+127, loaded [template = constants.%F]
 // CHECK:STDOUT:   %import_ref.5: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
 // CHECK:STDOUT:   %import_ref.6: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
 // CHECK:STDOUT:   %import_ref.7: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
 // CHECK:STDOUT:   %import_ref.8: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
-// CHECK:STDOUT:   %import_ref.9 = import_ref Implicit//default, inst+107, unloaded
+// CHECK:STDOUT:   %import_ref.9 = import_ref Implicit//default, inst+108, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -353,9 +356,9 @@ var c_bad: C({.a = 3, .b = 4}) = F();
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%S);
+// CHECK:STDOUT: specific invalid(constants.%S);
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%struct);
+// CHECK:STDOUT: specific invalid(constants.%struct);
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_bad_type.impl.carbon
 // CHECK:STDOUT:
@@ -366,13 +369,13 @@ var c_bad: C({.a = 3, .b = 4}) = F();
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %.3: type = struct_type {.a: i32, .b: i32} [template]
 // CHECK:STDOUT:   %S: %.3 = bind_symbolic_name S 0, <unexpected>.inst+21 [symbolic]
-// CHECK:STDOUT:   %C.2: type = class_type @C, <invalid>(%S) [symbolic]
+// CHECK:STDOUT:   %C.2: type = class_type @C, invalid(%S) [symbolic]
 // CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
 // CHECK:STDOUT:   %.5: i32 = int_literal 2 [template]
 // CHECK:STDOUT:   %.6: type = struct_type {.c: i32, .d: i32} [template]
 // CHECK:STDOUT:   %.7: type = ptr_type %.3 [template]
 // CHECK:STDOUT:   %struct: %.3 = struct_value (%.4, %.5) [template]
-// CHECK:STDOUT:   %C.3: type = class_type @C, <invalid>(%struct) [template]
+// CHECK:STDOUT:   %C.3: type = class_type @C, invalid(%struct) [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT:   %.8: type = ptr_type %.2 [template]
@@ -382,8 +385,8 @@ var c_bad: C({.a = 3, .b = 4}) = F();
 // CHECK:STDOUT:   %import_ref.1 = import_ref Implicit//default, inst+17, unloaded
 // CHECK:STDOUT:   %import_ref.2 = import_ref Implicit//default, inst+60, unloaded
 // CHECK:STDOUT:   %import_ref.3: %C.type = import_ref Implicit//default, inst+104, loaded [template = constants.%C.1]
-// CHECK:STDOUT:   %import_ref.4: %F.type = import_ref Implicit//default, inst+126, loaded [template = constants.%F]
-// CHECK:STDOUT:   %import_ref.5 = import_ref Implicit//default, inst+107, unloaded
+// CHECK:STDOUT:   %import_ref.4: %F.type = import_ref Implicit//default, inst+127, loaded [template = constants.%F]
+// CHECK:STDOUT:   %import_ref.5 = import_ref Implicit//default, inst+108, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -434,9 +437,9 @@ var c_bad: C({.a = 3, .b = 4}) = F();
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%S);
+// CHECK:STDOUT: specific invalid(constants.%S);
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%struct);
+// CHECK:STDOUT: specific invalid(constants.%struct);
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_bad_value.impl.carbon
 // CHECK:STDOUT:
@@ -447,17 +450,17 @@ var c_bad: C({.a = 3, .b = 4}) = F();
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %.3: type = struct_type {.a: i32, .b: i32} [template]
 // CHECK:STDOUT:   %S: %.3 = bind_symbolic_name S 0, <unexpected>.inst+21 [symbolic]
-// CHECK:STDOUT:   %C.2: type = class_type @C, <invalid>(%S) [symbolic]
+// CHECK:STDOUT:   %C.2: type = class_type @C, invalid(%S) [symbolic]
 // CHECK:STDOUT:   %.4: i32 = int_literal 3 [template]
 // CHECK:STDOUT:   %.5: i32 = int_literal 4 [template]
 // CHECK:STDOUT:   %.6: type = ptr_type %.3 [template]
 // CHECK:STDOUT:   %struct.1: %.3 = struct_value (%.4, %.5) [template]
-// CHECK:STDOUT:   %C.3: type = class_type @C, <invalid>(%struct.1) [template]
+// CHECK:STDOUT:   %C.3: type = class_type @C, invalid(%struct.1) [template]
 // CHECK:STDOUT:   %.7: type = ptr_type %.2 [template]
 // CHECK:STDOUT:   %.8: i32 = int_literal 2 [template]
 // CHECK:STDOUT:   %.9: i32 = int_literal 1 [template]
 // CHECK:STDOUT:   %struct.2: %.3 = struct_value (%.9, %.8) [template]
-// CHECK:STDOUT:   %C.4: type = class_type @C, <invalid>(%struct.2) [template]
+// CHECK:STDOUT:   %C.4: type = class_type @C, invalid(%struct.2) [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -466,8 +469,8 @@ var c_bad: C({.a = 3, .b = 4}) = F();
 // CHECK:STDOUT:   %import_ref.1 = import_ref Implicit//default, inst+17, unloaded
 // CHECK:STDOUT:   %import_ref.2 = import_ref Implicit//default, inst+60, unloaded
 // CHECK:STDOUT:   %import_ref.3: %C.type = import_ref Implicit//default, inst+104, loaded [template = constants.%C.1]
-// CHECK:STDOUT:   %import_ref.4: %F.type = import_ref Implicit//default, inst+126, loaded [template = constants.%F]
-// CHECK:STDOUT:   %import_ref.5 = import_ref Implicit//default, inst+107, unloaded
+// CHECK:STDOUT:   %import_ref.4: %F.type = import_ref Implicit//default, inst+127, loaded [template = constants.%F]
+// CHECK:STDOUT:   %import_ref.5 = import_ref Implicit//default, inst+108, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -520,9 +523,9 @@ var c_bad: C({.a = 3, .b = 4}) = F();
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%S);
+// CHECK:STDOUT: specific invalid(constants.%S);
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%struct.1);
+// CHECK:STDOUT: specific invalid(constants.%struct.1);
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%struct.2);
+// CHECK:STDOUT: specific invalid(constants.%struct.2);
 // CHECK:STDOUT:

+ 36 - 33
toolchain/check/testdata/tuples/import.carbon

@@ -81,10 +81,10 @@ var c_bad: C((3, 4)) = F();
 // CHECK:STDOUT:   %X: %.9 = bind_symbolic_name X 0 [symbolic]
 // CHECK:STDOUT:   %C.type: type = generic_class_type @C [template]
 // CHECK:STDOUT:   %C.1: %C.type = struct_value () [template]
-// CHECK:STDOUT:   %C.2: type = class_type @C, file.%C.decl(%X) [symbolic]
+// CHECK:STDOUT:   %C.2: type = class_type @C, @C(%X) [symbolic]
 // CHECK:STDOUT:   %.18: type = struct_type {} [template]
 // CHECK:STDOUT:   %tuple.5: %.9 = tuple_value (%.15, %.16) [template]
-// CHECK:STDOUT:   %C.3: type = class_type @C, file.%C.decl(%tuple.5) [template]
+// CHECK:STDOUT:   %C.3: type = class_type @C, @C(%tuple.5) [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -156,7 +156,7 @@ var c_bad: C((3, 4)) = F();
 // CHECK:STDOUT:     %.loc7_22.5: type = converted %int.make_type_32.loc7_19, %.loc7_22.4 [template = i32]
 // CHECK:STDOUT:     %.loc7_22.6: type = converted %.loc7_22.1, constants.%.9 [template = constants.%.9]
 // CHECK:STDOUT:     %X.loc7_9.1: %.9 = param X
-// CHECK:STDOUT:     %X.loc7_9.2: %.9 = bind_symbolic_name X 0, %X.loc7_9.1 [symbolic = %X.loc7_9.2 (constants.%X)]
+// CHECK:STDOUT:     %X.loc7_9.2: %.9 = bind_symbolic_name X 0, %X.loc7_9.1 [symbolic = @C.%X (constants.%X)]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {
 // CHECK:STDOUT:     %C.ref: %C.type = name_ref C, %C.decl [template = constants.%C.1]
@@ -172,10 +172,15 @@ var c_bad: C((3, 4)) = F();
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @C
-// CHECK:STDOUT:     generic [file.%X.loc7_9.2: %.9] {
-// CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = constants.%C.2
+// CHECK:STDOUT: generic class @C(file.%X.loc7_9.2: %.9) {
+// CHECK:STDOUT:   %X: %.9 = bind_symbolic_name X 0 [symbolic = %X (constants.%X)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%C.2
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
@@ -219,14 +224,12 @@ var c_bad: C((3, 4)) = F();
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%C.decl(constants.%X) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%X.loc7_9.2 => constants.%X
+// CHECK:STDOUT: specific @C(constants.%X) {
+// CHECK:STDOUT:   %X => constants.%X
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific file.%C.decl(constants.%tuple.5) {
-// CHECK:STDOUT: declaration:
-// CHECK:STDOUT:   file.%X.loc7_9.2 => constants.%tuple.5
+// CHECK:STDOUT: specific @C(constants.%tuple.5) {
+// CHECK:STDOUT:   %X => constants.%tuple.5
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- implicit.impl.carbon
@@ -251,11 +254,11 @@ var c_bad: C((3, 4)) = F();
 // CHECK:STDOUT:   %C.1: %C.type = struct_value () [template]
 // CHECK:STDOUT:   %.14: type = struct_type {} [template]
 // CHECK:STDOUT:   %X: %.8 = bind_symbolic_name X 0, <unexpected>.inst+105 [symbolic]
-// CHECK:STDOUT:   %C.2: type = class_type @C, <invalid>(%X) [symbolic]
+// CHECK:STDOUT:   %C.2: type = class_type @C, invalid(%X) [symbolic]
 // CHECK:STDOUT:   %.15: i32 = int_literal 1 [template]
 // CHECK:STDOUT:   %.16: i32 = int_literal 2 [template]
 // CHECK:STDOUT:   %tuple: %.8 = tuple_value (%.15, %.16) [template]
-// CHECK:STDOUT:   %C.3: type = class_type @C, <invalid>(%tuple) [template]
+// CHECK:STDOUT:   %C.3: type = class_type @C, invalid(%tuple) [template]
 // CHECK:STDOUT:   %.17: type = ptr_type %.14 [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
@@ -265,13 +268,13 @@ var c_bad: C((3, 4)) = F();
 // CHECK:STDOUT:   %import_ref.1: ref %.3 = import_ref Implicit//default, inst+17, loaded
 // CHECK:STDOUT:   %import_ref.2: ref %.9 = import_ref Implicit//default, inst+61, loaded
 // CHECK:STDOUT:   %import_ref.3: %C.type = import_ref Implicit//default, inst+109, loaded [template = constants.%C.1]
-// CHECK:STDOUT:   %import_ref.4: %F.type = import_ref Implicit//default, inst+126, loaded [template = constants.%F]
+// CHECK:STDOUT:   %import_ref.4: %F.type = import_ref Implicit//default, inst+127, loaded [template = constants.%F]
 // CHECK:STDOUT:   %import_ref.5: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
 // CHECK:STDOUT:   %import_ref.6: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
 // CHECK:STDOUT:   %import_ref.7: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
 // CHECK:STDOUT:   %import_ref.8: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
 // CHECK:STDOUT:   %import_ref.9: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
-// CHECK:STDOUT:   %import_ref.10 = import_ref Implicit//default, inst+112, unloaded
+// CHECK:STDOUT:   %import_ref.10 = import_ref Implicit//default, inst+113, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -394,9 +397,9 @@ var c_bad: C((3, 4)) = F();
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%X);
+// CHECK:STDOUT: specific invalid(constants.%X);
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%tuple);
+// CHECK:STDOUT: specific invalid(constants.%tuple);
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_bad_type.impl.carbon
 // CHECK:STDOUT:
@@ -407,14 +410,14 @@ var c_bad: C((3, 4)) = F();
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %.3: type = tuple_type (i32, i32) [template]
 // CHECK:STDOUT:   %X: %.3 = bind_symbolic_name X 0, <unexpected>.inst+17 [symbolic]
-// CHECK:STDOUT:   %C.2: type = class_type @C, <invalid>(%X) [symbolic]
+// CHECK:STDOUT:   %C.2: type = class_type @C, invalid(%X) [symbolic]
 // CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
 // CHECK:STDOUT:   %.5: i32 = int_literal 2 [template]
 // CHECK:STDOUT:   %.6: i32 = int_literal 3 [template]
 // CHECK:STDOUT:   %.7: type = tuple_type (i32, i32, i32) [template]
 // CHECK:STDOUT:   %.8: type = ptr_type %.3 [template]
 // CHECK:STDOUT:   %tuple: %.3 = tuple_value (%.4, %.5) [template]
-// CHECK:STDOUT:   %C.3: type = class_type @C, <invalid>(%tuple) [template]
+// CHECK:STDOUT:   %C.3: type = class_type @C, invalid(%tuple) [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT:   %.9: type = ptr_type %.2 [template]
@@ -424,8 +427,8 @@ var c_bad: C((3, 4)) = F();
 // CHECK:STDOUT:   %import_ref.1 = import_ref Implicit//default, inst+17, unloaded
 // CHECK:STDOUT:   %import_ref.2 = import_ref Implicit//default, inst+61, unloaded
 // CHECK:STDOUT:   %import_ref.3: %C.type = import_ref Implicit//default, inst+109, loaded [template = constants.%C.1]
-// CHECK:STDOUT:   %import_ref.4: %F.type = import_ref Implicit//default, inst+126, loaded [template = constants.%F]
-// CHECK:STDOUT:   %import_ref.5 = import_ref Implicit//default, inst+112, unloaded
+// CHECK:STDOUT:   %import_ref.4: %F.type = import_ref Implicit//default, inst+127, loaded [template = constants.%F]
+// CHECK:STDOUT:   %import_ref.5 = import_ref Implicit//default, inst+113, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -477,9 +480,9 @@ var c_bad: C((3, 4)) = F();
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%X);
+// CHECK:STDOUT: specific invalid(constants.%X);
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%tuple);
+// CHECK:STDOUT: specific invalid(constants.%tuple);
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_bad_value.impl.carbon
 // CHECK:STDOUT:
@@ -490,17 +493,17 @@ var c_bad: C((3, 4)) = F();
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %.3: type = tuple_type (i32, i32) [template]
 // CHECK:STDOUT:   %X: %.3 = bind_symbolic_name X 0, <unexpected>.inst+17 [symbolic]
-// CHECK:STDOUT:   %C.2: type = class_type @C, <invalid>(%X) [symbolic]
+// CHECK:STDOUT:   %C.2: type = class_type @C, invalid(%X) [symbolic]
 // CHECK:STDOUT:   %.4: i32 = int_literal 3 [template]
 // CHECK:STDOUT:   %.5: i32 = int_literal 4 [template]
 // CHECK:STDOUT:   %.6: type = ptr_type %.3 [template]
 // CHECK:STDOUT:   %tuple.1: %.3 = tuple_value (%.4, %.5) [template]
-// CHECK:STDOUT:   %C.3: type = class_type @C, <invalid>(%tuple.1) [template]
+// CHECK:STDOUT:   %C.3: type = class_type @C, invalid(%tuple.1) [template]
 // CHECK:STDOUT:   %.7: type = ptr_type %.2 [template]
 // CHECK:STDOUT:   %.8: i32 = int_literal 2 [template]
 // CHECK:STDOUT:   %.9: i32 = int_literal 1 [template]
 // CHECK:STDOUT:   %tuple.2: %.3 = tuple_value (%.9, %.8) [template]
-// CHECK:STDOUT:   %C.4: type = class_type @C, <invalid>(%tuple.2) [template]
+// CHECK:STDOUT:   %C.4: type = class_type @C, invalid(%tuple.2) [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [template]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT: }
@@ -509,8 +512,8 @@ var c_bad: C((3, 4)) = F();
 // CHECK:STDOUT:   %import_ref.1 = import_ref Implicit//default, inst+17, unloaded
 // CHECK:STDOUT:   %import_ref.2 = import_ref Implicit//default, inst+61, unloaded
 // CHECK:STDOUT:   %import_ref.3: %C.type = import_ref Implicit//default, inst+109, loaded [template = constants.%C.1]
-// CHECK:STDOUT:   %import_ref.4: %F.type = import_ref Implicit//default, inst+126, loaded [template = constants.%F]
-// CHECK:STDOUT:   %import_ref.5 = import_ref Implicit//default, inst+112, unloaded
+// CHECK:STDOUT:   %import_ref.4: %F.type = import_ref Implicit//default, inst+127, loaded [template = constants.%F]
+// CHECK:STDOUT:   %import_ref.5 = import_ref Implicit//default, inst+113, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -563,9 +566,9 @@ var c_bad: C((3, 4)) = F();
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%X);
+// CHECK:STDOUT: specific invalid(constants.%X);
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%tuple.1);
+// CHECK:STDOUT: specific invalid(constants.%tuple.1);
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific <invalid>(constants.%tuple.2);
+// CHECK:STDOUT: specific invalid(constants.%tuple.2);
 // CHECK:STDOUT:

+ 111 - 97
toolchain/sem_ir/formatter.cpp

@@ -151,14 +151,6 @@ class FormatterImpl {
     Indent(-2);
   }
 
-  // Wraps the current line, prior to some text that we expect to be quite long
-  // and more readable on a separate line. This is indented two levels more than
-  // the ambient text.
-  auto WrapLine() -> void {
-    out_ << '\n';
-    Indent(4);
-  }
-
   auto FormatConstants() -> void {
     if (!sem_ir_.constants().size()) {
       return;
@@ -186,15 +178,31 @@ class FormatterImpl {
     out_ << "\n\n";
   }
 
-  auto FormatClass(ClassId id) -> void {
-    const Class& class_info = sem_ir_.classes().Get(id);
-
-    out_ << "\nclass ";
-    FormatClassName(id);
+  template <typename IdT>
+  auto FormatEntityStart(llvm::StringRef entity_kind, GenericId generic_id,
+                         IdT entity_id) -> void {
+    if (generic_id.is_valid()) {
+      FormatGenericStart(entity_kind, generic_id);
+      out_ << "\n";
+      Indent();
+      out_ << entity_kind;
+    } else {
+      out_ << "\n";
+      Indent();
+      out_ << entity_kind << " ";
+      FormatName(entity_id);
+    }
+  }
 
-    if (class_info.generic_id.is_valid()) {
-      FormatGeneric(class_info.generic_id);
+  auto FormatEntityEnd(GenericId generic_id) -> void {
+    if (generic_id.is_valid()) {
+      FormatGenericEnd();
     }
+  }
+
+  auto FormatClass(ClassId id) -> void {
+    const Class& class_info = sem_ir_.classes().Get(id);
+    FormatEntityStart("class", class_info.generic_id, id);
 
     llvm::SaveAndRestore class_scope(scope_, inst_namer_->GetScopeFor(id));
 
@@ -208,17 +216,13 @@ class FormatterImpl {
     } else {
       out_ << ";\n";
     }
+
+    FormatEntityEnd(class_info.generic_id);
   }
 
   auto FormatInterface(InterfaceId id) -> void {
     const Interface& interface_info = sem_ir_.interfaces().Get(id);
-
-    out_ << "\ninterface ";
-    FormatInterfaceName(id);
-
-    if (interface_info.generic_id.is_valid()) {
-      FormatGeneric(interface_info.generic_id);
-    }
+    FormatEntityStart("interface", interface_info.generic_id, id);
 
     llvm::SaveAndRestore interface_scope(scope_, inst_namer_->GetScopeFor(id));
 
@@ -243,13 +247,14 @@ class FormatterImpl {
     } else {
       out_ << ";\n";
     }
+
+    FormatEntityEnd(interface_info.generic_id);
   }
 
   auto FormatImpl(ImplId id) -> void {
     const Impl& impl_info = sem_ir_.impls().Get(id);
+    FormatEntityStart("impl", SemIR::GenericId::Invalid, id);
 
-    out_ << "\nimpl ";
-    FormatImplName(id);
     out_ << ": ";
     // TODO: Include the deduced parameter list if present.
     FormatType(impl_info.self_id);
@@ -283,15 +288,7 @@ class FormatterImpl {
 
   auto FormatFunction(FunctionId id) -> void {
     const Function& fn = sem_ir_.functions().Get(id);
-
-    out_ << "\n";
-
-    if (fn.is_extern) {
-      out_ << "extern ";
-    }
-
-    out_ << "fn ";
-    FormatFunctionName(id);
+    FormatEntityStart(fn.is_extern ? "extern fn" : "fn", fn.generic_id, id);
 
     llvm::SaveAndRestore function_scope(scope_, inst_namer_->GetScopeFor(id));
 
@@ -310,7 +307,7 @@ class FormatterImpl {
     if (fn.return_storage_id.is_valid()) {
       out_ << " -> ";
       if (!fn.body_block_ids.empty() && fn.has_return_slot()) {
-        FormatInstName(fn.return_storage_id);
+        FormatName(fn.return_storage_id);
         out_ << ": ";
       }
       FormatType(sem_ir_.insts().Get(fn.return_storage_id).type_id());
@@ -323,10 +320,6 @@ class FormatterImpl {
       out_ << "\"";
     }
 
-    if (fn.generic_id.is_valid()) {
-      FormatGeneric(fn.generic_id);
-    }
-
     if (!fn.body_block_ids.empty()) {
       out_ << ' ';
       OpenBrace();
@@ -344,17 +337,37 @@ class FormatterImpl {
     } else {
       out_ << ";\n";
     }
+
+    FormatEntityEnd(fn.generic_id);
   }
 
-  auto FormatGeneric(GenericId generic_id) -> void {
+  auto FormatGenericStart(llvm::StringRef entity_kind, GenericId generic_id)
+      -> void {
     const auto& generic = sem_ir_.generics().Get(generic_id);
+    out_ << "\n";
+    Indent();
+    out_ << "generic " << entity_kind << " ";
+    FormatName(generic_id);
 
-    WrapLine();
-    out_ << "generic [";
+    llvm::SaveAndRestore generic_scope(scope_,
+                                       inst_namer_->GetScopeFor(generic_id));
+
+    out_ << "(";
     FormatParamList(generic.bindings_id);
-    out_ << "]";
-    // TODO: Format at least the portions of the declaration and definition
-    // blocks that don't duplicate portions of the generic body.
+    out_ << ") ";
+
+    OpenBrace();
+    FormatCodeBlock(generic.decl_block_id);
+    if (generic.definition_block_id.is_valid()) {
+      IndentLabel();
+      out_ << "!definition:\n";
+      FormatCodeBlock(generic.definition_block_id);
+    }
+  }
+
+  auto FormatGenericEnd() -> void {
+    CloseBrace();
+    out_ << '\n';
   }
 
   auto FormatSpecificRegion(const Generic& generic,
@@ -365,15 +378,33 @@ class FormatterImpl {
       return;
     }
 
-    IndentLabel();
-    out_ << region_name << ":\n";
-    for (auto [generic_inst_id, specific_inst_id] :
-         llvm::zip(sem_ir_.inst_blocks().Get(generic.GetEvalBlock(region)),
-                   sem_ir_.inst_blocks().Get(specific.GetValueBlock(region)))) {
+    if (!region_name.empty()) {
+      IndentLabel();
+      out_ << "!" << region_name << ":\n";
+    }
+    for (auto [generic_inst_id, specific_inst_id] : llvm::zip_longest(
+             sem_ir_.inst_blocks().Get(generic.GetEvalBlock(region)),
+             sem_ir_.inst_blocks().Get(specific.GetValueBlock(region)))) {
+      if (generic_inst_id && specific_inst_id &&
+          sem_ir_.insts().Is<StructTypeField>(*generic_inst_id) &&
+          sem_ir_.insts().Is<StructTypeField>(*specific_inst_id)) {
+        // Skip printing struct type fields to match the way we print the
+        // generic.
+        continue;
+      }
+
       Indent();
-      FormatInstName(generic_inst_id);
+      if (generic_inst_id) {
+        FormatName(*generic_inst_id);
+      } else {
+        out_ << "<missing>";
+      }
       out_ << " => ";
-      FormatInstName(specific_inst_id);
+      if (specific_inst_id) {
+        FormatName(*specific_inst_id);
+      } else {
+        out_ << "<missing>";
+      }
       out_ << "\n";
     }
   }
@@ -384,7 +415,7 @@ class FormatterImpl {
     out_ << "\n";
 
     out_ << "specific ";
-    FormatSpecificName(id);
+    FormatName(id);
 
     // TODO: Remove once we stop forming generic specifics with no generic
     // during import.
@@ -395,10 +426,12 @@ class FormatterImpl {
     out_ << " ";
 
     const auto& generic = sem_ir_.generics().Get(specific.generic_id);
+    llvm::SaveAndRestore generic_scope(
+        scope_, inst_namer_->GetScopeFor(specific.generic_id));
 
     OpenBrace();
     FormatSpecificRegion(generic, specific,
-                         GenericInstIndex::Region::Declaration, "declaration");
+                         GenericInstIndex::Region::Declaration, "");
     FormatSpecificRegion(generic, specific,
                          GenericInstIndex::Region::Definition, "definition");
     CloseBrace();
@@ -418,7 +451,7 @@ class FormatterImpl {
         out_ << "addr ";
         param_id = addr->inner_id;
       }
-      FormatInstName(param_id);
+      FormatName(param_id);
       out_ << ": ";
       FormatType(sem_ir_.insts().Get(param_id).type_id());
     }
@@ -472,7 +505,7 @@ class FormatterImpl {
           break;
       }
       out_ << " = ";
-      FormatInstName(inst_id);
+      FormatName(inst_id);
       out_ << "\n";
     }
 
@@ -560,7 +593,7 @@ class FormatterImpl {
   auto FormatInstLHS(InstId inst_id, Inst inst) -> void {
     switch (inst.kind().value_kind()) {
       case InstValueKind::Typed:
-        FormatInstName(inst_id);
+        FormatName(inst_id);
         out_ << ": ";
         switch (GetExprCategory(sem_ir_, inst_id)) {
           case ExprCategory::NotExpr:
@@ -586,14 +619,14 @@ class FormatterImpl {
 
   // Format ImportDecl with its name.
   auto FormatInstLHS(InstId inst_id, ImportDecl /*inst*/) -> void {
-    FormatInstName(inst_id);
+    FormatName(inst_id);
     out_ << " = ";
   }
 
   // Print ImportRefUnloaded with type-like semantics even though it lacks a
   // type_id.
   auto FormatInstLHS(InstId inst_id, ImportRefUnloaded /*inst*/) -> void {
-    FormatInstName(inst_id);
+    FormatName(inst_id);
     out_ << " = ";
   }
 
@@ -638,7 +671,7 @@ class FormatterImpl {
       Indent();
     }
     out_ << "if ";
-    FormatInstName(inst.cond_id);
+    FormatName(inst.cond_id);
     out_ << " " << Branch::Kind.ir_name() << " ";
     FormatLabel(inst.target_id);
     out_ << " else ";
@@ -652,7 +685,7 @@ class FormatterImpl {
     out_ << BranchWithArg::Kind.ir_name() << " ";
     FormatLabel(inst.target_id);
     out_ << "(";
-    FormatInstName(inst.arg_id);
+    FormatName(inst.arg_id);
     out_ << ")\n";
     in_terminator_sequence_ = false;
   }
@@ -826,17 +859,17 @@ class FormatterImpl {
     }
   }
 
-  auto FormatArg(FunctionId id) -> void { FormatFunctionName(id); }
+  auto FormatArg(FunctionId id) -> void { FormatName(id); }
 
-  auto FormatArg(ClassId id) -> void { FormatClassName(id); }
+  auto FormatArg(ClassId id) -> void { FormatName(id); }
 
-  auto FormatArg(InterfaceId id) -> void { FormatInterfaceName(id); }
+  auto FormatArg(InterfaceId id) -> void { FormatName(id); }
 
   auto FormatArg(IntKind k) -> void { k.Print(out_); }
 
   auto FormatArg(FloatKind k) -> void { k.Print(out_); }
 
-  auto FormatArg(ImplId id) -> void { FormatImplName(id); }
+  auto FormatArg(ImplId id) -> void { FormatName(id); }
 
   auto FormatArg(ImportIRId id) -> void {
     if (!id.is_valid()) {
@@ -891,7 +924,7 @@ class FormatterImpl {
     CloseBrace();
   }
 
-  auto FormatArg(InstId id) -> void { FormatInstName(id); }
+  auto FormatArg(InstId id) -> void { FormatName(id); }
 
   auto FormatArg(InstBlockId id) -> void {
     if (!id.is_valid()) {
@@ -908,7 +941,7 @@ class FormatterImpl {
     out_ << ')';
   }
 
-  auto FormatArg(GenericInstanceId id) -> void { FormatSpecificName(id); }
+  auto FormatArg(GenericInstanceId id) -> void { FormatName(id); }
 
   auto FormatArg(RealId id) -> void {
     // TODO: Format with a `.` when the exponent is near zero.
@@ -947,44 +980,25 @@ class FormatterImpl {
     out_ << sem_ir_.names().GetFormatted(id);
   }
 
-  auto FormatInstName(InstId id) -> void {
+  auto FormatName(InstId id) -> void {
     out_ << inst_namer_->GetNameFor(scope_, id);
   }
 
-  auto FormatLabel(InstBlockId id) -> void {
-    out_ << inst_namer_->GetLabelFor(scope_, id);
-  }
-
-  auto FormatFunctionName(FunctionId id) -> void {
+  template <typename IdT>
+  auto FormatName(IdT id) -> void {
     out_ << inst_namer_->GetNameFor(id);
   }
 
-  auto FormatClassName(ClassId id) -> void {
-    out_ << inst_namer_->GetNameFor(id);
-  }
-
-  auto FormatInterfaceName(InterfaceId id) -> void {
-    out_ << inst_namer_->GetNameFor(id);
-  }
-
-  auto FormatImplName(ImplId id) -> void {
-    out_ << inst_namer_->GetNameFor(id);
-  }
-
-  auto FormatSpecificName(GenericInstanceId id) -> void {
+  auto FormatName(GenericInstanceId id) -> void {
     const auto& specific = sem_ir_.generic_instances().Get(id);
-    // TODO: We don't yet import generics properly, and instead form specifics
-    // with an invalid generic ID. In this case, just print a placeholder for
-    // now. Once import works, we can remove this code.
-    if (!specific.generic_id.is_valid()) {
-      out_ << "<invalid>";
-    } else {
-      const Generic& generic = sem_ir_.generics().Get(specific.generic_id);
-      FormatInstName(generic.decl_id);
-    }
+    FormatName(specific.generic_id);
     FormatArg(specific.args_id);
   }
 
+  auto FormatLabel(InstBlockId id) -> void {
+    out_ << inst_namer_->GetLabelFor(scope_, id);
+  }
+
   auto FormatConstant(ConstantId id) -> void {
     if (!id.is_valid()) {
       out_ << "<not constant>";
@@ -999,17 +1013,17 @@ class FormatterImpl {
       if (symbolic_constant.generic_id.is_valid()) {
         const auto& generic =
             sem_ir_.generics().Get(symbolic_constant.generic_id);
-        FormatInstName(sem_ir_.inst_blocks().Get(generic.GetEvalBlock(
+        FormatName(sem_ir_.inst_blocks().Get(generic.GetEvalBlock(
             symbolic_constant.index
                 .region()))[symbolic_constant.index.index()]);
         out_ << " (";
-        FormatInstName(sem_ir_.constant_values().GetInstId(id));
+        FormatName(sem_ir_.constant_values().GetInstId(id));
         out_ << ")";
         return;
       }
     }
 
-    FormatInstName(sem_ir_.constant_values().GetInstId(id));
+    FormatName(sem_ir_.constant_values().GetInstId(id));
   }
 
   auto FormatType(TypeId id) -> void {

+ 32 - 16
toolchain/sem_ir/inst_namer.cpp

@@ -22,9 +22,10 @@ InstNamer::InstNamer(const Lex::TokenizedBuffer& tokenized_buffer,
     : tokenized_buffer_(tokenized_buffer),
       parse_tree_(parse_tree),
       sem_ir_(sem_ir) {
-  insts.resize(sem_ir.insts().size());
-  labels.resize(sem_ir.inst_blocks().size());
-  scopes.resize(static_cast<size_t>(GetScopeFor(NumberOfScopesTag())));
+  insts_.resize(sem_ir.insts().size());
+  labels_.resize(sem_ir.inst_blocks().size());
+  scopes_.resize(static_cast<size_t>(GetScopeFor(NumberOfScopesTag())));
+  generic_scopes_.resize(sem_ir.generics().size(), ScopeId::None);
 
   // Build the constants scope.
   CollectNamesInBlock(ScopeId::Constants, sem_ir.constants().array_ref());
@@ -43,12 +44,12 @@ InstNamer::InstNamer(const Lex::TokenizedBuffer& tokenized_buffer,
     // TODO: Provide a location for the function for use as a
     // disambiguator.
     auto fn_loc = Parse::NodeId::Invalid;
-    GetScopeInfo(fn_scope).name = globals.AllocateName(
+    GetScopeInfo(fn_scope).name = globals_.AllocateName(
         *this, fn_loc, sem_ir.names().GetIRBaseName(fn.name_id).str());
     CollectNamesInBlock(fn_scope, fn.implicit_param_refs_id);
     CollectNamesInBlock(fn_scope, fn.param_refs_id);
     if (fn.return_storage_id.is_valid()) {
-      insts[fn.return_storage_id.index] = {
+      insts_[fn.return_storage_id.index] = {
           fn_scope,
           GetScopeInfo(fn_scope).insts.AllocateName(
               *this, sem_ir.insts().GetLocId(fn.return_storage_id), "return")};
@@ -62,6 +63,7 @@ InstNamer::InstNamer(const Lex::TokenizedBuffer& tokenized_buffer,
     for (auto block_id : fn.body_block_ids) {
       AddBlockLabel(fn_scope, block_id);
     }
+    CollectNamesInGeneric(fn_scope, fn.generic_id);
   }
 
   // Build each class scope.
@@ -70,11 +72,12 @@ InstNamer::InstNamer(const Lex::TokenizedBuffer& tokenized_buffer,
     auto class_scope = GetScopeFor(class_id);
     // TODO: Provide a location for the class for use as a disambiguator.
     auto class_loc = Parse::NodeId::Invalid;
-    GetScopeInfo(class_scope).name = globals.AllocateName(
+    GetScopeInfo(class_scope).name = globals_.AllocateName(
         *this, class_loc,
         sem_ir.names().GetIRBaseName(class_info.name_id).str());
     AddBlockLabel(class_scope, class_info.body_block_id, "class", class_loc);
     CollectNamesInBlock(class_scope, class_info.body_block_id);
+    CollectNamesInGeneric(class_scope, class_info.generic_id);
   }
 
   // Build each interface scope.
@@ -84,12 +87,13 @@ InstNamer::InstNamer(const Lex::TokenizedBuffer& tokenized_buffer,
     auto interface_scope = GetScopeFor(interface_id);
     // TODO: Provide a location for the interface for use as a disambiguator.
     auto interface_loc = Parse::NodeId::Invalid;
-    GetScopeInfo(interface_scope).name = globals.AllocateName(
+    GetScopeInfo(interface_scope).name = globals_.AllocateName(
         *this, interface_loc,
         sem_ir.names().GetIRBaseName(interface_info.name_id).str());
     AddBlockLabel(interface_scope, interface_info.body_block_id, "interface",
                   interface_loc);
     CollectNamesInBlock(interface_scope, interface_info.body_block_id);
+    CollectNamesInGeneric(interface_scope, interface_info.generic_id);
   }
 
   // Build each impl scope.
@@ -100,9 +104,10 @@ InstNamer::InstNamer(const Lex::TokenizedBuffer& tokenized_buffer,
     auto impl_loc = Parse::NodeId::Invalid;
     // TODO: Invent a name based on the self and constraint types.
     GetScopeInfo(impl_scope).name =
-        globals.AllocateName(*this, impl_loc, "impl");
+        globals_.AllocateName(*this, impl_loc, "impl");
     AddBlockLabel(impl_scope, impl_info.body_block_id, "impl", impl_loc);
     CollectNamesInBlock(impl_scope, impl_info.body_block_id);
+    // TODO: Collect names from the generic once we support generic impls.
   }
 }
 
@@ -129,7 +134,7 @@ auto InstNamer::GetUnscopedNameFor(InstId inst_id) const -> llvm::StringRef {
   if (!inst_id.is_valid()) {
     return "";
   }
-  const auto& inst_name = insts[inst_id.index].second;
+  const auto& inst_name = insts_[inst_id.index].second;
   return inst_name ? inst_name.str() : "";
 }
 
@@ -148,7 +153,7 @@ auto InstNamer::GetNameFor(ScopeId scope_id, InstId inst_id) const
     return "package";
   }
 
-  const auto& [inst_scope, inst_name] = insts[inst_id.index];
+  const auto& [inst_scope, inst_name] = insts_[inst_id.index];
   if (!inst_name) {
     // This should not happen in valid IR.
     std::string str;
@@ -174,7 +179,7 @@ auto InstNamer::GetUnscopedLabelFor(InstBlockId block_id) const
   if (!block_id.is_valid()) {
     return "";
   }
-  const auto& label_name = labels[block_id.index].second;
+  const auto& label_name = labels_[block_id.index].second;
   return label_name ? label_name.str() : "";
 }
 
@@ -185,7 +190,7 @@ auto InstNamer::GetLabelFor(ScopeId scope_id, InstBlockId block_id) const
     return "!invalid";
   }
 
-  const auto& [label_scope, label_name] = labels[block_id.index];
+  const auto& [label_scope, label_name] = labels_[block_id.index];
   if (!label_name) {
     // This should not happen in valid IR.
     std::string str;
@@ -271,7 +276,7 @@ auto InstNamer::Namespace::AllocateName(const InstNamer& inst_namer,
 
 auto InstNamer::AddBlockLabel(ScopeId scope_id, InstBlockId block_id,
                               std::string name, SemIR::LocId loc_id) -> void {
-  if (!block_id.is_valid() || labels[block_id.index].second) {
+  if (!block_id.is_valid() || labels_[block_id.index].second) {
     return;
   }
 
@@ -282,7 +287,7 @@ auto InstNamer::AddBlockLabel(ScopeId scope_id, InstBlockId block_id,
     }
   }
 
-  labels[block_id.index] = {
+  labels_[block_id.index] = {
       scope_id, GetScopeInfo(scope_id).labels.AllocateName(*this, loc_id,
                                                            std::move(name))};
 }
@@ -376,7 +381,7 @@ auto InstNamer::CollectNamesInBlock(ScopeId scope_id,
 
     auto untyped_inst = sem_ir_.insts().Get(inst_id);
     auto add_inst_name = [&](std::string name) {
-      insts[inst_id.index] = {
+      insts_[inst_id.index] = {
           scope_id, scope.insts.AllocateName(
                         *this, sem_ir_.insts().GetLocId(inst_id), name)};
     };
@@ -481,7 +486,7 @@ auto InstNamer::CollectNamesInBlock(ScopeId scope_id,
         auto const_id = sem_ir_.constant_values().Get(inst_id);
         if (const_id.is_valid() && const_id.is_template()) {
           auto const_inst_id = sem_ir_.constant_values().GetInstId(const_id);
-          if (!insts[const_inst_id.index].second) {
+          if (!insts_[const_inst_id.index].second) {
             CollectNamesInBlock(ScopeId::ImportRefs, const_inst_id);
           }
         }
@@ -553,4 +558,15 @@ auto InstNamer::CollectNamesInBlock(ScopeId scope_id,
   }
 }
 
+auto InstNamer::CollectNamesInGeneric(ScopeId scope_id, GenericId generic_id)
+    -> void {
+  if (!generic_id.is_valid()) {
+    return;
+  }
+  generic_scopes_[generic_id.index] = scope_id;
+  const auto& generic = sem_ir_.generics().Get(generic_id);
+  CollectNamesInBlock(scope_id, generic.decl_block_id);
+  CollectNamesInBlock(scope_id, generic.definition_block_id);
+}
+
 }  // namespace Carbon::SemIR

+ 25 - 6
toolchain/sem_ir/inst_namer.h

@@ -9,6 +9,7 @@
 #include "toolchain/lex/tokenized_buffer.h"
 #include "toolchain/parse/tree.h"
 #include "toolchain/sem_ir/file.h"
+#include "toolchain/sem_ir/ids.h"
 
 namespace Carbon::SemIR {
 
@@ -59,6 +60,12 @@ class InstNamer {
     return static_cast<ScopeId>(index);
   }
 
+  // Returns the scope ID corresponding to a generic. A generic object shares
+  // its scope with its generic entity.
+  auto GetScopeFor(GenericId id) const -> ScopeId {
+    return generic_scopes_[id.index];
+  }
+
   // Returns the IR name for the specified scope.
   auto GetScopeName(ScopeId scope) const -> std::string;
 
@@ -135,11 +142,11 @@ class InstNamer {
   };
 
   auto GetScopeInfo(ScopeId scope_id) -> Scope& {
-    return scopes[static_cast<int>(scope_id)];
+    return scopes_[static_cast<int>(scope_id)];
   }
 
   auto GetScopeInfo(ScopeId scope_id) const -> const Scope& {
-    return scopes[static_cast<int>(scope_id)];
+    return scopes_[static_cast<int>(scope_id)];
   }
 
   auto AddBlockLabel(ScopeId scope_id, InstBlockId block_id,
@@ -156,14 +163,26 @@ class InstNamer {
   auto CollectNamesInBlock(ScopeId scope_id, llvm::ArrayRef<InstId> block)
       -> void;
 
+  auto CollectNamesInGeneric(ScopeId scope_id, GenericId generic_id) -> void;
+
   const Lex::TokenizedBuffer& tokenized_buffer_;
   const Parse::Tree& parse_tree_;
   const File& sem_ir_;
 
-  Namespace globals;
-  std::vector<std::pair<ScopeId, Namespace::Name>> insts;
-  std::vector<std::pair<ScopeId, Namespace::Name>> labels;
-  std::vector<Scope> scopes;
+  // The namespace for entity names. Names within this namespace are prefixed
+  // with `@` in formatted SemIR.
+  Namespace globals_;
+  // The enclosing scope and name for each instruction, indexed by the InstId's
+  // index.
+  std::vector<std::pair<ScopeId, Namespace::Name>> insts_;
+  // The enclosing scope and name for each block that might be a branch target,
+  // indexed by the InstBlockId's index.
+  std::vector<std::pair<ScopeId, Namespace::Name>> labels_;
+  // The scopes corresponding to ScopeId values.
+  std::vector<Scope> scopes_;
+  // The scope IDs corresponding to generics. The vector indexes are the
+  // GenericId index.
+  std::vector<ScopeId> generic_scopes_;
 };
 
 }  // namespace Carbon::SemIR