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

Fix handling of member types of generic classes. (#5332)

Instead of evaluating a non-parameterized class or interface to a
constant with `SpecificId::None`, use the self specific for that class
or interface, which will not be `None` if there is an enclosing generic.
Richard Smith 1 год назад
Родитель
Сommit
89c9714825

+ 1 - 1
toolchain/check/eval.cpp

@@ -1674,7 +1674,7 @@ static auto ComputeInstPhase(Context& context, SemIR::Inst inst) -> Phase {
                         context.types().GetConstantId(inst.type_id()));
   GetConstantValueForArg(eval_context, inst.arg0_and_kind(), &phase);
   GetConstantValueForArg(eval_context, inst.arg1_and_kind(), &phase);
-  CARBON_CHECK(IsConstant(phase));
+  CARBON_CHECK(phase != Phase::Runtime);
   return phase;
 }
 

+ 15 - 9
toolchain/check/eval_inst.cpp

@@ -115,18 +115,21 @@ auto EvalConstantInst(Context& context, SemIR::ClassElementAccess inst)
 
 auto EvalConstantInst(Context& context, SemIR::ClassDecl inst)
     -> ConstantEvalResult {
+  const auto& class_info = context.classes().Get(inst.class_id);
+
   // If the class has generic parameters, we don't produce a class type, but a
   // callable whose return value is a class type.
-  if (context.classes().Get(inst.class_id).has_parameters()) {
+  if (class_info.has_parameters()) {
     return ConstantEvalResult::NewSamePhase(SemIR::StructValue{
         .type_id = inst.type_id, .elements_id = SemIR::InstBlockId::Empty});
   }
 
   // A non-generic class declaration evaluates to the class type.
-  return ConstantEvalResult::NewSamePhase(
-      SemIR::ClassType{.type_id = SemIR::TypeType::TypeId,
-                       .class_id = inst.class_id,
-                       .specific_id = SemIR::SpecificId::None});
+  return ConstantEvalResult::NewAnyPhase(SemIR::ClassType{
+      .type_id = SemIR::TypeType::TypeId,
+      .class_id = inst.class_id,
+      .specific_id =
+          context.generics().GetSelfSpecific(class_info.generic_id)});
 }
 
 auto EvalConstantInst(Context& /*context*/, SemIR::ClassInit inst)
@@ -290,16 +293,19 @@ auto EvalConstantInst(Context& context, SemIR::InstId inst_id,
 
 auto EvalConstantInst(Context& context, SemIR::InterfaceDecl inst)
     -> ConstantEvalResult {
+  const auto& interface_info = context.interfaces().Get(inst.interface_id);
+
   // If the interface has generic parameters, we don't produce an interface
   // type, but a callable whose return value is an interface type.
-  if (context.interfaces().Get(inst.interface_id).has_parameters()) {
+  if (interface_info.has_parameters()) {
     return ConstantEvalResult::NewSamePhase(SemIR::StructValue{
         .type_id = inst.type_id, .elements_id = SemIR::InstBlockId::Empty});
   }
 
-  // A non-generic interface declaration evaluates to a facet type.
-  return ConstantEvalResult::NewSamePhase(FacetTypeFromInterface(
-      context, inst.interface_id, SemIR::SpecificId::None));
+  // A non-parameterized interface declaration evaluates to a facet type.
+  return ConstantEvalResult::NewAnyPhase(FacetTypeFromInterface(
+      context, inst.interface_id,
+      context.generics().GetSelfSpecific(interface_info.generic_id)));
 }
 
 auto EvalConstantInst(Context& context, SemIR::NameRef inst)

+ 819 - 0
toolchain/check/testdata/class/generic/member_type.carbon

@@ -0,0 +1,819 @@
+// 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/class/generic/member_type.carbon
+// TIP: To dump output, run:
+// TIP:   bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/generic/member_type.carbon
+
+// --- class.carbon
+
+library "[[@TEST_NAME]]";
+
+class Outer(T:! type) {
+  class Inner {
+    var n: T;
+  }
+
+  fn F(n: T) -> Inner { return {.n = n}; }
+}
+
+fn Test() -> i32 {
+  var c: Outer(i32).Inner = Outer(i32).F(1);
+  return c.n;
+}
+
+// --- interface.carbon
+
+library "[[@TEST_NAME]]";
+
+class Outer(T:! type) {
+  interface Inner {
+    fn F[self: Self]() -> T;
+  }
+
+  class C {
+    impl as Inner {
+      fn F[self: C]() -> T { return self.(Inner.F)(); }
+    }
+  }
+}
+
+class D {
+  impl as Outer(i32).Inner {
+    fn F[self: D]() -> i32;
+  }
+}
+
+fn Test() -> i32 {
+  var c: Outer(i32).C = {};
+  return c.(Outer(i32).Inner.F)();
+}
+
+// CHECK:STDOUT: --- class.carbon
+// CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T, 0 [symbolic]
+// CHECK:STDOUT:   %T.patt: type = symbolic_binding_pattern T, 0 [symbolic]
+// CHECK:STDOUT:   %Outer.type: type = generic_class_type @Outer [concrete]
+// CHECK:STDOUT:   %Outer.generic: %Outer.type = struct_value () [concrete]
+// CHECK:STDOUT:   %Outer.9d6: type = class_type @Outer, @Outer(%T) [symbolic]
+// CHECK:STDOUT:   %Inner.51b: type = class_type @Inner, @Inner(%T) [symbolic]
+// CHECK:STDOUT:   %require_complete.4ae: <witness> = require_complete_type %T [symbolic]
+// CHECK:STDOUT:   %Inner.elem.310: type = unbound_element_type %Inner.51b, %T [symbolic]
+// CHECK:STDOUT:   %struct_type.n.848: type = struct_type {.n: %T} [symbolic]
+// CHECK:STDOUT:   %complete_type.84b: <witness> = complete_type_witness %struct_type.n.848 [symbolic]
+// CHECK:STDOUT:   %F.type.2ee: type = fn_type @F, @Outer(%T) [symbolic]
+// CHECK:STDOUT:   %F.384: %F.type.2ee = struct_value () [symbolic]
+// CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
+// CHECK:STDOUT:   %complete_type.357: <witness> = complete_type_witness %empty_struct_type [concrete]
+// CHECK:STDOUT:   %require_complete.561: <witness> = require_complete_type %Inner.51b [symbolic]
+// CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [concrete]
+// CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [concrete]
+// CHECK:STDOUT:   %Test.type: type = fn_type @Test [concrete]
+// CHECK:STDOUT:   %Test: %Test.type = struct_value () [concrete]
+// CHECK:STDOUT:   %i32.builtin: type = int_type signed, %int_32 [concrete]
+// CHECK:STDOUT:   %complete_type.f8a: <witness> = complete_type_witness %i32.builtin [concrete]
+// CHECK:STDOUT:   %Outer.545: type = class_type @Outer, @Outer(%i32) [concrete]
+// CHECK:STDOUT:   %Inner.721: type = class_type @Inner, @Inner(%i32) [concrete]
+// CHECK:STDOUT:   %F.type.9d7: type = fn_type @F, @Outer(%i32) [concrete]
+// CHECK:STDOUT:   %F.c88: %F.type.9d7 = struct_value () [concrete]
+// CHECK:STDOUT:   %Inner.elem.6c2: type = unbound_element_type %Inner.721, %i32 [concrete]
+// CHECK:STDOUT:   %struct_type.n.033: type = struct_type {.n: %i32} [concrete]
+// CHECK:STDOUT:   %complete_type.54b: <witness> = complete_type_witness %struct_type.n.033 [concrete]
+// CHECK:STDOUT:   %int_1.5b8: Core.IntLiteral = int_value 1 [concrete]
+// CHECK:STDOUT:   %F.specific_fn: <specific function> = specific_function %F.c88, @F(%i32) [concrete]
+// CHECK:STDOUT:   %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete]
+// CHECK:STDOUT:   %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete]
+// CHECK:STDOUT:   %ImplicitAs.impl_witness_table.a2f = impl_witness_table (imports.%Core.import_ref.a5b), @impl.4f9 [concrete]
+// CHECK:STDOUT:   %ImplicitAs.impl_witness.c75: <witness> = impl_witness %ImplicitAs.impl_witness_table.a2f, @impl.4f9(%int_32) [concrete]
+// CHECK:STDOUT:   %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete]
+// CHECK:STDOUT:   %Convert.956: %Convert.type.035 = struct_value () [concrete]
+// CHECK:STDOUT:   %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, (%ImplicitAs.impl_witness.c75) [concrete]
+// CHECK:STDOUT:   %.9c3: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete]
+// CHECK:STDOUT:   %Convert.bound: <bound method> = bound_method %int_1.5b8, %Convert.956 [concrete]
+// CHECK:STDOUT:   %Convert.specific_fn: <specific function> = specific_function %Convert.956, @Convert.2(%int_32) [concrete]
+// CHECK:STDOUT:   %bound_method: <bound method> = bound_method %int_1.5b8, %Convert.specific_fn [concrete]
+// CHECK:STDOUT:   %int_1.5d2: %i32 = int_value 1 [concrete]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [concrete] {
+// CHECK:STDOUT:     .Int = %Core.Int
+// CHECK:STDOUT:     .ImplicitAs = %Core.ImplicitAs
+// CHECK:STDOUT:     import Core//prelude
+// CHECK:STDOUT:     import Core//prelude/...
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: file {
+// CHECK:STDOUT:   package: <namespace> = namespace [concrete] {
+// CHECK:STDOUT:     .Core = imports.%Core
+// CHECK:STDOUT:     .Outer = %Outer.decl
+// CHECK:STDOUT:     .Test = %Test.decl
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Core.import = import Core
+// CHECK:STDOUT:   %Outer.decl: %Outer.type = class_decl @Outer [concrete = constants.%Outer.generic] {
+// CHECK:STDOUT:     %T.patt.loc4_13.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_13.2 (constants.%T.patt)]
+// CHECK:STDOUT:   } {
+// CHECK:STDOUT:     %T.loc4_13.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_13.2 (constants.%T)]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Test.decl: %Test.type = fn_decl @Test [concrete = constants.%Test] {
+// CHECK:STDOUT:     %return.patt: %i32 = return_slot_pattern
+// CHECK:STDOUT:     %return.param_patt: %i32 = out_param_pattern %return.patt, call_param0
+// CHECK:STDOUT:   } {
+// CHECK:STDOUT:     %int_32.loc12: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
+// CHECK:STDOUT:     %i32.loc12: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
+// CHECK:STDOUT:     %return.param: ref %i32 = out_param call_param0
+// CHECK:STDOUT:     %return: ref %i32 = return_slot %return.param
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic class @Outer(%T.loc4_13.1: type) {
+// CHECK:STDOUT:   %T.loc4_13.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_13.2 (constants.%T)]
+// CHECK:STDOUT:   %T.patt.loc4_13.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_13.2 (constants.%T.patt)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Inner: type = class_type @Inner, @Inner(%T.loc4_13.2) [symbolic = %Inner (constants.%Inner.51b)]
+// CHECK:STDOUT:   %F.type: type = fn_type @F, @Outer(%T.loc4_13.2) [symbolic = %F.type (constants.%F.type.2ee)]
+// CHECK:STDOUT:   %F: @Outer.%F.type (%F.type.2ee) = struct_value () [symbolic = %F (constants.%F.384)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:     %Inner.decl: type = class_decl @Inner [symbolic = @Outer.%Inner (constants.%Inner.51b)] {} {}
+// CHECK:STDOUT:     %F.decl: @Outer.%F.type (%F.type.2ee) = fn_decl @F [symbolic = @Outer.%F (constants.%F.384)] {
+// CHECK:STDOUT:       %n.patt: @F.%T (%T) = binding_pattern n
+// CHECK:STDOUT:       %n.param_patt: @F.%T (%T) = value_param_pattern %n.patt, call_param0
+// CHECK:STDOUT:       %return.patt: @F.%Inner (%Inner.51b) = return_slot_pattern
+// CHECK:STDOUT:       %return.param_patt: @F.%Inner (%Inner.51b) = out_param_pattern %return.patt, call_param1
+// CHECK:STDOUT:     } {
+// CHECK:STDOUT:       %.loc9_17: type = specific_constant @Outer.%Inner.decl, @Outer(constants.%T) [symbolic = %Inner (constants.%Inner.51b)]
+// CHECK:STDOUT:       %Inner.ref: type = name_ref Inner, %.loc9_17 [symbolic = %Inner (constants.%Inner.51b)]
+// CHECK:STDOUT:       %n.param: @F.%T (%T) = value_param call_param0
+// CHECK:STDOUT:       %T.ref: type = name_ref T, @Outer.%T.loc4_13.1 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:       %n: @F.%T (%T) = bind_name n, %n.param
+// CHECK:STDOUT:       %return.param: ref @F.%Inner (%Inner.51b) = out_param call_param1
+// CHECK:STDOUT:       %return: ref @F.%Inner (%Inner.51b) = return_slot %return.param
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type]
+// CHECK:STDOUT:     %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357]
+// CHECK:STDOUT:     complete_type_witness = %complete_type
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%Outer.9d6
+// CHECK:STDOUT:     .Inner = %Inner.decl
+// CHECK:STDOUT:     .T = <poisoned>
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic class @Inner(@Outer.%T.loc4_13.1: type) {
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %T [symbolic = %require_complete (constants.%require_complete.4ae)]
+// CHECK:STDOUT:   %Inner: type = class_type @Inner, @Inner(%T) [symbolic = %Inner (constants.%Inner.51b)]
+// CHECK:STDOUT:   %Inner.elem: type = unbound_element_type %Inner, %T [symbolic = %Inner.elem (constants.%Inner.elem.310)]
+// CHECK:STDOUT:   %struct_type.n.loc7_3.2: type = struct_type {.n: @Inner.%T (%T)} [symbolic = %struct_type.n.loc7_3.2 (constants.%struct_type.n.848)]
+// CHECK:STDOUT:   %complete_type.loc7_3.2: <witness> = complete_type_witness %struct_type.n.loc7_3.2 [symbolic = %complete_type.loc7_3.2 (constants.%complete_type.84b)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:     %.loc6_10: @Inner.%Inner.elem (%Inner.elem.310) = field_decl n, element0 [concrete]
+// CHECK:STDOUT:     name_binding_decl {
+// CHECK:STDOUT:       %.loc6_5: @Inner.%Inner.elem (%Inner.elem.310) = var_pattern %.loc6_10
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %.var: ref @Inner.%Inner.elem (%Inner.elem.310) = var <none>
+// CHECK:STDOUT:     %struct_type.n.loc7_3.1: type = struct_type {.n: %T} [symbolic = %struct_type.n.loc7_3.2 (constants.%struct_type.n.848)]
+// CHECK:STDOUT:     %complete_type.loc7_3.1: <witness> = complete_type_witness %struct_type.n.loc7_3.1 [symbolic = %complete_type.loc7_3.2 (constants.%complete_type.84b)]
+// CHECK:STDOUT:     complete_type_witness = %complete_type.loc7_3.1
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%Inner.51b
+// CHECK:STDOUT:     .T = <poisoned>
+// CHECK:STDOUT:     .n = %.loc6_10
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @F(@Outer.%T.loc4_13.1: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %Inner: type = class_type @Inner, @Inner(%T) [symbolic = %Inner (constants.%Inner.51b)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %require_complete.loc9_14: <witness> = require_complete_type %Inner [symbolic = %require_complete.loc9_14 (constants.%require_complete.561)]
+// CHECK:STDOUT:   %require_complete.loc9_9: <witness> = require_complete_type %T [symbolic = %require_complete.loc9_9 (constants.%require_complete.4ae)]
+// CHECK:STDOUT:   %struct_type.n: type = struct_type {.n: @F.%T (%T)} [symbolic = %struct_type.n (constants.%struct_type.n.848)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%n.param_patt: @F.%T (%T)) -> %return.param_patt: @F.%Inner (%Inner.51b) {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %n.ref: @F.%T (%T) = name_ref n, %n
+// CHECK:STDOUT:     %.loc9_39.1: @F.%struct_type.n (%struct_type.n.848) = struct_literal (%n.ref)
+// CHECK:STDOUT:     %.loc9_39.2: ref @F.%T (%T) = class_element_access %return, element0
+// CHECK:STDOUT:     %.loc9_39.3: init @F.%T (%T) = initialize_from %n.ref to %.loc9_39.2
+// CHECK:STDOUT:     %.loc9_39.4: init @F.%Inner (%Inner.51b) = class_init (%.loc9_39.3), %return
+// CHECK:STDOUT:     %.loc9_40: init @F.%Inner (%Inner.51b) = converted %.loc9_39.1, %.loc9_39.4
+// CHECK:STDOUT:     return %.loc9_40 to %return
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Test() -> %i32 {
+// CHECK:STDOUT: !entry:
+// CHECK:STDOUT:   name_binding_decl {
+// CHECK:STDOUT:     %c.patt: %Inner.721 = binding_pattern c
+// CHECK:STDOUT:     %.loc13_3.1: %Inner.721 = var_pattern %c.patt
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %c.var: ref %Inner.721 = var c
+// CHECK:STDOUT:   %Outer.ref.loc13_29: %Outer.type = name_ref Outer, file.%Outer.decl [concrete = constants.%Outer.generic]
+// CHECK:STDOUT:   %int_32.loc13_35: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
+// CHECK:STDOUT:   %i32.loc13_35: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
+// CHECK:STDOUT:   %Outer.loc13_38: type = class_type @Outer, @Outer(constants.%i32) [concrete = constants.%Outer.545]
+// CHECK:STDOUT:   %.loc13_39: %F.type.9d7 = specific_constant @Outer.%F.decl, @Outer(constants.%i32) [concrete = constants.%F.c88]
+// CHECK:STDOUT:   %F.ref: %F.type.9d7 = name_ref F, %.loc13_39 [concrete = constants.%F.c88]
+// CHECK:STDOUT:   %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8]
+// CHECK:STDOUT:   %F.specific_fn: <specific function> = specific_function %F.ref, @F(constants.%i32) [concrete = constants.%F.specific_fn]
+// CHECK:STDOUT:   %.loc13_3.2: ref %Inner.721 = splice_block %c.var {}
+// CHECK:STDOUT:   %impl.elem0: %.9c3 = impl_witness_access constants.%ImplicitAs.impl_witness.c75, element0 [concrete = constants.%Convert.956]
+// CHECK:STDOUT:   %bound_method.loc13_42.1: <bound method> = bound_method %int_1, %impl.elem0 [concrete = constants.%Convert.bound]
+// CHECK:STDOUT:   %specific_fn: <specific function> = specific_function %impl.elem0, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
+// CHECK:STDOUT:   %bound_method.loc13_42.2: <bound method> = bound_method %int_1, %specific_fn [concrete = constants.%bound_method]
+// CHECK:STDOUT:   %int.convert_checked: init %i32 = call %bound_method.loc13_42.2(%int_1) [concrete = constants.%int_1.5d2]
+// CHECK:STDOUT:   %.loc13_42.1: %i32 = value_of_initializer %int.convert_checked [concrete = constants.%int_1.5d2]
+// CHECK:STDOUT:   %.loc13_42.2: %i32 = converted %int_1, %.loc13_42.1 [concrete = constants.%int_1.5d2]
+// CHECK:STDOUT:   %F.call: init %Inner.721 = call %F.specific_fn(%.loc13_42.2) to %.loc13_3.2
+// CHECK:STDOUT:   assign %c.var, %F.call
+// CHECK:STDOUT:   %.loc13_20.1: type = splice_block %Inner.ref [concrete = constants.%Inner.721] {
+// CHECK:STDOUT:     %Outer.ref.loc13_10: %Outer.type = name_ref Outer, file.%Outer.decl [concrete = constants.%Outer.generic]
+// CHECK:STDOUT:     %int_32.loc13_16: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
+// CHECK:STDOUT:     %i32.loc13_16: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
+// CHECK:STDOUT:     %Outer.loc13_19: type = class_type @Outer, @Outer(constants.%i32) [concrete = constants.%Outer.545]
+// CHECK:STDOUT:     %.loc13_20.2: type = specific_constant @Outer.%Inner.decl, @Outer(constants.%i32) [concrete = constants.%Inner.721]
+// CHECK:STDOUT:     %Inner.ref: type = name_ref Inner, %.loc13_20.2 [concrete = constants.%Inner.721]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %c: ref %Inner.721 = bind_name c, %c.var
+// CHECK:STDOUT:   %c.ref: ref %Inner.721 = name_ref c, %c
+// CHECK:STDOUT:   %n.ref: %Inner.elem.6c2 = name_ref n, @Inner.%.loc6_10 [concrete = @Inner.%.loc6_10]
+// CHECK:STDOUT:   %.loc14_11.1: ref %i32 = class_element_access %c.ref, element0
+// CHECK:STDOUT:   %.loc14_11.2: %i32 = bind_value %.loc14_11.1
+// CHECK:STDOUT:   return %.loc14_11.2
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Outer(constants.%T) {
+// CHECK:STDOUT:   %T.loc4_13.2 => constants.%T
+// CHECK:STDOUT:   %T.patt.loc4_13.2 => constants.%T.patt
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Inner => constants.%Inner.51b
+// CHECK:STDOUT:   %F.type => constants.%F.type.2ee
+// CHECK:STDOUT:   %F => constants.%F.384
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Inner(constants.%T) {
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %require_complete => constants.%require_complete.4ae
+// CHECK:STDOUT:   %Inner => constants.%Inner.51b
+// CHECK:STDOUT:   %Inner.elem => constants.%Inner.elem.310
+// CHECK:STDOUT:   %struct_type.n.loc7_3.2 => constants.%struct_type.n.848
+// CHECK:STDOUT:   %complete_type.loc7_3.2 => constants.%complete_type.84b
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Inner(%T) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %Inner => constants.%Inner.51b
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Inner(@F.%T) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Inner(@Outer.%T.loc4_13.2) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Outer(%T.loc4_13.2) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Outer(constants.%i32) {
+// CHECK:STDOUT:   %T.loc4_13.2 => constants.%i32
+// CHECK:STDOUT:   %T.patt.loc4_13.2 => constants.%T.patt
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Inner => constants.%Inner.721
+// CHECK:STDOUT:   %F.type => constants.%F.type.9d7
+// CHECK:STDOUT:   %F => constants.%F.c88
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Inner(constants.%i32) {
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %T => constants.%i32
+// CHECK:STDOUT:   %require_complete => constants.%complete_type.f8a
+// CHECK:STDOUT:   %Inner => constants.%Inner.721
+// CHECK:STDOUT:   %Inner.elem => constants.%Inner.elem.6c2
+// CHECK:STDOUT:   %struct_type.n.loc7_3.2 => constants.%struct_type.n.033
+// CHECK:STDOUT:   %complete_type.loc7_3.2 => constants.%complete_type.54b
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F(constants.%i32) {
+// CHECK:STDOUT:   %T => constants.%i32
+// CHECK:STDOUT:   %Inner => constants.%Inner.721
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %require_complete.loc9_14 => constants.%complete_type.54b
+// CHECK:STDOUT:   %require_complete.loc9_9 => constants.%complete_type.f8a
+// CHECK:STDOUT:   %struct_type.n => constants.%struct_type.n.033
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: --- interface.carbon
+// CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T, 0 [symbolic]
+// CHECK:STDOUT:   %T.patt: type = symbolic_binding_pattern T, 0 [symbolic]
+// CHECK:STDOUT:   %Outer.type: type = generic_class_type @Outer [concrete]
+// CHECK:STDOUT:   %Outer.generic: %Outer.type = struct_value () [concrete]
+// CHECK:STDOUT:   %Outer.9d6: type = class_type @Outer, @Outer(%T) [symbolic]
+// CHECK:STDOUT:   %Inner.type.392: type = facet_type <@Inner, @Inner(%T)> [symbolic]
+// CHECK:STDOUT:   %Self.770: %Inner.type.392 = bind_symbolic_name Self, 1 [symbolic]
+// CHECK:STDOUT:   %Self.as_type.ea1: type = facet_access_type %Self.770 [symbolic]
+// CHECK:STDOUT:   %F.type.0f3: type = fn_type @F.1, @Inner(%T) [symbolic]
+// CHECK:STDOUT:   %F.db9: %F.type.0f3 = struct_value () [symbolic]
+// CHECK:STDOUT:   %Inner.assoc_type.115: type = assoc_entity_type @Inner, @Inner(%T) [symbolic]
+// CHECK:STDOUT:   %assoc0.95e: %Inner.assoc_type.115 = assoc_entity element0, @Inner.%F.decl [symbolic]
+// CHECK:STDOUT:   %C.390: type = class_type @C, @C(%T) [symbolic]
+// CHECK:STDOUT:   %require_complete.8fa: <witness> = require_complete_type %Inner.type.392 [symbolic]
+// CHECK:STDOUT:   %Inner.impl_witness.b15: <witness> = impl_witness @C.%Inner.impl_witness_table, @impl.eed(%T) [symbolic]
+// CHECK:STDOUT:   %F.type.77b: type = fn_type @F.2, @impl.eed(%T) [symbolic]
+// CHECK:STDOUT:   %F.ed9: %F.type.77b = struct_value () [symbolic]
+// CHECK:STDOUT:   %Inner.facet.9a3: %Inner.type.392 = facet_value %C.390, (%Inner.impl_witness.b15) [symbolic]
+// CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
+// CHECK:STDOUT:   %complete_type.357: <witness> = complete_type_witness %empty_struct_type [concrete]
+// CHECK:STDOUT:   %require_complete.4ae: <witness> = require_complete_type %T [symbolic]
+// CHECK:STDOUT:   %require_complete.930: <witness> = require_complete_type %C.390 [symbolic]
+// CHECK:STDOUT:   %Inner.lookup_impl_witness: <witness> = lookup_impl_witness %C.390, @Inner, @Inner(%T) [symbolic]
+// CHECK:STDOUT:   %Inner.facet.c18: %Inner.type.392 = facet_value %C.390, (%Inner.lookup_impl_witness) [symbolic]
+// CHECK:STDOUT:   %.692: type = fn_type_with_self_type %F.type.0f3, %Inner.facet.c18 [symbolic]
+// CHECK:STDOUT:   %impl.elem0: %.692 = impl_witness_access %Inner.lookup_impl_witness, element0 [symbolic]
+// CHECK:STDOUT:   %specific_impl_fn: <specific function> = specific_impl_function %impl.elem0, @F.1(%T, %Inner.facet.c18) [symbolic]
+// CHECK:STDOUT:   %D: type = class_type @D [concrete]
+// CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [concrete]
+// CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [concrete]
+// CHECK:STDOUT:   %Outer.545: type = class_type @Outer, @Outer(%i32) [concrete]
+// CHECK:STDOUT:   %Inner.type.52d: type = facet_type <@Inner, @Inner(%i32)> [concrete]
+// CHECK:STDOUT:   %C.70f: type = class_type @C, @C(%i32) [concrete]
+// CHECK:STDOUT:   %Self.493: %Inner.type.52d = bind_symbolic_name Self, 1 [symbolic]
+// CHECK:STDOUT:   %F.type.86e: type = fn_type @F.1, @Inner(%i32) [concrete]
+// CHECK:STDOUT:   %F.11d: %F.type.86e = struct_value () [concrete]
+// CHECK:STDOUT:   %Inner.assoc_type.215: type = assoc_entity_type @Inner, @Inner(%i32) [concrete]
+// CHECK:STDOUT:   %assoc0.e80: %Inner.assoc_type.215 = assoc_entity element0, @Inner.%F.decl [concrete]
+// CHECK:STDOUT:   %Inner.impl_witness.1dc: <witness> = impl_witness @D.%Inner.impl_witness_table [concrete]
+// CHECK:STDOUT:   %F.type.a78: type = fn_type @F.3 [concrete]
+// CHECK:STDOUT:   %F.a24: %F.type.a78 = struct_value () [concrete]
+// CHECK:STDOUT:   %Inner.facet.edc: %Inner.type.52d = facet_value %D, (%Inner.impl_witness.1dc) [concrete]
+// CHECK:STDOUT:   %Test.type: type = fn_type @Test [concrete]
+// CHECK:STDOUT:   %Test: %Test.type = struct_value () [concrete]
+// CHECK:STDOUT:   %i32.builtin: type = int_type signed, %int_32 [concrete]
+// CHECK:STDOUT:   %complete_type.f8a: <witness> = complete_type_witness %i32.builtin [concrete]
+// CHECK:STDOUT:   %C.val: %C.70f = struct_value () [concrete]
+// CHECK:STDOUT:   %complete_type.9fa: <witness> = complete_type_witness %Inner.type.52d [concrete]
+// CHECK:STDOUT:   %Inner.impl_witness.47d: <witness> = impl_witness @C.%Inner.impl_witness_table, @impl.eed(%i32) [concrete]
+// CHECK:STDOUT:   %F.type.f11: type = fn_type @F.2, @impl.eed(%i32) [concrete]
+// CHECK:STDOUT:   %F.e75: %F.type.f11 = struct_value () [concrete]
+// CHECK:STDOUT:   %Inner.facet.840: %Inner.type.52d = facet_value %C.70f, (%Inner.impl_witness.47d) [concrete]
+// CHECK:STDOUT:   %.b10: type = fn_type_with_self_type %F.type.86e, %Inner.facet.840 [concrete]
+// CHECK:STDOUT:   %F.specific_fn: <specific function> = specific_function %F.e75, @F.2(%i32) [concrete]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [concrete] {
+// CHECK:STDOUT:     .Int = %Core.Int
+// CHECK:STDOUT:     import Core//prelude
+// CHECK:STDOUT:     import Core//prelude/...
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: file {
+// CHECK:STDOUT:   package: <namespace> = namespace [concrete] {
+// CHECK:STDOUT:     .Core = imports.%Core
+// CHECK:STDOUT:     .Outer = %Outer.decl
+// CHECK:STDOUT:     .D = %D.decl
+// CHECK:STDOUT:     .Test = %Test.decl
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Core.import = import Core
+// CHECK:STDOUT:   %Outer.decl: %Outer.type = class_decl @Outer [concrete = constants.%Outer.generic] {
+// CHECK:STDOUT:     %T.patt.loc4_13.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_13.2 (constants.%T.patt)]
+// CHECK:STDOUT:   } {
+// CHECK:STDOUT:     %T.loc4_13.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_13.2 (constants.%T)]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %D.decl: type = class_decl @D [concrete = constants.%D] {} {}
+// CHECK:STDOUT:   %Test.decl: %Test.type = fn_decl @Test [concrete = constants.%Test] {
+// CHECK:STDOUT:     %return.patt: %i32 = return_slot_pattern
+// CHECK:STDOUT:     %return.param_patt: %i32 = out_param_pattern %return.patt, call_param0
+// CHECK:STDOUT:   } {
+// CHECK:STDOUT:     %int_32.loc22: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
+// CHECK:STDOUT:     %i32.loc22: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
+// CHECK:STDOUT:     %return.param: ref %i32 = out_param call_param0
+// CHECK:STDOUT:     %return: ref %i32 = return_slot %return.param
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic interface @Inner(@Outer.%T.loc4_13.1: type) {
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %Inner.type: type = facet_type <@Inner, @Inner(%T)> [symbolic = %Inner.type (constants.%Inner.type.392)]
+// CHECK:STDOUT:   %Self.2: @Inner.%Inner.type (%Inner.type.392) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self.770)]
+// CHECK:STDOUT:   %F.type: type = fn_type @F.1, @Inner(%T) [symbolic = %F.type (constants.%F.type.0f3)]
+// CHECK:STDOUT:   %F: @Inner.%F.type (%F.type.0f3) = struct_value () [symbolic = %F (constants.%F.db9)]
+// CHECK:STDOUT:   %Inner.assoc_type: type = assoc_entity_type @Inner, @Inner(%T) [symbolic = %Inner.assoc_type (constants.%Inner.assoc_type.115)]
+// CHECK:STDOUT:   %assoc0.loc6_28.2: @Inner.%Inner.assoc_type (%Inner.assoc_type.115) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc6_28.2 (constants.%assoc0.95e)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   interface {
+// CHECK:STDOUT:     %Self.1: @Inner.%Inner.type (%Inner.type.392) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self.770)]
+// CHECK:STDOUT:     %F.decl: @Inner.%F.type (%F.type.0f3) = fn_decl @F.1 [symbolic = @Inner.%F (constants.%F.db9)] {
+// CHECK:STDOUT:       %self.patt: @F.1.%Self.as_type.loc6_16.1 (%Self.as_type.ea1) = binding_pattern self
+// CHECK:STDOUT:       %self.param_patt: @F.1.%Self.as_type.loc6_16.1 (%Self.as_type.ea1) = value_param_pattern %self.patt, call_param0
+// CHECK:STDOUT:       %return.patt: @F.1.%T (%T) = return_slot_pattern
+// CHECK:STDOUT:       %return.param_patt: @F.1.%T (%T) = out_param_pattern %return.patt, call_param1
+// CHECK:STDOUT:     } {
+// CHECK:STDOUT:       %T.ref: type = name_ref T, @Outer.%T.loc4_13.1 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:       %self.param: @F.1.%Self.as_type.loc6_16.1 (%Self.as_type.ea1) = value_param call_param0
+// CHECK:STDOUT:       %.loc6_16.1: type = splice_block %.loc6_16.3 [symbolic = %Self.as_type.loc6_16.1 (constants.%Self.as_type.ea1)] {
+// CHECK:STDOUT:         %.loc6_16.2: @F.1.%Inner.type (%Inner.type.392) = specific_constant @Inner.%Self.1, @Inner(constants.%T) [symbolic = %Self (constants.%Self.770)]
+// CHECK:STDOUT:         %Self.ref: @F.1.%Inner.type (%Inner.type.392) = name_ref Self, %.loc6_16.2 [symbolic = %Self (constants.%Self.770)]
+// CHECK:STDOUT:         %Self.as_type.loc6_16.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc6_16.1 (constants.%Self.as_type.ea1)]
+// CHECK:STDOUT:         %.loc6_16.3: type = converted %Self.ref, %Self.as_type.loc6_16.2 [symbolic = %Self.as_type.loc6_16.1 (constants.%Self.as_type.ea1)]
+// CHECK:STDOUT:       }
+// CHECK:STDOUT:       %self: @F.1.%Self.as_type.loc6_16.1 (%Self.as_type.ea1) = bind_name self, %self.param
+// CHECK:STDOUT:       %return.param: ref @F.1.%T (%T) = out_param call_param1
+// CHECK:STDOUT:       %return: ref @F.1.%T (%T) = return_slot %return.param
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %assoc0.loc6_28.1: @Inner.%Inner.assoc_type (%Inner.assoc_type.115) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc6_28.2 (constants.%assoc0.95e)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = %Self.1
+// CHECK:STDOUT:     .T = <poisoned>
+// CHECK:STDOUT:     .F = %assoc0.loc6_28.1
+// CHECK:STDOUT:     witness = (%F.decl)
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic impl @impl.eed(@Outer.%T.loc4_13.1: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C.390)]
+// CHECK:STDOUT:   %Inner.type: type = facet_type <@Inner, @Inner(%T)> [symbolic = %Inner.type (constants.%Inner.type.392)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %Inner.type [symbolic = %require_complete (constants.%require_complete.8fa)]
+// CHECK:STDOUT:   %Inner.impl_witness: <witness> = impl_witness @C.%Inner.impl_witness_table, @impl.eed(%T) [symbolic = %Inner.impl_witness (constants.%Inner.impl_witness.b15)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %F.type: type = fn_type @F.2, @impl.eed(%T) [symbolic = %F.type (constants.%F.type.77b)]
+// CHECK:STDOUT:   %F: @impl.eed.%F.type (%F.type.77b) = struct_value () [symbolic = %F (constants.%F.ed9)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   impl: %Self.ref as %Inner.ref {
+// CHECK:STDOUT:     %F.decl: @impl.eed.%F.type (%F.type.77b) = fn_decl @F.2 [symbolic = @impl.eed.%F (constants.%F.ed9)] {
+// CHECK:STDOUT:       %self.patt: @F.2.%C (%C.390) = binding_pattern self
+// CHECK:STDOUT:       %self.param_patt: @F.2.%C (%C.390) = value_param_pattern %self.patt, call_param0
+// CHECK:STDOUT:       %return.patt: @F.2.%T (%T) = return_slot_pattern
+// CHECK:STDOUT:       %return.param_patt: @F.2.%T (%T) = out_param_pattern %return.patt, call_param1
+// CHECK:STDOUT:     } {
+// CHECK:STDOUT:       %T.ref: type = name_ref T, @Outer.%T.loc4_13.1 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:       %self.param: @F.2.%C (%C.390) = value_param call_param0
+// CHECK:STDOUT:       %.loc11_18.1: type = splice_block %C.ref [symbolic = %C (constants.%C.390)] {
+// CHECK:STDOUT:         %.loc11_18.2: type = specific_constant @Outer.%C.decl, @Outer(constants.%T) [symbolic = %C (constants.%C.390)]
+// CHECK:STDOUT:         %C.ref: type = name_ref C, %.loc11_18.2 [symbolic = %C (constants.%C.390)]
+// CHECK:STDOUT:       }
+// CHECK:STDOUT:       %self: @F.2.%C (%C.390) = bind_name self, %self.param
+// CHECK:STDOUT:       %return.param: ref @F.2.%T (%T) = out_param call_param1
+// CHECK:STDOUT:       %return: ref @F.2.%T (%T) = return_slot %return.param
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .C = <poisoned>
+// CHECK:STDOUT:     .T = <poisoned>
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:     .Inner = <poisoned>
+// CHECK:STDOUT:     witness = @C.%Inner.impl_witness
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: impl @impl.a83: %Self.ref as %Inner.ref {
+// CHECK:STDOUT:   %F.decl: %F.type.a78 = fn_decl @F.3 [concrete = constants.%F.a24] {
+// CHECK:STDOUT:     %self.patt: %D = binding_pattern self
+// CHECK:STDOUT:     %self.param_patt: %D = value_param_pattern %self.patt, call_param0
+// CHECK:STDOUT:     %return.patt: %i32 = return_slot_pattern
+// CHECK:STDOUT:     %return.param_patt: %i32 = out_param_pattern %return.patt, call_param1
+// CHECK:STDOUT:   } {
+// CHECK:STDOUT:     %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
+// CHECK:STDOUT:     %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
+// CHECK:STDOUT:     %self.param: %D = value_param call_param0
+// CHECK:STDOUT:     %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D]
+// CHECK:STDOUT:     %self: %D = bind_name self, %self.param
+// CHECK:STDOUT:     %return.param: ref %i32 = out_param call_param1
+// CHECK:STDOUT:     %return: ref %i32 = return_slot %return.param
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .D = <poisoned>
+// CHECK:STDOUT:   .F = %F.decl
+// CHECK:STDOUT:   witness = @D.%Inner.impl_witness
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic class @Outer(%T.loc4_13.1: type) {
+// CHECK:STDOUT:   %T.loc4_13.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_13.2 (constants.%T)]
+// CHECK:STDOUT:   %T.patt.loc4_13.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_13.2 (constants.%T.patt)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Inner.type: type = facet_type <@Inner, @Inner(%T.loc4_13.2)> [symbolic = %Inner.type (constants.%Inner.type.392)]
+// CHECK:STDOUT:   %C: type = class_type @C, @C(%T.loc4_13.2) [symbolic = %C (constants.%C.390)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:     %Inner.decl: type = interface_decl @Inner [symbolic = @Outer.%Inner.type (constants.%Inner.type.392)] {} {}
+// CHECK:STDOUT:     %C.decl: type = class_decl @C [symbolic = @Outer.%C (constants.%C.390)] {} {}
+// CHECK:STDOUT:     %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type]
+// CHECK:STDOUT:     %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357]
+// CHECK:STDOUT:     complete_type_witness = %complete_type
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%Outer.9d6
+// CHECK:STDOUT:     .Inner = %Inner.decl
+// CHECK:STDOUT:     .T = <poisoned>
+// CHECK:STDOUT:     .C = %C.decl
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic class @C(@Outer.%T.loc4_13.1: type) {
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:     impl_decl @impl.eed [concrete] {} {
+// CHECK:STDOUT:       %Self.ref: type = name_ref Self, constants.%C.390 [symbolic = %C (constants.%C.390)]
+// CHECK:STDOUT:       %.loc10: type = specific_constant @Outer.%Inner.decl, @Outer(constants.%T) [symbolic = %Inner.type (constants.%Inner.type.392)]
+// CHECK:STDOUT:       %Inner.ref: type = name_ref Inner, %.loc10 [symbolic = %Inner.type (constants.%Inner.type.392)]
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %Inner.impl_witness_table = impl_witness_table (@impl.eed.%F.decl), @impl.eed [concrete]
+// CHECK:STDOUT:     %Inner.impl_witness: <witness> = impl_witness %Inner.impl_witness_table, @impl.eed(constants.%T) [symbolic = @impl.eed.%Inner.impl_witness (constants.%Inner.impl_witness.b15)]
+// CHECK:STDOUT:     %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type]
+// CHECK:STDOUT:     %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357]
+// CHECK:STDOUT:     complete_type_witness = %complete_type
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%C.390
+// CHECK:STDOUT:     .Inner = <poisoned>
+// CHECK:STDOUT:     .C = <poisoned>
+// CHECK:STDOUT:     .T = <poisoned>
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: class @D {
+// CHECK:STDOUT:   impl_decl @impl.a83 [concrete] {} {
+// CHECK:STDOUT:     %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D]
+// CHECK:STDOUT:     %Outer.ref: %Outer.type = name_ref Outer, file.%Outer.decl [concrete = constants.%Outer.generic]
+// CHECK:STDOUT:     %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
+// CHECK:STDOUT:     %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
+// CHECK:STDOUT:     %Outer: type = class_type @Outer, @Outer(constants.%i32) [concrete = constants.%Outer.545]
+// CHECK:STDOUT:     %.loc17: type = specific_constant @Outer.%Inner.decl, @Outer(constants.%i32) [concrete = constants.%Inner.type.52d]
+// CHECK:STDOUT:     %Inner.ref: type = name_ref Inner, %.loc17 [concrete = constants.%Inner.type.52d]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Inner.impl_witness_table = impl_witness_table (@impl.a83.%F.decl), @impl.a83 [concrete]
+// CHECK:STDOUT:   %Inner.impl_witness: <witness> = impl_witness %Inner.impl_witness_table [concrete = constants.%Inner.impl_witness.1dc]
+// CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type]
+// CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357]
+// CHECK:STDOUT:   complete_type_witness = %complete_type
+// CHECK:STDOUT:
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%D
+// CHECK:STDOUT:   .Outer = <poisoned>
+// CHECK:STDOUT:   .D = <poisoned>
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @F.1(@Outer.%T.loc4_13.1: type, @Inner.%Self.1: @Inner.%Inner.type (%Inner.type.392)) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %Inner.type: type = facet_type <@Inner, @Inner(%T)> [symbolic = %Inner.type (constants.%Inner.type.392)]
+// CHECK:STDOUT:   %Self: @F.1.%Inner.type (%Inner.type.392) = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self.770)]
+// CHECK:STDOUT:   %Self.as_type.loc6_16.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc6_16.1 (constants.%Self.as_type.ea1)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn[%self.param_patt: @F.1.%Self.as_type.loc6_16.1 (%Self.as_type.ea1)]() -> @F.1.%T (%T);
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @F.2(@Outer.%T.loc4_13.1: type) {
+// CHECK:STDOUT:   %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)]
+// CHECK:STDOUT:   %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C.390)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %require_complete.loc11_23: <witness> = require_complete_type %T [symbolic = %require_complete.loc11_23 (constants.%require_complete.4ae)]
+// CHECK:STDOUT:   %require_complete.loc11_16: <witness> = require_complete_type %C [symbolic = %require_complete.loc11_16 (constants.%require_complete.930)]
+// CHECK:STDOUT:   %Inner.type: type = facet_type <@Inner, @Inner(%T)> [symbolic = %Inner.type (constants.%Inner.type.392)]
+// CHECK:STDOUT:   %require_complete.loc11_48: <witness> = require_complete_type %Inner.type [symbolic = %require_complete.loc11_48 (constants.%require_complete.8fa)]
+// CHECK:STDOUT:   %Inner.assoc_type: type = assoc_entity_type @Inner, @Inner(%T) [symbolic = %Inner.assoc_type (constants.%Inner.assoc_type.115)]
+// CHECK:STDOUT:   %assoc0: @F.2.%Inner.assoc_type (%Inner.assoc_type.115) = assoc_entity element0, @Inner.%F.decl [symbolic = %assoc0 (constants.%assoc0.95e)]
+// CHECK:STDOUT:   %Inner.lookup_impl_witness: <witness> = lookup_impl_witness %C, @Inner, @Inner(%T) [symbolic = %Inner.lookup_impl_witness (constants.%Inner.lookup_impl_witness)]
+// CHECK:STDOUT:   %F.type: type = fn_type @F.1, @Inner(%T) [symbolic = %F.type (constants.%F.type.0f3)]
+// CHECK:STDOUT:   %Inner.facet: @F.2.%Inner.type (%Inner.type.392) = facet_value %C, (%Inner.lookup_impl_witness) [symbolic = %Inner.facet (constants.%Inner.facet.c18)]
+// CHECK:STDOUT:   %.loc11_41: type = fn_type_with_self_type %F.type, %Inner.facet [symbolic = %.loc11_41 (constants.%.692)]
+// CHECK:STDOUT:   %impl.elem0.loc11_41.2: @F.2.%.loc11_41 (%.692) = impl_witness_access %Inner.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc11_41.2 (constants.%impl.elem0)]
+// CHECK:STDOUT:   %specific_impl_fn.loc11_41.2: <specific function> = specific_impl_function %impl.elem0.loc11_41.2, @F.1(%T, %Inner.facet) [symbolic = %specific_impl_fn.loc11_41.2 (constants.%specific_impl_fn)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn[%self.param_patt: @F.2.%C (%C.390)]() -> @F.2.%T (%T) {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %self.ref: @F.2.%C (%C.390) = name_ref self, %self
+// CHECK:STDOUT:     %.loc11_43: type = specific_constant @Outer.%Inner.decl, @Outer(constants.%T) [symbolic = %Inner.type (constants.%Inner.type.392)]
+// CHECK:STDOUT:     %Inner.ref: type = name_ref Inner, %.loc11_43 [symbolic = %Inner.type (constants.%Inner.type.392)]
+// CHECK:STDOUT:     %.loc11_48: @F.2.%Inner.assoc_type (%Inner.assoc_type.115) = specific_constant @Inner.%assoc0.loc6_28.1, @Inner(constants.%T) [symbolic = %assoc0 (constants.%assoc0.95e)]
+// CHECK:STDOUT:     %F.ref: @F.2.%Inner.assoc_type (%Inner.assoc_type.115) = name_ref F, %.loc11_48 [symbolic = %assoc0 (constants.%assoc0.95e)]
+// CHECK:STDOUT:     %impl.elem0.loc11_41.1: @F.2.%.loc11_41 (%.692) = impl_witness_access constants.%Inner.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc11_41.2 (constants.%impl.elem0)]
+// CHECK:STDOUT:     %bound_method.loc11_41: <bound method> = bound_method %self.ref, %impl.elem0.loc11_41.1
+// CHECK:STDOUT:     %specific_impl_fn.loc11_41.1: <specific function> = specific_impl_function %impl.elem0.loc11_41.1, @F.1(constants.%T, constants.%Inner.facet.c18) [symbolic = %specific_impl_fn.loc11_41.2 (constants.%specific_impl_fn)]
+// CHECK:STDOUT:     %bound_method.loc11_52: <bound method> = bound_method %self.ref, %specific_impl_fn.loc11_41.1
+// CHECK:STDOUT:     %.loc11_52: init @F.2.%T (%T) = call %bound_method.loc11_52(%self.ref)
+// CHECK:STDOUT:     %.loc11_53.1: @F.2.%T (%T) = value_of_initializer %.loc11_52
+// CHECK:STDOUT:     %.loc11_53.2: @F.2.%T (%T) = converted %.loc11_52, %.loc11_53.1
+// CHECK:STDOUT:     return %.loc11_53.2
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @F.3[%self.param_patt: %D]() -> %i32;
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Test() -> %i32 {
+// CHECK:STDOUT: !entry:
+// CHECK:STDOUT:   name_binding_decl {
+// CHECK:STDOUT:     %c.patt: %C.70f = binding_pattern c
+// CHECK:STDOUT:     %.loc23_3.1: %C.70f = var_pattern %c.patt
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %c.var: ref %C.70f = var c
+// CHECK:STDOUT:   %.loc23_26.1: %empty_struct_type = struct_literal ()
+// CHECK:STDOUT:   %.loc23_26.2: init %C.70f = class_init (), %c.var [concrete = constants.%C.val]
+// CHECK:STDOUT:   %.loc23_3.2: init %C.70f = converted %.loc23_26.1, %.loc23_26.2 [concrete = constants.%C.val]
+// CHECK:STDOUT:   assign %c.var, %.loc23_3.2
+// CHECK:STDOUT:   %.loc23_20.1: type = splice_block %C.ref [concrete = constants.%C.70f] {
+// CHECK:STDOUT:     %Outer.ref.loc23: %Outer.type = name_ref Outer, file.%Outer.decl [concrete = constants.%Outer.generic]
+// CHECK:STDOUT:     %int_32.loc23: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
+// CHECK:STDOUT:     %i32.loc23: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
+// CHECK:STDOUT:     %Outer.loc23: type = class_type @Outer, @Outer(constants.%i32) [concrete = constants.%Outer.545]
+// CHECK:STDOUT:     %.loc23_20.2: type = specific_constant @Outer.%C.decl, @Outer(constants.%i32) [concrete = constants.%C.70f]
+// CHECK:STDOUT:     %C.ref: type = name_ref C, %.loc23_20.2 [concrete = constants.%C.70f]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %c: ref %C.70f = bind_name c, %c.var
+// CHECK:STDOUT:   %c.ref: ref %C.70f = name_ref c, %c
+// CHECK:STDOUT:   %Outer.ref.loc24: %Outer.type = name_ref Outer, file.%Outer.decl [concrete = constants.%Outer.generic]
+// CHECK:STDOUT:   %int_32.loc24: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
+// CHECK:STDOUT:   %i32.loc24: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
+// CHECK:STDOUT:   %Outer.loc24: type = class_type @Outer, @Outer(constants.%i32) [concrete = constants.%Outer.545]
+// CHECK:STDOUT:   %.loc24_23: type = specific_constant @Outer.%Inner.decl, @Outer(constants.%i32) [concrete = constants.%Inner.type.52d]
+// CHECK:STDOUT:   %Inner.ref: type = name_ref Inner, %.loc24_23 [concrete = constants.%Inner.type.52d]
+// CHECK:STDOUT:   %.loc24_29: %Inner.assoc_type.215 = specific_constant @Inner.%assoc0.loc6_28.1, @Inner(constants.%i32) [concrete = constants.%assoc0.e80]
+// CHECK:STDOUT:   %F.ref: %Inner.assoc_type.215 = name_ref F, %.loc24_29 [concrete = constants.%assoc0.e80]
+// CHECK:STDOUT:   %impl.elem0: %.b10 = impl_witness_access constants.%Inner.impl_witness.47d, element0 [concrete = constants.%F.e75]
+// CHECK:STDOUT:   %bound_method.loc24_11: <bound method> = bound_method %c.ref, %impl.elem0
+// CHECK:STDOUT:   %specific_fn: <specific function> = specific_function %impl.elem0, @F.2(constants.%i32) [concrete = constants.%F.specific_fn]
+// CHECK:STDOUT:   %bound_method.loc24_33: <bound method> = bound_method %c.ref, %specific_fn
+// CHECK:STDOUT:   %.loc24_10: %C.70f = bind_value %c.ref
+// CHECK:STDOUT:   %F.call: init %i32 = call %bound_method.loc24_33(%.loc24_10)
+// CHECK:STDOUT:   %.loc24_34.1: %i32 = value_of_initializer %F.call
+// CHECK:STDOUT:   %.loc24_34.2: %i32 = converted %F.call, %.loc24_34.1
+// CHECK:STDOUT:   return %.loc24_34.2
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Outer(constants.%T) {
+// CHECK:STDOUT:   %T.loc4_13.2 => constants.%T
+// CHECK:STDOUT:   %T.patt.loc4_13.2 => constants.%T.patt
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Inner.type => constants.%Inner.type.392
+// CHECK:STDOUT:   %C => constants.%C.390
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Inner(constants.%T) {
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %Inner.type => constants.%Inner.type.392
+// CHECK:STDOUT:   %Self.2 => constants.%Self.770
+// CHECK:STDOUT:   %F.type => constants.%F.type.0f3
+// CHECK:STDOUT:   %F => constants.%F.db9
+// CHECK:STDOUT:   %Inner.assoc_type => constants.%Inner.assoc_type.115
+// CHECK:STDOUT:   %assoc0.loc6_28.2 => constants.%assoc0.95e
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F.1(constants.%T, constants.%Self.770) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %Inner.type => constants.%Inner.type.392
+// CHECK:STDOUT:   %Self => constants.%Self.770
+// CHECK:STDOUT:   %Self.as_type.loc6_16.1 => constants.%Self.as_type.ea1
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Inner(@F.1.%T) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Inner(%T) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @C(constants.%T) {
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @impl.eed(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %C => constants.%C.390
+// CHECK:STDOUT:   %Inner.type => constants.%Inner.type.392
+// CHECK:STDOUT:   %require_complete => constants.%require_complete.8fa
+// CHECK:STDOUT:   %Inner.impl_witness => constants.%Inner.impl_witness.b15
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %F.type => constants.%F.type.77b
+// CHECK:STDOUT:   %F => constants.%F.ed9
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @C(@impl.eed.%T) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Inner(@impl.eed.%T) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @impl.eed(%T) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F.2(constants.%T) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %C => constants.%C.390
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @C(@F.2.%T) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F.1(constants.%T, constants.%Inner.facet.9a3) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %Inner.type => constants.%Inner.type.392
+// CHECK:STDOUT:   %Self => constants.%Inner.facet.9a3
+// CHECK:STDOUT:   %Self.as_type.loc6_16.1 => constants.%C.390
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Inner(@Outer.%T.loc4_13.2) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @C(@Outer.%T.loc4_13.2) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F.1(constants.%T, constants.%Inner.facet.c18) {
+// CHECK:STDOUT:   %T => constants.%T
+// CHECK:STDOUT:   %Inner.type => constants.%Inner.type.392
+// CHECK:STDOUT:   %Self => constants.%Inner.facet.c18
+// CHECK:STDOUT:   %Self.as_type.loc6_16.1 => constants.%C.390
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Inner(@F.2.%T) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F.1(@F.2.%T, @F.2.%Inner.facet) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Outer(constants.%i32) {
+// CHECK:STDOUT:   %T.loc4_13.2 => constants.%i32
+// CHECK:STDOUT:   %T.patt.loc4_13.2 => constants.%T.patt
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Inner.type => constants.%Inner.type.52d
+// CHECK:STDOUT:   %C => constants.%C.70f
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Inner(constants.%i32) {
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %T => constants.%i32
+// CHECK:STDOUT:   %Inner.type => constants.%Inner.type.52d
+// CHECK:STDOUT:   %Self.2 => constants.%Self.493
+// CHECK:STDOUT:   %F.type => constants.%F.type.86e
+// CHECK:STDOUT:   %F => constants.%F.11d
+// CHECK:STDOUT:   %Inner.assoc_type => constants.%Inner.assoc_type.215
+// CHECK:STDOUT:   %assoc0.loc6_28.2 => constants.%assoc0.e80
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @C(constants.%i32) {
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F.1(constants.%i32, constants.%Inner.facet.edc) {
+// CHECK:STDOUT:   %T => constants.%i32
+// CHECK:STDOUT:   %Inner.type => constants.%Inner.type.52d
+// CHECK:STDOUT:   %Self => constants.%Inner.facet.edc
+// CHECK:STDOUT:   %Self.as_type.loc6_16.1 => constants.%D
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @impl.eed(constants.%i32) {
+// CHECK:STDOUT:   %T => constants.%i32
+// CHECK:STDOUT:   %C => constants.%C.70f
+// CHECK:STDOUT:   %Inner.type => constants.%Inner.type.52d
+// CHECK:STDOUT:   %require_complete => constants.%complete_type.9fa
+// CHECK:STDOUT:   %Inner.impl_witness => constants.%Inner.impl_witness.47d
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %F.type => constants.%F.type.f11
+// CHECK:STDOUT:   %F => constants.%F.e75
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F.2(constants.%i32) {
+// CHECK:STDOUT:   %T => constants.%i32
+// CHECK:STDOUT:   %C => constants.%C.70f
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %require_complete.loc11_23 => constants.%complete_type.f8a
+// CHECK:STDOUT:   %require_complete.loc11_16 => constants.%complete_type.357
+// CHECK:STDOUT:   %Inner.type => constants.%Inner.type.52d
+// CHECK:STDOUT:   %require_complete.loc11_48 => constants.%complete_type.9fa
+// CHECK:STDOUT:   %Inner.assoc_type => constants.%Inner.assoc_type.215
+// CHECK:STDOUT:   %assoc0 => constants.%assoc0.e80
+// CHECK:STDOUT:   %Inner.lookup_impl_witness => constants.%Inner.impl_witness.47d
+// CHECK:STDOUT:   %F.type => constants.%F.type.86e
+// CHECK:STDOUT:   %Inner.facet => constants.%Inner.facet.840
+// CHECK:STDOUT:   %.loc11_41 => constants.%.b10
+// CHECK:STDOUT:   %impl.elem0.loc11_41.2 => constants.%F.e75
+// CHECK:STDOUT:   %specific_impl_fn.loc11_41.2 => constants.%F.specific_fn
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F.1(constants.%i32, constants.%Inner.facet.840) {
+// CHECK:STDOUT:   %T => constants.%i32
+// CHECK:STDOUT:   %Inner.type => constants.%Inner.type.52d
+// CHECK:STDOUT:   %Self => constants.%Inner.facet.840
+// CHECK:STDOUT:   %Self.as_type.loc6_16.1 => constants.%C.70f
+// CHECK:STDOUT: }
+// CHECK:STDOUT:

+ 12 - 16
toolchain/check/testdata/class/no_prelude/fail_error_recovery.carbon

@@ -29,13 +29,9 @@ fn F(N:! error_not_found) {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %F.type: type = fn_type @F [concrete]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [concrete]
-// CHECK:STDOUT:   %C: type = class_type @C [concrete]
-// CHECK:STDOUT:   %ptr.454: type = ptr_type <vtable> [concrete]
-// CHECK:STDOUT:   %struct_type.vptr: type = struct_type {.<vptr>: %ptr.454} [concrete]
-// CHECK:STDOUT:   %complete_type.513: <witness> = complete_type_witness %struct_type.vptr [concrete]
-// CHECK:STDOUT:   %D: type = class_type @D [concrete]
-// CHECK:STDOUT:   %struct_type.base: type = struct_type {.base: %C} [concrete]
-// CHECK:STDOUT:   %complete_type.1d0: <witness> = complete_type_witness %struct_type.base [concrete]
+// CHECK:STDOUT:   %ptr: type = ptr_type <vtable> [concrete]
+// CHECK:STDOUT:   %struct_type.vptr: type = struct_type {.<vptr>: %ptr} [concrete]
+// CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %struct_type.vptr [concrete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -64,8 +60,8 @@ fn F(N:! error_not_found) {
 // CHECK:STDOUT:       %self: <error> = bind_name self, %self.param
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %.loc9: <vtable> = vtable (%Foo.decl) [concrete = <error>]
-// CHECK:STDOUT:     %struct_type.vptr: type = struct_type {.<vptr>: %ptr.454} [concrete = constants.%struct_type.vptr]
-// CHECK:STDOUT:     %complete_type: <witness> = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type.513]
+// CHECK:STDOUT:     %struct_type.vptr: type = struct_type {.<vptr>: %ptr} [concrete = constants.%struct_type.vptr]
+// CHECK:STDOUT:     %complete_type: <witness> = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type]
 // CHECK:STDOUT:     complete_type_witness = %complete_type
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
@@ -78,17 +74,17 @@ fn F(N:! error_not_found) {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
 // CHECK:STDOUT:   class {
-// CHECK:STDOUT:     %C.ref: type = name_ref C, @F.%C.decl [concrete = constants.%C]
-// CHECK:STDOUT:     %.loc12: <error> = base_decl %C.ref, element0 [concrete]
-// CHECK:STDOUT:     %struct_type.base: type = struct_type {.base: %C} [concrete = constants.%struct_type.base]
-// CHECK:STDOUT:     %complete_type: <witness> = complete_type_witness %struct_type.base [concrete = constants.%complete_type.1d0]
+// CHECK:STDOUT:     %C.ref: type = name_ref C, @F.%C.decl [concrete = <error>]
+// CHECK:STDOUT:     %.loc12: <error> = base_decl <error>, element0 [concrete]
+// CHECK:STDOUT:     %struct_type.base: type = struct_type {.base: <error>} [concrete = <error>]
+// CHECK:STDOUT:     %complete_type: <witness> = complete_type_witness %struct_type.base [concrete = <error>]
 // CHECK:STDOUT:     complete_type_witness = %complete_type
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .Self = <error>
 // CHECK:STDOUT:     .C = <poisoned>
 // CHECK:STDOUT:     .base = %.loc12
-// CHECK:STDOUT:     extend %C.ref
+// CHECK:STDOUT:     has_error
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -97,8 +93,8 @@ fn F(N:! error_not_found) {
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%N.patt: <error>) {
 // CHECK:STDOUT:   !entry:
-// CHECK:STDOUT:     %C.decl: type = class_decl @C [concrete = constants.%C] {} {}
-// CHECK:STDOUT:     %D.decl: type = class_decl @D [concrete = constants.%D] {} {}
+// CHECK:STDOUT:     %C.decl: type = class_decl @C [concrete = <error>] {} {}
+// CHECK:STDOUT:     %D.decl: type = class_decl @D [concrete = <error>] {} {}
 // CHECK:STDOUT:     return
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }

+ 20 - 11
toolchain/check/testdata/class/no_prelude/generic_vs_params.carbon

@@ -91,7 +91,6 @@ class Foo[T:! type];
 // CHECK:STDOUT:   %C.type: type = generic_class_type @C [concrete]
 // CHECK:STDOUT:   %C.generic: %C.type = struct_value () [concrete]
 // CHECK:STDOUT:   %C.f2e: type = class_type @C, @C(%T) [symbolic]
-// CHECK:STDOUT:   %GenericNoParams.72f: type = class_type @GenericNoParams [concrete]
 // CHECK:STDOUT:   %GenericNoParams.fbf: type = class_type @GenericNoParams, @GenericNoParams(%T) [symbolic]
 // CHECK:STDOUT:   %U: type = bind_symbolic_name U, 1 [symbolic]
 // CHECK:STDOUT:   %U.patt: type = symbolic_binding_pattern U, 1 [symbolic]
@@ -104,9 +103,10 @@ class Foo[T:! type];
 // CHECK:STDOUT:   %GenericAndParams.2bb: type = class_type @GenericAndParams.1, @GenericAndParams.1(%X) [concrete]
 // CHECK:STDOUT:   %GenericAndParams.val.0b2: %GenericAndParams.2bb = struct_value () [concrete]
 // CHECK:STDOUT:   %C.fac: type = class_type @C, @C(%X) [concrete]
+// CHECK:STDOUT:   %GenericNoParams.fa1: type = class_type @GenericNoParams, @GenericNoParams(%X) [concrete]
 // CHECK:STDOUT:   %GenericAndParams.type.c20: type = generic_class_type @GenericAndParams.2, @C(%X) [concrete]
 // CHECK:STDOUT:   %GenericAndParams.generic.a55: %GenericAndParams.type.c20 = struct_value () [concrete]
-// CHECK:STDOUT:   %GenericNoParams.val: %GenericNoParams.72f = struct_value () [concrete]
+// CHECK:STDOUT:   %GenericNoParams.val: %GenericNoParams.fa1 = struct_value () [concrete]
 // CHECK:STDOUT:   %GenericAndParams.91f: type = class_type @GenericAndParams.2, @GenericAndParams.2(%X, %X) [concrete]
 // CHECK:STDOUT:   %GenericAndParams.val.99b: %GenericAndParams.91f = struct_value () [concrete]
 // CHECK:STDOUT: }
@@ -166,17 +166,18 @@ class Foo[T:! type];
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %c: ref %GenericAndParams.2bb = bind_name c, %c.var
 // CHECK:STDOUT:   name_binding_decl {
-// CHECK:STDOUT:     %d.patt: %GenericNoParams.72f = binding_pattern d
-// CHECK:STDOUT:     %.loc18_1: %GenericNoParams.72f = var_pattern %d.patt
+// CHECK:STDOUT:     %d.patt: %GenericNoParams.fa1 = binding_pattern d
+// CHECK:STDOUT:     %.loc18_1: %GenericNoParams.fa1 = var_pattern %d.patt
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %d.var: ref %GenericNoParams.72f = var d
-// CHECK:STDOUT:   %.loc18_12: type = splice_block %GenericNoParams.ref [concrete = constants.%GenericNoParams.72f] {
+// CHECK:STDOUT:   %d.var: ref %GenericNoParams.fa1 = var d
+// CHECK:STDOUT:   %.loc18_12.1: type = splice_block %GenericNoParams.ref [concrete = constants.%GenericNoParams.fa1] {
 // CHECK:STDOUT:     %C.ref.loc18: %C.type = name_ref C, %C.decl [concrete = constants.%C.generic]
 // CHECK:STDOUT:     %X.ref.loc18: type = name_ref X, %X.decl [concrete = constants.%X]
 // CHECK:STDOUT:     %C.loc18: type = class_type @C, @C(constants.%X) [concrete = constants.%C.fac]
-// CHECK:STDOUT:     %GenericNoParams.ref: type = name_ref GenericNoParams, @C.%GenericNoParams.decl [concrete = constants.%GenericNoParams.72f]
+// CHECK:STDOUT:     %.loc18_12.2: type = specific_constant @C.%GenericNoParams.decl, @C(constants.%X) [concrete = constants.%GenericNoParams.fa1]
+// CHECK:STDOUT:     %GenericNoParams.ref: type = name_ref GenericNoParams, %.loc18_12.2 [concrete = constants.%GenericNoParams.fa1]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %d: ref %GenericNoParams.72f = bind_name d, %d.var
+// CHECK:STDOUT:   %d: ref %GenericNoParams.fa1 = bind_name d, %d.var
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %e.patt: %GenericAndParams.91f = binding_pattern e
 // CHECK:STDOUT:     %.loc19_1: %GenericAndParams.91f = var_pattern %e.patt
@@ -233,11 +234,12 @@ class Foo[T:! type];
 // CHECK:STDOUT:   %T.patt.loc8_9.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_9.2 (constants.%T.patt)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %GenericNoParams: type = class_type @GenericNoParams, @GenericNoParams(%T.loc8_9.2) [symbolic = %GenericNoParams (constants.%GenericNoParams.fbf)]
 // CHECK:STDOUT:   %GenericAndParams.type: type = generic_class_type @GenericAndParams.2, @C(%T.loc8_9.2) [symbolic = %GenericAndParams.type (constants.%GenericAndParams.type.3ce)]
 // CHECK:STDOUT:   %GenericAndParams.generic: @C.%GenericAndParams.type (%GenericAndParams.type.3ce) = struct_value () [symbolic = %GenericAndParams.generic (constants.%GenericAndParams.generic.54a)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   class {
-// CHECK:STDOUT:     %GenericNoParams.decl: type = class_decl @GenericNoParams [concrete = constants.%GenericNoParams.72f] {} {}
+// CHECK:STDOUT:     %GenericNoParams.decl: type = class_decl @GenericNoParams [symbolic = @C.%GenericNoParams (constants.%GenericNoParams.fbf)] {} {}
 // CHECK:STDOUT:     %GenericAndParams.decl: @C.%GenericAndParams.type (%GenericAndParams.type.3ce) = class_decl @GenericAndParams.2 [symbolic = @C.%GenericAndParams.generic (constants.%GenericAndParams.generic.54a)] {
 // CHECK:STDOUT:       %U.patt.loc10_26.1: type = symbolic_binding_pattern U, 1 [symbolic = %U.patt.loc10_26.2 (constants.%U.patt)]
 // CHECK:STDOUT:     } {
@@ -307,8 +309,8 @@ class Foo[T:! type];
 // CHECK:STDOUT:   %.loc17_1: init %GenericAndParams.2bb = converted %.loc17_31.1, %.loc17_31.2 [concrete = constants.%GenericAndParams.val.0b2]
 // CHECK:STDOUT:   assign file.%c.var, %.loc17_1
 // CHECK:STDOUT:   %.loc18_32.1: %empty_struct_type = struct_literal ()
-// CHECK:STDOUT:   %.loc18_32.2: init %GenericNoParams.72f = class_init (), file.%d.var [concrete = constants.%GenericNoParams.val]
-// CHECK:STDOUT:   %.loc18_1: init %GenericNoParams.72f = converted %.loc18_32.1, %.loc18_32.2 [concrete = constants.%GenericNoParams.val]
+// CHECK:STDOUT:   %.loc18_32.2: init %GenericNoParams.fa1 = class_init (), file.%d.var [concrete = constants.%GenericNoParams.val]
+// CHECK:STDOUT:   %.loc18_1: init %GenericNoParams.fa1 = converted %.loc18_32.1, %.loc18_32.2 [concrete = constants.%GenericNoParams.val]
 // CHECK:STDOUT:   assign file.%d.var, %.loc18_1
 // CHECK:STDOUT:   %.loc19_36.1: %empty_struct_type = struct_literal ()
 // CHECK:STDOUT:   %.loc19_36.2: init %GenericAndParams.91f = class_init (), file.%e.var [concrete = constants.%GenericAndParams.val.99b]
@@ -334,6 +336,8 @@ class Foo[T:! type];
 // CHECK:STDOUT:   %U.patt.loc10_26.2 => constants.%U.patt
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @GenericNoParams(@C.%T.loc8_9.2) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @C(%T.loc8_9.2) {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @GenericAndParams.1(constants.%X) {
@@ -348,10 +352,15 @@ class Foo[T:! type];
 // CHECK:STDOUT:   %T.patt.loc8_9.2 => constants.%T.patt
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %GenericNoParams => constants.%GenericNoParams.fa1
 // CHECK:STDOUT:   %GenericAndParams.type => constants.%GenericAndParams.type.c20
 // CHECK:STDOUT:   %GenericAndParams.generic => constants.%GenericAndParams.generic.a55
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @GenericNoParams(constants.%X) {
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @GenericAndParams.2(constants.%X, constants.%X) {
 // CHECK:STDOUT:   %U.loc10_26.2 => constants.%X
 // CHECK:STDOUT:   %U.patt.loc10_26.2 => constants.%U.patt

+ 7 - 4
toolchain/check/testdata/function/call/prefer_unqualified_lookup.carbon

@@ -31,8 +31,7 @@ fn Class(F:! type).Inner.G() -> i32 { return F(); }
 // CHECK:STDOUT:   %Class.type: type = generic_class_type @Class [concrete]
 // CHECK:STDOUT:   %Class.generic: %Class.type = struct_value () [concrete]
 // CHECK:STDOUT:   %Class: type = class_type @Class, @Class(%F.8b3) [symbolic]
-// CHECK:STDOUT:   %Inner.b32: type = class_type @Inner [concrete]
-// CHECK:STDOUT:   %Inner.6e0: type = class_type @Inner, @Inner(%F.8b3) [symbolic]
+// CHECK:STDOUT:   %Inner: type = class_type @Inner, @Inner(%F.8b3) [symbolic]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [concrete]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [concrete]
 // CHECK:STDOUT:   %F.type: type = fn_type @F, @Inner(%F.8b3) [symbolic]
@@ -94,9 +93,10 @@ fn Class(F:! type).Inner.G() -> i32 { return F(); }
 // CHECK:STDOUT:   %F.patt.loc5_13.2: type = symbolic_binding_pattern F, 0 [symbolic = %F.patt.loc5_13.2 (constants.%F.patt)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Inner: type = class_type @Inner, @Inner(%F.loc5_13.2) [symbolic = %Inner (constants.%Inner)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   class {
-// CHECK:STDOUT:     %Inner.decl: type = class_decl @Inner [concrete = constants.%Inner.b32] {} {}
+// CHECK:STDOUT:     %Inner.decl: type = class_decl @Inner [symbolic = @Class.%Inner (constants.%Inner)] {} {}
 // CHECK:STDOUT:     %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type]
 // CHECK:STDOUT:     %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357]
 // CHECK:STDOUT:     complete_type_witness = %complete_type
@@ -139,7 +139,7 @@ fn Class(F:! type).Inner.G() -> i32 { return F(); }
 // CHECK:STDOUT:     complete_type_witness = %complete_type
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
-// CHECK:STDOUT:     .Self = constants.%Inner.6e0
+// CHECK:STDOUT:     .Self = constants.%Inner
 // CHECK:STDOUT:     .F = %F.decl
 // CHECK:STDOUT:     .G = %G.decl
 // CHECK:STDOUT:   }
@@ -186,6 +186,7 @@ fn Class(F:! type).Inner.G() -> i32 { return F(); }
 // CHECK:STDOUT:   %F.patt.loc5_13.2 => constants.%F.patt
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Inner => constants.%Inner
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @Inner(constants.%F.8b3) {
@@ -205,6 +206,8 @@ fn Class(F:! type).Inner.G() -> i32 { return F(); }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @Inner(%F.loc8_19.1) {}
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @Inner(@Class.%F.loc5_13.2) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @Inner(@G.%F.loc13_46.1) {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(@G.%F.loc13_46.1) {}

+ 6 - 7
toolchain/check/testdata/impl/fail_extend_partially_defined_interface.carbon

@@ -26,8 +26,7 @@ interface I {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %I.type: type = facet_type <@I> [concrete]
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %C.f28: type = class_type @C [concrete]
-// CHECK:STDOUT:   %C.6b4: type = class_type @C, @C(%Self) [symbolic]
+// CHECK:STDOUT:   %C: type = class_type @C, @C(%Self) [symbolic]
 // CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness @C.%I.impl_witness_table, @impl(%Self) [symbolic]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
@@ -51,7 +50,7 @@ interface I {
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %C.decl: type = class_decl @C [concrete = constants.%C.f28] {} {}
+// CHECK:STDOUT:   %C.decl: type = class_decl @C [symbolic = constants.%C] {} {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -62,7 +61,7 @@ interface I {
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic impl @impl(@I.%Self: %I.type) {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)]
-// CHECK:STDOUT:   %C: type = class_type @C, @C(%Self) [symbolic = %C (constants.%C.6b4)]
+// CHECK:STDOUT:   %C: type = class_type @C, @C(%Self) [symbolic = %C (constants.%C)]
 // CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness @C.%I.impl_witness_table, @impl(%Self) [symbolic = %I.impl_witness (constants.%I.impl_witness)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   impl: %Self.ref as %I.ref;
@@ -73,7 +72,7 @@ interface I {
 // CHECK:STDOUT:
 // CHECK:STDOUT:   class {
 // CHECK:STDOUT:     impl_decl @impl [concrete] {} {
-// CHECK:STDOUT:       %Self.ref: type = name_ref Self, constants.%C.6b4 [symbolic = %C (constants.%C.6b4)]
+// CHECK:STDOUT:       %Self.ref: type = name_ref Self, constants.%C [symbolic = %C (constants.%C)]
 // CHECK:STDOUT:       %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %I.impl_witness_table = impl_witness_table (), @impl [concrete]
@@ -84,7 +83,7 @@ interface I {
 // CHECK:STDOUT:     complete_type_witness = %complete_type
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
-// CHECK:STDOUT:     .Self = constants.%C.6b4
+// CHECK:STDOUT:     .Self = constants.%C
 // CHECK:STDOUT:     .I = <poisoned>
 // CHECK:STDOUT:     has_error
 // CHECK:STDOUT:   }
@@ -94,7 +93,7 @@ interface I {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl(constants.%Self) {
 // CHECK:STDOUT:   %Self => constants.%Self
-// CHECK:STDOUT:   %C => constants.%C.6b4
+// CHECK:STDOUT:   %C => constants.%C
 // CHECK:STDOUT:   %I.impl_witness => constants.%I.impl_witness
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 84 - 46
toolchain/check/testdata/impl/min_prelude/forward_decls.carbon

@@ -240,11 +240,16 @@ interface I {
   // CHECK:STDERR:
   default fn F() {
     class C {}
-    // CHECK:STDERR: fail_todo_impl_in_interface_definition.carbon:[[@LINE+4]]:5: error: `impl` with unused generic binding [ImplUnusedBinding]
-    // CHECK:STDERR:     impl C as I;
-    // CHECK:STDERR:     ^~~~~~~~~~~~
-    // CHECK:STDERR:
     impl C as I;
+
+    // CHECK:STDERR: fail_todo_impl_in_interface_definition.carbon:[[@LINE+7]]:5: error: missing implementation of F in impl of interface I [ImplMissingFunction]
+    // CHECK:STDERR:     impl C as I {}
+    // CHECK:STDERR:     ^~~~~~~~~~~~~
+    // CHECK:STDERR: fail_todo_impl_in_interface_definition.carbon:[[@LINE-7]]:3: note: associated function F declared here [AssociatedFunctionHere]
+    // CHECK:STDERR:   default fn F() {
+    // CHECK:STDERR:   ^~~~~~~~~~~~~~~~
+    // CHECK:STDERR:
+    impl C as I {}
   }
 }
 
@@ -260,12 +265,15 @@ interface I {
   // CHECK:STDERR:
   default fn F() {
     class C {}
-    // CHECK:STDERR: fail_todo_impl_in_interface_definition_with_associated.carbon:[[@LINE+4]]:5: error: `impl` with unused generic binding [ImplUnusedBinding]
-    // CHECK:STDERR:     impl C as I where .U = C;
-    // CHECK:STDERR:     ^~~~~~~~~~~~~~~~~~~~~~~~~
-    // CHECK:STDERR:
     impl C as I where .U = C;
 
+    // CHECK:STDERR: fail_todo_impl_in_interface_definition_with_associated.carbon:[[@LINE+7]]:5: error: missing implementation of F in impl of interface I [ImplMissingFunction]
+    // CHECK:STDERR:     impl C as I where .U = C {}
+    // CHECK:STDERR:     ^~~~~~~~~~~~~~~~~~~~~~~~~~
+    // CHECK:STDERR: fail_todo_impl_in_interface_definition_with_associated.carbon:[[@LINE-7]]:3: note: associated function F declared here [AssociatedFunctionHere]
+    // CHECK:STDERR:   default fn F() {
+    // CHECK:STDERR:   ^~~~~~~~~~~~~~~~
+    // CHECK:STDERR:
     impl C as I where .U = C {}
   }
 }
@@ -1940,8 +1948,7 @@ interface I {
 // CHECK:STDOUT:   %F: %F.type = struct_value () [concrete]
 // CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type @I [concrete]
 // CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, @I.%F.decl [concrete]
-// CHECK:STDOUT:   %C.a2d: type = class_type @C [concrete]
-// CHECK:STDOUT:   %C.023: type = class_type @C, @C(%Self) [symbolic]
+// CHECK:STDOUT:   %C: type = class_type @C, @C(%Self) [symbolic]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
 // CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness @F.%I.impl_witness_table, @impl(%Self) [symbolic]
@@ -1976,9 +1983,16 @@ interface I {
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic impl @impl(@I.%Self: %I.type) {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)]
+// CHECK:STDOUT:   %C: type = class_type @C, @C(%Self) [symbolic = %C (constants.%C)]
 // CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness @F.%I.impl_witness_table, @impl(%Self) [symbolic = %I.impl_witness (constants.%I.impl_witness)]
 // CHECK:STDOUT:
-// CHECK:STDOUT:   impl: %C.ref as %I.ref;
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:
+// CHECK:STDOUT:   impl: %C.ref.loc11 as %I.ref.loc11 {
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .F = <poisoned>
+// CHECK:STDOUT:     witness = @F.%I.impl_witness
+// CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic class @C(@I.%Self: %I.type) {
@@ -1990,22 +2004,28 @@ interface I {
 // CHECK:STDOUT:     complete_type_witness = %complete_type
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
-// CHECK:STDOUT:     .Self = constants.%C.023
+// CHECK:STDOUT:     .Self = constants.%C
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(@I.%Self: %I.type) {
 // CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)]
+// CHECK:STDOUT:   %C: type = class_type @C, @C(%Self) [symbolic = %C (constants.%C)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn() {
 // CHECK:STDOUT:   !entry:
-// CHECK:STDOUT:     %C.decl: type = class_decl @C [concrete = constants.%C.a2d] {} {}
+// CHECK:STDOUT:     %C.decl: type = class_decl @C [symbolic = @F.%C (constants.%C)] {} {}
 // CHECK:STDOUT:     impl_decl @impl [concrete] {} {
-// CHECK:STDOUT:       %C.ref: type = name_ref C, @F.%C.decl [concrete = constants.%C.a2d]
-// CHECK:STDOUT:       %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type]
+// CHECK:STDOUT:       %C.ref.loc11: type = name_ref C, @F.%C.decl [symbolic = %C (constants.%C)]
+// CHECK:STDOUT:       %I.ref.loc11: type = name_ref I, file.%I.decl [concrete = constants.%I.type]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %I.impl_witness_table = impl_witness_table (), @impl [concrete]
+// CHECK:STDOUT:     %I.impl_witness_table = impl_witness_table (<error>), @impl [concrete]
 // CHECK:STDOUT:     %I.impl_witness: <witness> = impl_witness %I.impl_witness_table, @impl(constants.%Self) [symbolic = @impl.%I.impl_witness (constants.%I.impl_witness)]
+// CHECK:STDOUT:     impl_decl @impl [concrete] {} {
+// CHECK:STDOUT:       %C.ref.loc20: type = name_ref C, @F.%C.decl [symbolic = %C (constants.%C)]
+// CHECK:STDOUT:       %I.ref.loc20: type = name_ref I, file.%I.decl [concrete = constants.%I.type]
+// CHECK:STDOUT:     }
 // CHECK:STDOUT:     return
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -2016,11 +2036,16 @@ interface I {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl(constants.%Self) {
 // CHECK:STDOUT:   %Self => constants.%Self
+// CHECK:STDOUT:   %C => constants.%C
 // CHECK:STDOUT:   %I.impl_witness => constants.%I.impl_witness
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @C(@impl.%Self) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl(%Self) {}
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @C(@F.%Self) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_todo_impl_in_interface_definition_with_associated.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
@@ -2031,8 +2056,7 @@ interface I {
 // CHECK:STDOUT:   %F.type: type = fn_type @F [concrete]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [concrete]
 // CHECK:STDOUT:   %assoc1: %I.assoc_type = assoc_entity element1, @I.%F.decl [concrete]
-// CHECK:STDOUT:   %C.a2d: type = class_type @C [concrete]
-// CHECK:STDOUT:   %C.023: type = class_type @C, @C(%Self) [symbolic]
+// CHECK:STDOUT:   %C: type = class_type @C, @C(%Self) [symbolic]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
 // CHECK:STDOUT:   %.Self: %I.type = bind_symbolic_name .Self [symbolic_self]
@@ -2040,7 +2064,8 @@ interface I {
 // CHECK:STDOUT:   %.Self.as_wit.iface0: <witness> = facet_access_witness %.Self, element0 [symbolic_self]
 // CHECK:STDOUT:   %I.facet: %I.type = facet_value %.Self.as_type, (%.Self.as_wit.iface0) [symbolic_self]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %.Self.as_wit.iface0, element0 [symbolic_self]
-// CHECK:STDOUT:   %I_where.type: type = facet_type <@I where %impl.elem0 = %C.a2d> [concrete]
+// CHECK:STDOUT:   %I_where.type: type = facet_type <@I where %impl.elem0 = %C> [symbolic]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %I_where.type [symbolic]
 // CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness @F.%I.impl_witness_table, @impl(%Self) [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -2081,13 +2106,17 @@ interface I {
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic impl @impl(@I.%Self: %I.type) {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)]
+// CHECK:STDOUT:   %C: type = class_type @C, @C(%Self) [symbolic = %C (constants.%C)]
+// CHECK:STDOUT:   %I_where.type: type = facet_type <@I where constants.%impl.elem0 = %C> [symbolic = %I_where.type (constants.%I_where.type)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %I_where.type [symbolic = %require_complete (constants.%require_complete)]
 // CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness @F.%I.impl_witness_table, @impl(%Self) [symbolic = %I.impl_witness (constants.%I.impl_witness)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
-// CHECK:STDOUT:   impl: %C.ref.loc16_10 as %.loc16_17 {
+// CHECK:STDOUT:   impl: %C.ref.loc12_10 as %.loc12_17 {
 // CHECK:STDOUT:   !members:
-// CHECK:STDOUT:     witness = <error>
+// CHECK:STDOUT:     .F = <poisoned>
+// CHECK:STDOUT:     witness = @F.%I.impl_witness
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -2100,47 +2129,49 @@ interface I {
 // CHECK:STDOUT:     complete_type_witness = %complete_type
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
-// CHECK:STDOUT:     .Self = constants.%C.023
+// CHECK:STDOUT:     .Self = constants.%C
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(@I.%Self: %I.type) {
 // CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)]
+// CHECK:STDOUT:   %C: type = class_type @C, @C(%Self) [symbolic = %C (constants.%C)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn() {
 // CHECK:STDOUT:   !entry:
-// CHECK:STDOUT:     %C.decl: type = class_decl @C [concrete = constants.%C.a2d] {} {}
+// CHECK:STDOUT:     %C.decl: type = class_decl @C [symbolic = @F.%C (constants.%C)] {} {}
 // CHECK:STDOUT:     impl_decl @impl [concrete] {} {
-// CHECK:STDOUT:       %C.ref.loc16_10: type = name_ref C, @F.%C.decl [concrete = constants.%C.a2d]
-// CHECK:STDOUT:       %I.ref.loc16: type = name_ref I, file.%I.decl [concrete = constants.%I.type]
+// CHECK:STDOUT:       %C.ref.loc12_10: type = name_ref C, @F.%C.decl [symbolic = %C (constants.%C)]
+// CHECK:STDOUT:       %I.ref.loc12: type = name_ref I, file.%I.decl [concrete = constants.%I.type]
 // CHECK:STDOUT:       %.Self.1: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self]
-// CHECK:STDOUT:       %.Self.ref.loc16: %I.type = name_ref .Self, %.Self.1 [symbolic_self = constants.%.Self]
-// CHECK:STDOUT:       %U.ref.loc16: %I.assoc_type = name_ref U, @U.%assoc0 [concrete = constants.%assoc0]
-// CHECK:STDOUT:       %.Self.as_type.loc16: type = facet_access_type %.Self.ref.loc16 [symbolic_self = constants.%.Self.as_type]
-// CHECK:STDOUT:       %.loc16_23: type = converted %.Self.ref.loc16, %.Self.as_type.loc16 [symbolic_self = constants.%.Self.as_type]
-// CHECK:STDOUT:       %.Self.as_wit.iface0.loc16: <witness> = facet_access_witness %.Self.ref.loc16, element0 [symbolic_self = constants.%.Self.as_wit.iface0]
-// CHECK:STDOUT:       %impl.elem0.loc16: type = impl_witness_access %.Self.as_wit.iface0.loc16, element0 [symbolic_self = constants.%impl.elem0]
-// CHECK:STDOUT:       %C.ref.loc16_28: type = name_ref C, @F.%C.decl [concrete = constants.%C.a2d]
-// CHECK:STDOUT:       %.loc16_17: type = where_expr %.Self.1 [concrete = constants.%I_where.type] {
-// CHECK:STDOUT:         requirement_rewrite %impl.elem0.loc16, %C.ref.loc16_28
+// CHECK:STDOUT:       %.Self.ref.loc12: %I.type = name_ref .Self, %.Self.1 [symbolic_self = constants.%.Self]
+// CHECK:STDOUT:       %U.ref.loc12: %I.assoc_type = name_ref U, @U.%assoc0 [concrete = constants.%assoc0]
+// CHECK:STDOUT:       %.Self.as_type.loc12: type = facet_access_type %.Self.ref.loc12 [symbolic_self = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.loc12_23: type = converted %.Self.ref.loc12, %.Self.as_type.loc12 [symbolic_self = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.Self.as_wit.iface0.loc12: <witness> = facet_access_witness %.Self.ref.loc12, element0 [symbolic_self = constants.%.Self.as_wit.iface0]
+// CHECK:STDOUT:       %impl.elem0.loc12: type = impl_witness_access %.Self.as_wit.iface0.loc12, element0 [symbolic_self = constants.%impl.elem0]
+// CHECK:STDOUT:       %C.ref.loc12_28: type = name_ref C, @F.%C.decl [symbolic = %C (constants.%C)]
+// CHECK:STDOUT:       %.loc12_17: type = where_expr %.Self.1 [symbolic = %I_where.type (constants.%I_where.type)] {
+// CHECK:STDOUT:         requirement_rewrite %impl.elem0.loc12, %C.ref.loc12_28
 // CHECK:STDOUT:       }
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %I.impl_witness_table = impl_witness_table (%impl_witness_assoc_constant, <error>), @impl [concrete]
 // CHECK:STDOUT:     %I.impl_witness: <witness> = impl_witness %I.impl_witness_table, @impl(constants.%Self) [symbolic = @impl.%I.impl_witness (constants.%I.impl_witness)]
-// CHECK:STDOUT:     %impl_witness_assoc_constant: type = impl_witness_assoc_constant constants.%C.a2d [concrete = constants.%C.a2d]
+// CHECK:STDOUT:     %impl_witness_assoc_constant: type = impl_witness_assoc_constant constants.%C [symbolic = @impl.%C (constants.%C)]
 // CHECK:STDOUT:     impl_decl @impl [concrete] {} {
-// CHECK:STDOUT:       %C.ref.loc18_10: type = name_ref C, @F.%C.decl [concrete = constants.%C.a2d]
-// CHECK:STDOUT:       %I.ref.loc18: type = name_ref I, file.%I.decl [concrete = constants.%I.type]
+// CHECK:STDOUT:       %C.ref.loc21_10: type = name_ref C, @F.%C.decl [symbolic = %C (constants.%C)]
+// CHECK:STDOUT:       %I.ref.loc21: type = name_ref I, file.%I.decl [concrete = constants.%I.type]
 // CHECK:STDOUT:       %.Self.2: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self]
-// CHECK:STDOUT:       %.Self.ref.loc18: %I.type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self]
-// CHECK:STDOUT:       %U.ref.loc18: %I.assoc_type = name_ref U, @U.%assoc0 [concrete = constants.%assoc0]
-// CHECK:STDOUT:       %.Self.as_type.loc18: type = facet_access_type %.Self.ref.loc18 [symbolic_self = constants.%.Self.as_type]
-// CHECK:STDOUT:       %.loc18_23: type = converted %.Self.ref.loc18, %.Self.as_type.loc18 [symbolic_self = constants.%.Self.as_type]
-// CHECK:STDOUT:       %.Self.as_wit.iface0.loc18: <witness> = facet_access_witness %.Self.ref.loc18, element0 [symbolic_self = constants.%.Self.as_wit.iface0]
-// CHECK:STDOUT:       %impl.elem0.loc18: type = impl_witness_access %.Self.as_wit.iface0.loc18, element0 [symbolic_self = constants.%impl.elem0]
-// CHECK:STDOUT:       %C.ref.loc18_28: type = name_ref C, @F.%C.decl [concrete = constants.%C.a2d]
-// CHECK:STDOUT:       %.loc18_17: type = where_expr %.Self.2 [concrete = constants.%I_where.type] {
-// CHECK:STDOUT:         requirement_rewrite %impl.elem0.loc18, %C.ref.loc18_28
+// CHECK:STDOUT:       %.Self.ref.loc21: %I.type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self]
+// CHECK:STDOUT:       %U.ref.loc21: %I.assoc_type = name_ref U, @U.%assoc0 [concrete = constants.%assoc0]
+// CHECK:STDOUT:       %.Self.as_type.loc21: type = facet_access_type %.Self.ref.loc21 [symbolic_self = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.loc21_23: type = converted %.Self.ref.loc21, %.Self.as_type.loc21 [symbolic_self = constants.%.Self.as_type]
+// CHECK:STDOUT:       %.Self.as_wit.iface0.loc21: <witness> = facet_access_witness %.Self.ref.loc21, element0 [symbolic_self = constants.%.Self.as_wit.iface0]
+// CHECK:STDOUT:       %impl.elem0.loc21: type = impl_witness_access %.Self.as_wit.iface0.loc21, element0 [symbolic_self = constants.%impl.elem0]
+// CHECK:STDOUT:       %C.ref.loc21_28: type = name_ref C, @F.%C.decl [symbolic = %C (constants.%C)]
+// CHECK:STDOUT:       %.loc21_17: type = where_expr %.Self.2 [symbolic = %I_where.type (constants.%I_where.type)] {
+// CHECK:STDOUT:         requirement_rewrite %impl.elem0.loc21, %C.ref.loc21_28
 // CHECK:STDOUT:       }
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     return
@@ -2157,11 +2188,18 @@ interface I {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl(constants.%Self) {
 // CHECK:STDOUT:   %Self => constants.%Self
+// CHECK:STDOUT:   %C => constants.%C
+// CHECK:STDOUT:   %I_where.type => constants.%I_where.type
+// CHECK:STDOUT:   %require_complete => constants.%require_complete
 // CHECK:STDOUT:   %I.impl_witness => constants.%I.impl_witness
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @C(@impl.%Self) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl(%Self) {}
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @C(@F.%Self) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: --- include_files/facet_types.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {

+ 21 - 22
toolchain/check/testdata/interface/fail_todo_define_default_fn_out_of_line.carbon

@@ -201,8 +201,7 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; }
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Interface.type: type = facet_type <@Interface> [concrete]
 // CHECK:STDOUT:   %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %C.1ea: type = class_type @C [concrete]
-// CHECK:STDOUT:   %C.7e5: type = class_type @C, @C(%Self) [symbolic]
+// CHECK:STDOUT:   %C: type = class_type @C, @C(%Self) [symbolic]
 // CHECK:STDOUT:   %U: type = bind_symbolic_name U, 1 [symbolic]
 // CHECK:STDOUT:   %U.patt: type = symbolic_binding_pattern U, 1 [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F, @C(%Self) [symbolic]
@@ -210,7 +209,7 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; }
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
 // CHECK:STDOUT:   %require_complete.b54: <witness> = require_complete_type %U [symbolic]
-// CHECK:STDOUT:   %require_complete.e44: <witness> = require_complete_type %C.7e5 [symbolic]
+// CHECK:STDOUT:   %require_complete.e44: <witness> = require_complete_type %C [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -228,8 +227,8 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; }
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %Interface.decl: type = interface_decl @Interface [concrete = constants.%Interface.type] {} {}
 // CHECK:STDOUT:   %F.decl: @C.%F.type (%F.type) = fn_decl @F [symbolic = constants.%F] {
-// CHECK:STDOUT:     %self.patt: @F.%C (%C.7e5) = binding_pattern self
-// CHECK:STDOUT:     %self.param_patt: @F.%C (%C.7e5) = value_param_pattern %self.patt, call_param0
+// CHECK:STDOUT:     %self.patt: @F.%C (%C) = binding_pattern self
+// CHECK:STDOUT:     %self.param_patt: @F.%C (%C) = value_param_pattern %self.patt, call_param0
 // CHECK:STDOUT:     %U.patt.loc20: type = symbolic_binding_pattern U, 1 [symbolic = %U.patt.loc14 (constants.%U.patt)]
 // CHECK:STDOUT:     %u.patt: @F.%U.loc14_22.1 (%U) = binding_pattern u
 // CHECK:STDOUT:     %u.param_patt: @F.%U.loc14_22.1 (%U) = value_param_pattern %u.patt, call_param1
@@ -237,12 +236,12 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; }
 // CHECK:STDOUT:     %return.param_patt: @F.%U.loc14_22.1 (%U) = out_param_pattern %return.patt, call_param2
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %U.ref.loc20_49: type = name_ref U, %U.loc20 [symbolic = %U.loc14_22.1 (constants.%U)]
-// CHECK:STDOUT:     %self.param.loc20: @F.%C (%C.7e5) = value_param call_param0
-// CHECK:STDOUT:     %.loc20_24.1: type = splice_block %Self.ref.loc20 [symbolic = %C (constants.%C.7e5)] {
-// CHECK:STDOUT:       %.loc20_24.2: type = specific_constant constants.%C.7e5, @C(constants.%Self) [symbolic = %C (constants.%C.7e5)]
-// CHECK:STDOUT:       %Self.ref.loc20: type = name_ref Self, %.loc20_24.2 [symbolic = %C (constants.%C.7e5)]
+// CHECK:STDOUT:     %self.param.loc20: @F.%C (%C) = value_param call_param0
+// CHECK:STDOUT:     %.loc20_24.1: type = splice_block %Self.ref.loc20 [symbolic = %C (constants.%C)] {
+// CHECK:STDOUT:       %.loc20_24.2: type = specific_constant constants.%C, @C(constants.%Self) [symbolic = %C (constants.%C)]
+// CHECK:STDOUT:       %Self.ref.loc20: type = name_ref Self, %.loc20_24.2 [symbolic = %C (constants.%C)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %self.loc20: @F.%C (%C.7e5) = bind_name self, %self.param.loc20
+// CHECK:STDOUT:     %self.loc20: @F.%C (%C) = bind_name self, %self.param.loc20
 // CHECK:STDOUT:     %U.loc20: type = bind_symbolic_name U, 1 [symbolic = %U.loc14_22.1 (constants.%U)]
 // CHECK:STDOUT:     %u.param.loc20: @F.%U.loc14_22.1 (%U) = value_param call_param1
 // CHECK:STDOUT:     %U.ref.loc20_43: type = name_ref U, %U.loc20 [symbolic = %U.loc14_22.1 (constants.%U)]
@@ -254,7 +253,7 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Interface {
 // CHECK:STDOUT:   %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
-// CHECK:STDOUT:   %C.decl: type = class_decl @C [concrete = constants.%C.1ea] {} {}
+// CHECK:STDOUT:   %C.decl: type = class_decl @C [symbolic = constants.%C] {} {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self
@@ -270,8 +269,8 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; }
 // CHECK:STDOUT:
 // CHECK:STDOUT:   class {
 // CHECK:STDOUT:     %F.decl: @C.%F.type (%F.type) = fn_decl @F [symbolic = @C.%F (constants.%F)] {
-// CHECK:STDOUT:       %self.patt: @F.%C (%C.7e5) = binding_pattern self
-// CHECK:STDOUT:       %self.param_patt: @F.%C (%C.7e5) = value_param_pattern %self.patt, call_param0
+// CHECK:STDOUT:       %self.patt: @F.%C (%C) = binding_pattern self
+// CHECK:STDOUT:       %self.param_patt: @F.%C (%C) = value_param_pattern %self.patt, call_param0
 // CHECK:STDOUT:       %U.patt.loc20: type = symbolic_binding_pattern U, 1 [symbolic = %U.patt.loc14 (constants.%U.patt)]
 // CHECK:STDOUT:       %u.patt: @F.%U.loc14_22.1 (%U) = binding_pattern u
 // CHECK:STDOUT:       %u.param_patt: @F.%U.loc14_22.1 (%U) = value_param_pattern %u.patt, call_param1
@@ -279,12 +278,12 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; }
 // CHECK:STDOUT:       %return.param_patt: @F.%U.loc14_22.1 (%U) = out_param_pattern %return.patt, call_param2
 // CHECK:STDOUT:     } {
 // CHECK:STDOUT:       %U.ref.loc14_41: type = name_ref U, %U.loc14_22.2 [symbolic = %U.loc14_22.1 (constants.%U)]
-// CHECK:STDOUT:       %self.param.loc14: @F.%C (%C.7e5) = value_param call_param0
-// CHECK:STDOUT:       %.loc14_16.1: type = splice_block %Self.ref.loc14 [symbolic = %C (constants.%C.7e5)] {
-// CHECK:STDOUT:         %.loc14_16.2: type = specific_constant constants.%C.7e5, @C(constants.%Self) [symbolic = %C (constants.%C.7e5)]
-// CHECK:STDOUT:         %Self.ref.loc14: type = name_ref Self, %.loc14_16.2 [symbolic = %C (constants.%C.7e5)]
+// CHECK:STDOUT:       %self.param.loc14: @F.%C (%C) = value_param call_param0
+// CHECK:STDOUT:       %.loc14_16.1: type = splice_block %Self.ref.loc14 [symbolic = %C (constants.%C)] {
+// CHECK:STDOUT:         %.loc14_16.2: type = specific_constant constants.%C, @C(constants.%Self) [symbolic = %C (constants.%C)]
+// CHECK:STDOUT:         %Self.ref.loc14: type = name_ref Self, %.loc14_16.2 [symbolic = %C (constants.%C)]
 // CHECK:STDOUT:       }
-// CHECK:STDOUT:       %self.loc14: @F.%C (%C.7e5) = bind_name self, %self.param.loc14
+// CHECK:STDOUT:       %self.loc14: @F.%C (%C) = bind_name self, %self.param.loc14
 // CHECK:STDOUT:       %U.loc14_22.2: type = bind_symbolic_name U, 1 [symbolic = %U.loc14_22.1 (constants.%U)]
 // CHECK:STDOUT:       %u.param.loc14: @F.%U.loc14_22.1 (%U) = value_param call_param1
 // CHECK:STDOUT:       %U.ref.loc14_35: type = name_ref U, %U.loc14_22.2 [symbolic = %U.loc14_22.1 (constants.%U)]
@@ -297,14 +296,14 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; }
 // CHECK:STDOUT:     complete_type_witness = %complete_type
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
-// CHECK:STDOUT:     .Self = constants.%C.7e5
+// CHECK:STDOUT:     .Self = constants.%C
 // CHECK:STDOUT:     .F = %F.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic fn @F(@Interface.%Self: %Interface.type, %U.loc14_22.2: type) {
 // CHECK:STDOUT:   %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)]
-// CHECK:STDOUT:   %C: type = class_type @C, @C(%Self) [symbolic = %C (constants.%C.7e5)]
+// CHECK:STDOUT:   %C: type = class_type @C, @C(%Self) [symbolic = %C (constants.%C)]
 // CHECK:STDOUT:   %U.loc14_22.1: type = bind_symbolic_name U, 1 [symbolic = %U.loc14_22.1 (constants.%U)]
 // CHECK:STDOUT:   %U.patt.loc14: type = symbolic_binding_pattern U, 1 [symbolic = %U.patt.loc14 (constants.%U.patt)]
 // CHECK:STDOUT:
@@ -312,7 +311,7 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; }
 // CHECK:STDOUT:   %require_complete.loc20_46: <witness> = require_complete_type %U.loc14_22.1 [symbolic = %require_complete.loc20_46 (constants.%require_complete.b54)]
 // CHECK:STDOUT:   %require_complete.loc20_22: <witness> = require_complete_type %C [symbolic = %require_complete.loc20_22 (constants.%require_complete.e44)]
 // CHECK:STDOUT:
-// CHECK:STDOUT:   fn[%self.param_patt: @F.%C (%C.7e5)](%U.patt.loc20: type, %u.param_patt: @F.%U.loc14_22.1 (%U)) -> @F.%U.loc14_22.1 (%U) {
+// CHECK:STDOUT:   fn[%self.param_patt: @F.%C (%C)](%U.patt.loc20: type, %u.param_patt: @F.%U.loc14_22.1 (%U)) -> @F.%U.loc14_22.1 (%U) {
 // CHECK:STDOUT:   !entry:
 // CHECK:STDOUT:     %u.ref: @F.%U.loc14_22.1 (%U) = name_ref u, %u.loc20
 // CHECK:STDOUT:     return %u.ref
@@ -328,7 +327,7 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%Self, constants.%U) {
 // CHECK:STDOUT:   %Self => constants.%Self
-// CHECK:STDOUT:   %C => constants.%C.7e5
+// CHECK:STDOUT:   %C => constants.%C
 // CHECK:STDOUT:   %U.loc14_22.1 => constants.%U
 // CHECK:STDOUT:   %U.patt.loc14 => constants.%U.patt
 // CHECK:STDOUT: }

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

@@ -41,9 +41,8 @@ interface Outer {
 // CHECK:STDOUT:   %F.5d3: %F.type.1ad = struct_value () [concrete]
 // CHECK:STDOUT:   %Outer.type: type = facet_type <@Outer> [concrete]
 // CHECK:STDOUT:   %Self.277: %Outer.type = bind_symbolic_name Self, 0 [symbolic]
-// CHECK:STDOUT:   %Inner.type.428: type = facet_type <@Inner> [concrete]
-// CHECK:STDOUT:   %Inner.type.3d8: type = facet_type <@Inner, @Inner(%Self.277)> [symbolic]
-// CHECK:STDOUT:   %Self.b60: %Inner.type.3d8 = bind_symbolic_name Self, 1 [symbolic]
+// CHECK:STDOUT:   %Inner.type: type = facet_type <@Inner, @Inner(%Self.277)> [symbolic]
+// CHECK:STDOUT:   %Self.b60: %Inner.type = bind_symbolic_name Self, 1 [symbolic]
 // CHECK:STDOUT:   %F.type.82c77c.1: type = fn_type @F.2, @Inner(%Self.277) [symbolic]
 // CHECK:STDOUT:   %F.9789e2.1: %F.type.82c77c.1 = struct_value () [symbolic]
 // CHECK:STDOUT:   %F.type.82c77c.2: type = fn_type @F.3, @Inner(%Self.277) [symbolic]
@@ -71,7 +70,7 @@ interface Outer {
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Outer {
 // CHECK:STDOUT:   %Self: %Outer.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.277]
-// CHECK:STDOUT:   %Inner.decl: type = interface_decl @Inner [concrete = constants.%Inner.type.428] {} {}
+// CHECK:STDOUT:   %Inner.decl: type = interface_decl @Inner [symbolic = constants.%Inner.type] {} {}
 // CHECK:STDOUT:   %F.decl: %F.type.82c77c.2 = fn_decl @F.3 [symbolic = constants.%F.9789e2.2] {} {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
@@ -83,13 +82,13 @@ interface Outer {
 // CHECK:STDOUT: generic interface @Inner(@Outer.%Self: %Outer.type) {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %Self.2: %Outer.type = bind_symbolic_name Self, 0 [symbolic = %Self.2 (constants.%Self.277)]
-// CHECK:STDOUT:   %Inner.type: type = facet_type <@Inner, @Inner(%Self.2)> [symbolic = %Inner.type (constants.%Inner.type.3d8)]
-// CHECK:STDOUT:   %Self.3: @Inner.%Inner.type (%Inner.type.3d8) = bind_symbolic_name Self, 1 [symbolic = %Self.3 (constants.%Self.b60)]
+// CHECK:STDOUT:   %Inner.type: type = facet_type <@Inner, @Inner(%Self.2)> [symbolic = %Inner.type (constants.%Inner.type)]
+// CHECK:STDOUT:   %Self.3: @Inner.%Inner.type (%Inner.type) = bind_symbolic_name Self, 1 [symbolic = %Self.3 (constants.%Self.b60)]
 // CHECK:STDOUT:   %F.type: type = fn_type @F.2, @Inner(%Self.2) [symbolic = %F.type (constants.%F.type.82c77c.1)]
 // CHECK:STDOUT:   %F: @Inner.%F.type (%F.type.82c77c.1) = struct_value () [symbolic = %F (constants.%F.9789e2.1)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
-// CHECK:STDOUT:     %Self.1: @Inner.%Inner.type (%Inner.type.3d8) = bind_symbolic_name Self, 1 [symbolic = %Self.3 (constants.%Self.b60)]
+// CHECK:STDOUT:     %Self.1: @Inner.%Inner.type (%Inner.type) = bind_symbolic_name Self, 1 [symbolic = %Self.3 (constants.%Self.b60)]
 // CHECK:STDOUT:     %F.decl: @Inner.%F.type (%F.type.82c77c.1) = fn_decl @F.2 [symbolic = @Inner.%F (constants.%F.9789e2.1)] {} {}
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
@@ -108,11 +107,11 @@ interface Outer {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: generic fn @F.2(@Outer.%Self: %Outer.type, @Inner.%Self.1: @Inner.%Inner.type (%Inner.type.3d8)) {
+// CHECK:STDOUT: generic fn @F.2(@Outer.%Self: %Outer.type, @Inner.%Self.1: @Inner.%Inner.type (%Inner.type)) {
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: generic fn @F.3(@Outer.%Self: %Outer.type, @Inner.%Self.1: @Inner.%Inner.type (%Inner.type.3d8)) {
+// CHECK:STDOUT: generic fn @F.3(@Outer.%Self: %Outer.type, @Inner.%Self.1: @Inner.%Inner.type (%Inner.type)) {
 // CHECK:STDOUT:   fn();
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -121,7 +120,7 @@ interface Outer {
 // CHECK:STDOUT: specific @Inner(constants.%Self.277) {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %Self.2 => constants.%Self.277
-// CHECK:STDOUT:   %Inner.type => constants.%Inner.type.3d8
+// CHECK:STDOUT:   %Inner.type => constants.%Inner.type
 // CHECK:STDOUT:   %Self.3 => constants.%Self.b60
 // CHECK:STDOUT:   %F.type => constants.%F.type.82c77c.1
 // CHECK:STDOUT:   %F => constants.%F.9789e2.1

+ 19 - 6
toolchain/check/testdata/interface/no_prelude/generic_vs_params.carbon

@@ -86,7 +86,6 @@ interface Bar[T:! type] {}
 // CHECK:STDOUT:   %C.type: type = generic_class_type @C [concrete]
 // CHECK:STDOUT:   %C.generic: %C.type = struct_value () [concrete]
 // CHECK:STDOUT:   %C.f2e: type = class_type @C, @C(%T) [symbolic]
-// CHECK:STDOUT:   %GenericNoParams.type.f90: type = facet_type <@GenericNoParams> [concrete]
 // CHECK:STDOUT:   %GenericNoParams.type.b79: type = facet_type <@GenericNoParams, @GenericNoParams(%T)> [symbolic]
 // CHECK:STDOUT:   %Self.0f6: %GenericNoParams.type.b79 = bind_symbolic_name Self, 1 [symbolic]
 // CHECK:STDOUT:   %U: type = bind_symbolic_name U, 1 [symbolic]
@@ -104,8 +103,10 @@ interface Bar[T:! type] {}
 // CHECK:STDOUT:   %Self.2f7: %GenericAndParams.type.4b6 = bind_symbolic_name Self, 1 [symbolic]
 // CHECK:STDOUT:   %GenericAndParams.impl_witness.c06: <witness> = impl_witness file.%GenericAndParams.impl_witness_table.loc16 [concrete]
 // CHECK:STDOUT:   %C.fac: type = class_type @C, @C(%X) [concrete]
+// CHECK:STDOUT:   %GenericNoParams.type.b7e: type = facet_type <@GenericNoParams, @GenericNoParams(%X)> [concrete]
 // CHECK:STDOUT:   %GenericAndParams.type.425: type = generic_interface_type @GenericAndParams.2, @C(%X) [concrete]
 // CHECK:STDOUT:   %GenericAndParams.generic.b50: %GenericAndParams.type.425 = struct_value () [concrete]
+// CHECK:STDOUT:   %Self.108: %GenericNoParams.type.b7e = bind_symbolic_name Self, 1 [symbolic]
 // CHECK:STDOUT:   %GenericNoParams.impl_witness: <witness> = impl_witness file.%GenericNoParams.impl_witness_table [concrete]
 // CHECK:STDOUT:   %GenericAndParams.type.79c: type = facet_type <@GenericAndParams.2, @GenericAndParams.2(%X, %X)> [concrete]
 // CHECK:STDOUT:   %Self.f51: %GenericAndParams.type.79c = bind_symbolic_name Self, 2 [symbolic]
@@ -154,14 +155,15 @@ interface Bar[T:! type] {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %GenericAndParams.impl_witness_table.loc16 = impl_witness_table (), @impl.87f [concrete]
 // CHECK:STDOUT:   %GenericAndParams.impl_witness.loc16: <witness> = impl_witness %GenericAndParams.impl_witness_table.loc16 [concrete = constants.%GenericAndParams.impl_witness.c06]
-// CHECK:STDOUT:   impl_decl @impl.3f8 [concrete] {} {
+// CHECK:STDOUT:   impl_decl @impl.cd5 [concrete] {} {
 // CHECK:STDOUT:     %X.ref.loc17_6: type = name_ref X, file.%X.decl [concrete = constants.%X]
 // CHECK:STDOUT:     %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic]
 // CHECK:STDOUT:     %X.ref.loc17_13: type = name_ref X, file.%X.decl [concrete = constants.%X]
 // CHECK:STDOUT:     %C: type = class_type @C, @C(constants.%X) [concrete = constants.%C.fac]
-// CHECK:STDOUT:     %GenericNoParams.ref: type = name_ref GenericNoParams, @C.%GenericNoParams.decl [concrete = constants.%GenericNoParams.type.f90]
+// CHECK:STDOUT:     %.loc17: type = specific_constant @C.%GenericNoParams.decl, @C(constants.%X) [concrete = constants.%GenericNoParams.type.b7e]
+// CHECK:STDOUT:     %GenericNoParams.ref: type = name_ref GenericNoParams, %.loc17 [concrete = constants.%GenericNoParams.type.b7e]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %GenericNoParams.impl_witness_table = impl_witness_table (), @impl.3f8 [concrete]
+// CHECK:STDOUT:   %GenericNoParams.impl_witness_table = impl_witness_table (), @impl.cd5 [concrete]
 // CHECK:STDOUT:   %GenericNoParams.impl_witness: <witness> = impl_witness %GenericNoParams.impl_witness_table [concrete = constants.%GenericNoParams.impl_witness]
 // CHECK:STDOUT:   impl_decl @impl.15f [concrete] {} {
 // CHECK:STDOUT:     %X.ref.loc18_6: type = name_ref X, file.%X.decl [concrete = constants.%X]
@@ -258,7 +260,7 @@ interface Bar[T:! type] {}
 // CHECK:STDOUT:   witness = file.%GenericAndParams.impl_witness.loc16
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: impl @impl.3f8: %X.ref.loc17_6 as %GenericNoParams.ref {
+// CHECK:STDOUT: impl @impl.cd5: %X.ref.loc17_6 as %GenericNoParams.ref {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   witness = file.%GenericNoParams.impl_witness
 // CHECK:STDOUT: }
@@ -273,11 +275,12 @@ interface Bar[T:! type] {}
 // CHECK:STDOUT:   %T.patt.loc8_9.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_9.2 (constants.%T.patt)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %GenericNoParams.type: type = facet_type <@GenericNoParams, @GenericNoParams(%T.loc8_9.2)> [symbolic = %GenericNoParams.type (constants.%GenericNoParams.type.b79)]
 // CHECK:STDOUT:   %GenericAndParams.type: type = generic_interface_type @GenericAndParams.2, @C(%T.loc8_9.2) [symbolic = %GenericAndParams.type (constants.%GenericAndParams.type.597)]
 // CHECK:STDOUT:   %GenericAndParams.generic: @C.%GenericAndParams.type (%GenericAndParams.type.597) = struct_value () [symbolic = %GenericAndParams.generic (constants.%GenericAndParams.generic.2ec)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   class {
-// CHECK:STDOUT:     %GenericNoParams.decl: type = interface_decl @GenericNoParams [concrete = constants.%GenericNoParams.type.f90] {} {}
+// CHECK:STDOUT:     %GenericNoParams.decl: type = interface_decl @GenericNoParams [symbolic = @C.%GenericNoParams.type (constants.%GenericNoParams.type.b79)] {} {}
 // CHECK:STDOUT:     %GenericAndParams.decl: @C.%GenericAndParams.type (%GenericAndParams.type.597) = interface_decl @GenericAndParams.2 [symbolic = @C.%GenericAndParams.generic (constants.%GenericAndParams.generic.2ec)] {
 // CHECK:STDOUT:       %U.patt.loc10_30.1: type = symbolic_binding_pattern U, 1 [symbolic = %U.patt.loc10_30.2 (constants.%U.patt)]
 // CHECK:STDOUT:     } {
@@ -326,6 +329,8 @@ interface Bar[T:! type] {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @GenericAndParams.2(%T, %U.loc10_30.2) {}
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @GenericNoParams(@C.%T.loc8_9.2) {}
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @C(%T.loc8_9.2) {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @GenericAndParams.1(constants.%X) {
@@ -342,10 +347,18 @@ interface Bar[T:! type] {}
 // CHECK:STDOUT:   %T.patt.loc8_9.2 => constants.%T.patt
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %GenericNoParams.type => constants.%GenericNoParams.type.b7e
 // CHECK:STDOUT:   %GenericAndParams.type => constants.%GenericAndParams.type.425
 // CHECK:STDOUT:   %GenericAndParams.generic => constants.%GenericAndParams.generic.b50
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @GenericNoParams(constants.%X) {
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %T => constants.%X
+// CHECK:STDOUT:   %GenericNoParams.type => constants.%GenericNoParams.type.b7e
+// CHECK:STDOUT:   %Self.2 => constants.%Self.108
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: specific @GenericAndParams.2(constants.%X, constants.%X) {
 // CHECK:STDOUT:   %U.loc10_30.2 => constants.%X
 // CHECK:STDOUT:   %U.patt.loc10_30.2 => constants.%U.patt