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

Avoid witnesses in redecls when handling errors in handle_impl (#5409)

When we fill the witness table with errors, set the witness id to an
error too, which signals to impl lookups to not use the impl.

Make the use of the `Impl` from the store more consistent once it's been
added to the store (or known to be there already).
Dana Jansens 1 год назад
Родитель
Сommit
90898a8e19

+ 39 - 34
toolchain/check/handle_impl.cpp

@@ -393,7 +393,6 @@ static auto BuildImplDecl(Context& context, Parse::AnyImplDeclId node_id,
                                 context, impl_decl_id, constraint_type_inst_id),
                             .is_final = is_final}};
   // Add the impl declaration.
-  bool invalid_redeclaration = false;
   auto lookup_bucket_ref = context.impls().GetOrAddLookupBucket(impl_info);
   // TODO: Detect two impl declarations with the same self type and interface,
   // and issue an error if they don't match.
@@ -404,7 +403,7 @@ static auto BuildImplDecl(Context& context, Parse::AnyImplDeclId node_id,
       } else {
         // IsValidImplRedecl() has issued a diagnostic, avoid generating more
         // diagnostics for this declaration.
-        invalid_redeclaration = true;
+        impl_info.witness_id = SemIR::ErrorInst::InstId;
       }
       break;
     }
@@ -413,18 +412,22 @@ static auto BuildImplDecl(Context& context, Parse::AnyImplDeclId node_id,
   // Create a new impl if this isn't a valid redeclaration.
   if (!impl_decl.impl_id.has_value()) {
     impl_info.generic_id = BuildGeneric(context, impl_decl_id);
-    if (impl_info.interface.interface_id.has_value()) {
-      impl_info.witness_id =
-          ImplWitnessForDeclaration(context, impl_info, is_definition);
-    } else {
-      impl_info.witness_id = SemIR::ErrorInst::InstId;
-      // TODO: We might also want to mark that the name scope for the impl has
-      // an error -- at least once we start making name lookups within the impl
-      // also look into the facet (eg, so you can name associated constants from
-      // within the impl).
+    if (impl_info.witness_id != SemIR::ErrorInst::InstId) {
+      if (impl_info.interface.interface_id.has_value()) {
+        impl_info.witness_id =
+            ImplWitnessForDeclaration(context, impl_info, is_definition);
+      } else {
+        impl_info.witness_id = SemIR::ErrorInst::InstId;
+        // TODO: We might also want to mark that the name scope for the impl has
+        // an error -- at least once we start making name lookups within the
+        // impl also look into the facet (eg, so you can name associated
+        // constants from within the impl).
+      }
     }
     FinishGenericDecl(context, SemIR::LocId(impl_decl_id),
                       impl_info.generic_id);
+    // From here on, use the `Impl` from the `ImplStore` instead of `impl_info`
+    // in order to make and see any changes to the `Impl`.
     impl_decl.impl_id = context.impls().Add(impl_info);
     lookup_bucket_ref.push_back(impl_decl.impl_id);
 
@@ -444,16 +447,20 @@ static auto BuildImplDecl(Context& context, Parse::AnyImplDeclId node_id,
         }
       }
     }
-    if (impl_info.generic_id.has_value() && !has_error_in_implicit_pattern &&
-        impl_info.witness_id != SemIR::ErrorInst::InstId) {
+
+    auto& stored_impl_info = context.impls().Get(impl_decl.impl_id);
+
+    if (stored_impl_info.generic_id.has_value() &&
+        !has_error_in_implicit_pattern &&
+        stored_impl_info.witness_id != SemIR::ErrorInst::InstId) {
       context.inst_block_stack().Push();
       auto deduced_specific_id = DeduceImplArguments(
           context, node_id,
-          DeduceImpl{.self_id = impl_info.self_id,
-                     .generic_id = impl_info.generic_id,
-                     .specific_id = impl_info.interface.specific_id},
-          context.constant_values().Get(impl_info.self_id),
-          impl_info.interface.specific_id);
+          DeduceImpl{.self_id = stored_impl_info.self_id,
+                     .generic_id = stored_impl_info.generic_id,
+                     .specific_id = stored_impl_info.interface.specific_id},
+          context.constant_values().Get(stored_impl_info.self_id),
+          stored_impl_info.interface.specific_id);
       // TODO: Deduce has side effects in the semir by generating `Converted`
       // instructions which we will not use here. We should stop generating
       // those when deducing for impl lookup, but for now we discard them by
@@ -472,15 +479,12 @@ static auto BuildImplDecl(Context& context, Parse::AnyImplDeclId node_id,
         context.emitter().Emit(loc, ImplUnusedBinding);
         // Don't try to match the impl at all, save us work and possible future
         // diagnostics.
-        FillImplWitnessWithErrors(context, impl_info);
-        context.impls().Get(impl_decl.impl_id).witness_id =
-            SemIR::ErrorInst::InstId;
+        FillImplWitnessWithErrors(context, stored_impl_info);
       }
     }
   } else {
-    auto prev_decl_generic_id =
-        context.impls().Get(impl_decl.impl_id).generic_id;
-    FinishGenericRedecl(context, prev_decl_generic_id);
+    auto& stored_impl_info = context.impls().Get(impl_decl.impl_id);
+    FinishGenericRedecl(context, stored_impl_info.generic_id);
   }
 
   // Write the impl ID into the ImplDecl.
@@ -489,32 +493,33 @@ static auto BuildImplDecl(Context& context, Parse::AnyImplDeclId node_id,
   // For an `extend impl` declaration, mark the impl as extending this `impl`.
   if (self_type_id != SemIR::ErrorInst::TypeId &&
       introducer.modifier_set.HasAnyOf(KeywordModifierSet::Extend)) {
+    auto& stored_impl_info = context.impls().Get(impl_decl.impl_id);
+
     auto extend_node = introducer.modifier_node_id(ModifierOrder::Extend);
-    if (impl_info.generic_id.has_value()) {
+    if (stored_impl_info.generic_id.has_value()) {
       constraint_type_inst_id = AddTypeInst<SemIR::SpecificConstant>(
           context, SemIR::LocId(constraint_type_inst_id),
           {.type_id = SemIR::TypeType::TypeId,
            .inst_id = constraint_type_inst_id,
-           .specific_id =
-               context.generics().GetSelfSpecific(impl_info.generic_id)});
+           .specific_id = context.generics().GetSelfSpecific(
+               stored_impl_info.generic_id)});
     }
     if (!ExtendImpl(context, extend_node, node_id, impl_decl.impl_id,
                     self_type_node, self_type_id, name.implicit_params_loc_id,
                     constraint_type_inst_id, constraint_type_id)) {
       // Don't allow the invalid impl to be used.
-      FillImplWitnessWithErrors(context, impl_info);
-      context.impls().Get(impl_decl.impl_id).witness_id =
-          SemIR::ErrorInst::InstId;
+      FillImplWitnessWithErrors(context, stored_impl_info);
     }
   }
 
   // Impl definitions are required in the same file as the declaration. We skip
   // this requirement if we've already issued an invalid redeclaration error, or
   // there is an error that would prevent the impl from being legal to define.
-  if (!is_definition && !invalid_redeclaration &&
-      context.impls().Get(impl_decl.impl_id).witness_id !=
-          SemIR::ErrorInst::InstId) {
-    context.definitions_required_by_decl().push_back(impl_decl_id);
+  if (!is_definition) {
+    auto& stored_impl_info = context.impls().Get(impl_decl.impl_id);
+    if (stored_impl_info.witness_id != SemIR::ErrorInst::InstId) {
+      context.definitions_required_by_decl().push_back(impl_decl_id);
+    }
   }
 
   return {impl_decl.impl_id, impl_decl_id};

+ 12 - 11
toolchain/check/impl.cpp

@@ -243,19 +243,20 @@ auto FinishImplWitness(Context& context, SemIR::ImplId impl_id) -> void {
 }
 
 auto FillImplWitnessWithErrors(Context& context, SemIR::Impl& impl) -> void {
-  if (impl.witness_id.has_value() &&
-      impl.witness_id != SemIR::ErrorInst::InstId) {
-    auto witness = context.insts().GetAs<SemIR::ImplWitness>(impl.witness_id);
-    auto witness_table = context.insts().GetAs<SemIR::ImplWitnessTable>(
-        witness.witness_table_id);
-    auto witness_block =
-        context.inst_blocks().GetMutable(witness_table.elements_id);
-    for (auto& elem : witness_block) {
-      if (elem == SemIR::ImplWitnessTablePlaceholder::TypeInstId) {
-        elem = SemIR::ErrorInst::InstId;
-      }
+  if (impl.witness_id == SemIR::ErrorInst::InstId) {
+    return;
+  }
+  auto witness = context.insts().GetAs<SemIR::ImplWitness>(impl.witness_id);
+  auto witness_table =
+      context.insts().GetAs<SemIR::ImplWitnessTable>(witness.witness_table_id);
+  auto witness_block =
+      context.inst_blocks().GetMutable(witness_table.elements_id);
+  for (auto& elem : witness_block) {
+    if (elem == SemIR::ImplWitnessTablePlaceholder::TypeInstId) {
+      elem = SemIR::ErrorInst::InstId;
     }
   }
+  impl.witness_id = SemIR::ErrorInst::InstId;
 }
 
 auto AssignImplIdInWitness(Context& context, SemIR::ImplId impl_id,

+ 2 - 1
toolchain/check/impl.h

@@ -23,7 +23,8 @@ auto ImplWitnessStartDefinition(Context& context, SemIR::Impl& impl) -> void;
 // Adds the function members to the witness for `impl`.
 auto FinishImplWitness(Context& context, SemIR::ImplId impl_id) -> void;
 
-// Sets all unset members of the witness for `impl` to the error instruction.
+// Sets all unset members of the witness for `impl` to the error instruction and
+// sets the witness id in the `Impl` to an error.
 auto FillImplWitnessWithErrors(Context& context, SemIR::Impl& impl) -> void;
 
 // Sets the `ImplId` in the `ImplWitnessTable`.

+ 5 - 8
toolchain/check/testdata/impl/fail_redefinition.carbon

@@ -30,8 +30,7 @@ impl i32 as I {}
 // CHECK:STDOUT:   %Int.type: type = generic_class_type @Int [concrete]
 // CHECK:STDOUT:   %Int.generic: %Int.type = struct_value () [concrete]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [concrete]
-// CHECK:STDOUT:   %I.impl_witness.684cdb.1: <witness> = impl_witness file.%I.impl_witness_table.loc13 [concrete]
-// CHECK:STDOUT:   %I.impl_witness.684cdb.2: <witness> = impl_witness file.%I.impl_witness_table.loc22 [concrete]
+// CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness file.%I.impl_witness_table [concrete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -55,15 +54,13 @@ impl i32 as I {}
 // CHECK:STDOUT:     %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
 // CHECK:STDOUT:     %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %I.impl_witness_table.loc13 = impl_witness_table (), @impl.a9ac64.1 [concrete]
-// CHECK:STDOUT:   %I.impl_witness.loc13: <witness> = impl_witness %I.impl_witness_table.loc13 [concrete = constants.%I.impl_witness.684cdb.1]
+// CHECK:STDOUT:   %I.impl_witness_table = impl_witness_table (), @impl.a9ac64.1 [concrete]
+// CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness %I.impl_witness_table [concrete = constants.%I.impl_witness]
 // CHECK:STDOUT:   impl_decl @impl.a9ac64.2 [concrete] {} {
 // 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:     %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %I.impl_witness_table.loc22 = impl_witness_table (), @impl.a9ac64.2 [concrete]
-// CHECK:STDOUT:   %I.impl_witness.loc22: <witness> = impl_witness %I.impl_witness_table.loc22 [concrete = constants.%I.impl_witness.684cdb.2]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @I {
@@ -76,11 +73,11 @@ impl i32 as I {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl.a9ac64.1: %i32 as %I.ref {
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   witness = file.%I.impl_witness.loc13
+// CHECK:STDOUT:   witness = file.%I.impl_witness
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl.a9ac64.2: %i32 as %I.ref {
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   witness = file.%I.impl_witness.loc22
+// CHECK:STDOUT:   witness = <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 14 - 24
toolchain/check/testdata/impl/min_prelude/generic_redeclaration.carbon

@@ -360,8 +360,7 @@ impl forall [T:! type] T as I {
 // CHECK:STDOUT:   %T: %I.type = bind_symbolic_name T, 0 [symbolic]
 // CHECK:STDOUT:   %pattern_type: type = pattern_type %I.type [concrete]
 // CHECK:STDOUT:   %T.as_type: type = facet_access_type %T [symbolic]
-// CHECK:STDOUT:   %J.impl_witness.a529f4.1: <witness> = impl_witness file.%J.impl_witness_table.loc7, @impl.bfd509.1(%T) [symbolic]
-// CHECK:STDOUT:   %J.impl_witness.a529f4.2: <witness> = impl_witness file.%J.impl_witness_table.loc15, @impl.bfd509.2(%T) [symbolic]
+// CHECK:STDOUT:   %J.impl_witness: <witness> = impl_witness file.%J.impl_witness_table, @impl.bfd509.1(%T) [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -389,8 +388,8 @@ impl forall [T:! type] T as I {
 // CHECK:STDOUT:     %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type]
 // CHECK:STDOUT:     %T.loc7_14.1: %I.type = bind_symbolic_name T, 0 [symbolic = %T.loc7_14.2 (constants.%T)]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %J.impl_witness_table.loc7 = impl_witness_table (), @impl.bfd509.1 [concrete]
-// CHECK:STDOUT:   %J.impl_witness.loc7: <witness> = impl_witness %J.impl_witness_table.loc7, @impl.bfd509.1(constants.%T) [symbolic = @impl.bfd509.1.%J.impl_witness (constants.%J.impl_witness.a529f4.1)]
+// CHECK:STDOUT:   %J.impl_witness_table = impl_witness_table (), @impl.bfd509.1 [concrete]
+// CHECK:STDOUT:   %J.impl_witness: <witness> = impl_witness %J.impl_witness_table, @impl.bfd509.1(constants.%T) [symbolic = @impl.bfd509.1.%J.impl_witness (constants.%J.impl_witness)]
 // CHECK:STDOUT:   impl_decl @impl.bfd509.2 [concrete] {
 // CHECK:STDOUT:     %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete]
 // CHECK:STDOUT:   } {
@@ -401,8 +400,6 @@ impl forall [T:! type] T as I {
 // CHECK:STDOUT:     %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type]
 // CHECK:STDOUT:     %T.loc15_14.1: %I.type = bind_symbolic_name T, 0 [symbolic = %T.loc15_14.2 (constants.%T)]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %J.impl_witness_table.loc15 = impl_witness_table (), @impl.bfd509.2 [concrete]
-// CHECK:STDOUT:   %J.impl_witness.loc15: <witness> = impl_witness %J.impl_witness_table.loc15, @impl.bfd509.2(constants.%T) [symbolic = @impl.bfd509.2.%J.impl_witness (constants.%J.impl_witness.a529f4.2)]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @I {
@@ -424,39 +421,37 @@ impl forall [T:! type] T as I {
 // CHECK:STDOUT: generic impl @impl.bfd509.1(%T.loc7_14.1: %I.type) {
 // CHECK:STDOUT:   %T.loc7_14.2: %I.type = bind_symbolic_name T, 0 [symbolic = %T.loc7_14.2 (constants.%T)]
 // CHECK:STDOUT:   %T.as_type.loc7_21.2: type = facet_access_type %T.loc7_14.2 [symbolic = %T.as_type.loc7_21.2 (constants.%T.as_type)]
-// CHECK:STDOUT:   %J.impl_witness: <witness> = impl_witness file.%J.impl_witness_table.loc7, @impl.bfd509.1(%T.loc7_14.2) [symbolic = %J.impl_witness (constants.%J.impl_witness.a529f4.1)]
+// CHECK:STDOUT:   %J.impl_witness: <witness> = impl_witness file.%J.impl_witness_table, @impl.bfd509.1(%T.loc7_14.2) [symbolic = %J.impl_witness (constants.%J.impl_witness)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
 // CHECK:STDOUT:   impl: %.loc7 as %J.ref {
 // CHECK:STDOUT:   !members:
-// CHECK:STDOUT:     witness = file.%J.impl_witness.loc7
+// CHECK:STDOUT:     witness = file.%J.impl_witness
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic impl @impl.bfd509.2(%T.loc15_14.1: %I.type) {
 // CHECK:STDOUT:   %T.loc15_14.2: %I.type = bind_symbolic_name T, 0 [symbolic = %T.loc15_14.2 (constants.%T)]
 // CHECK:STDOUT:   %T.as_type.loc15_21.2: type = facet_access_type %T.loc15_14.2 [symbolic = %T.as_type.loc15_21.2 (constants.%T.as_type)]
-// CHECK:STDOUT:   %J.impl_witness: <witness> = impl_witness file.%J.impl_witness_table.loc15, @impl.bfd509.2(%T.loc15_14.2) [symbolic = %J.impl_witness (constants.%J.impl_witness.a529f4.2)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
 // CHECK:STDOUT:   impl: %.loc15 as %J.ref {
 // CHECK:STDOUT:   !members:
-// CHECK:STDOUT:     witness = file.%J.impl_witness.loc15
+// CHECK:STDOUT:     witness = <error>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl.bfd509.1(constants.%T) {
 // CHECK:STDOUT:   %T.loc7_14.2 => constants.%T
 // CHECK:STDOUT:   %T.as_type.loc7_21.2 => constants.%T.as_type
-// CHECK:STDOUT:   %J.impl_witness => constants.%J.impl_witness.a529f4.1
+// CHECK:STDOUT:   %J.impl_witness => constants.%J.impl_witness
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl.bfd509.2(constants.%T) {
 // CHECK:STDOUT:   %T.loc15_14.2 => constants.%T
 // CHECK:STDOUT:   %T.as_type.loc15_21.2 => constants.%T.as_type
-// CHECK:STDOUT:   %J.impl_witness => constants.%J.impl_witness.a529f4.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- same_type_different_spelling.carbon
@@ -534,11 +529,10 @@ impl forall [T:! type] T as I {
 // CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %T: type = bind_symbolic_name T, 0 [symbolic]
 // CHECK:STDOUT:   %pattern_type.98f: type = pattern_type type [concrete]
-// CHECK:STDOUT:   %I.impl_witness.dad390.1: <witness> = impl_witness file.%I.impl_witness_table.loc4, @impl.2caff2.1(%T) [symbolic]
+// CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness file.%I.impl_witness_table, @impl.2caff2.1(%T) [symbolic]
 // CHECK:STDOUT:   %A.type: type = fn_type @A, @impl.2caff2.1(%T) [symbolic]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %A: %A.type = struct_value () [symbolic]
-// CHECK:STDOUT:   %I.impl_witness.dad390.2: <witness> = impl_witness file.%I.impl_witness_table.loc15, @impl.2caff2.2(%T) [symbolic]
 // CHECK:STDOUT:   %B.type: type = fn_type @B, @impl.2caff2.2(%T) [symbolic]
 // CHECK:STDOUT:   %B: %B.type = struct_value () [symbolic]
 // CHECK:STDOUT:   %pattern_type.cb1: type = pattern_type %empty_tuple.type [concrete]
@@ -570,8 +564,8 @@ impl forall [T:! type] T as I {
 // CHECK:STDOUT:     %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type]
 // CHECK:STDOUT:     %T.loc4_14.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_14.2 (constants.%T)]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %I.impl_witness_table.loc4 = impl_witness_table (), @impl.2caff2.1 [concrete]
-// CHECK:STDOUT:   %I.impl_witness.loc4: <witness> = impl_witness %I.impl_witness_table.loc4, @impl.2caff2.1(constants.%T) [symbolic = @impl.2caff2.1.%I.impl_witness (constants.%I.impl_witness.dad390.1)]
+// CHECK:STDOUT:   %I.impl_witness_table = impl_witness_table (), @impl.2caff2.1 [concrete]
+// CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness %I.impl_witness_table, @impl.2caff2.1(constants.%T) [symbolic = @impl.2caff2.1.%I.impl_witness (constants.%I.impl_witness)]
 // CHECK:STDOUT:   impl_decl @impl.2caff2.2 [concrete] {
 // CHECK:STDOUT:     %T.patt: %pattern_type.98f = symbolic_binding_pattern T, 0 [concrete]
 // CHECK:STDOUT:   } {
@@ -579,8 +573,6 @@ impl forall [T:! type] T as I {
 // CHECK:STDOUT:     %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type]
 // CHECK:STDOUT:     %T.loc15_14.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc15_14.2 (constants.%T)]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %I.impl_witness_table.loc15 = impl_witness_table (), @impl.2caff2.2 [concrete]
-// CHECK:STDOUT:   %I.impl_witness.loc15: <witness> = impl_witness %I.impl_witness_table.loc15, @impl.2caff2.2(constants.%T) [symbolic = @impl.2caff2.2.%I.impl_witness (constants.%I.impl_witness.dad390.2)]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @I {
@@ -593,7 +585,7 @@ impl forall [T:! type] T as I {
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic impl @impl.2caff2.1(%T.loc4_14.1: type) {
 // CHECK:STDOUT:   %T.loc4_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_14.2 (constants.%T)]
-// CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness file.%I.impl_witness_table.loc4, @impl.2caff2.1(%T.loc4_14.2) [symbolic = %I.impl_witness (constants.%I.impl_witness.dad390.1)]
+// CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness file.%I.impl_witness_table, @impl.2caff2.1(%T.loc4_14.2) [symbolic = %I.impl_witness (constants.%I.impl_witness)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %A.type: type = fn_type @A, @impl.2caff2.1(%T.loc4_14.2) [symbolic = %A.type (constants.%A.type)]
@@ -604,13 +596,12 @@ impl forall [T:! type] T as I {
 // CHECK:STDOUT:
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     .A = %A.decl
-// CHECK:STDOUT:     witness = file.%I.impl_witness.loc4
+// CHECK:STDOUT:     witness = file.%I.impl_witness
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic impl @impl.2caff2.2(%T.loc15_14.1: type) {
 // CHECK:STDOUT:   %T.loc15_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc15_14.2 (constants.%T)]
-// CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness file.%I.impl_witness_table.loc15, @impl.2caff2.2(%T.loc15_14.2) [symbolic = %I.impl_witness (constants.%I.impl_witness.dad390.2)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %B.type: type = fn_type @B, @impl.2caff2.2(%T.loc15_14.2) [symbolic = %B.type (constants.%B.type)]
@@ -645,7 +636,7 @@ impl forall [T:! type] T as I {
 // CHECK:STDOUT:     .B = %B.decl
 // CHECK:STDOUT:     .C = %C.decl
 // CHECK:STDOUT:     .D = %D.decl
-// CHECK:STDOUT:     witness = file.%I.impl_witness.loc15
+// CHECK:STDOUT:     witness = <error>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -702,7 +693,7 @@ impl forall [T:! type] T as I {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl.2caff2.1(constants.%T) {
 // CHECK:STDOUT:   %T.loc4_14.2 => constants.%T
-// CHECK:STDOUT:   %I.impl_witness => constants.%I.impl_witness.dad390.1
+// CHECK:STDOUT:   %I.impl_witness => constants.%I.impl_witness
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %A.type => constants.%A.type
@@ -713,7 +704,6 @@ impl forall [T:! type] T as I {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl.2caff2.2(constants.%T) {
 // CHECK:STDOUT:   %T.loc15_14.2 => constants.%T
-// CHECK:STDOUT:   %I.impl_witness => constants.%I.impl_witness.dad390.2
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %B.type => constants.%B.type

+ 5 - 8
toolchain/check/testdata/impl/no_prelude/fail_alias.carbon

@@ -33,8 +33,7 @@ impl AC as AI {}
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
 // 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.215123.1: <witness> = impl_witness file.%I.impl_witness_table.loc17 [concrete]
-// CHECK:STDOUT:   %I.impl_witness.215123.2: <witness> = impl_witness file.%I.impl_witness_table.loc26 [concrete]
+// CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness file.%I.impl_witness_table [concrete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -54,14 +53,12 @@ impl AC as AI {}
 // CHECK:STDOUT:     %AC.ref: type = name_ref AC, file.%AC [concrete = constants.%C]
 // CHECK:STDOUT:     %AI.ref: type = name_ref AI, file.%AI [concrete = constants.%I.type]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %I.impl_witness_table.loc17 = impl_witness_table (), @impl.7704ae.1 [concrete]
-// CHECK:STDOUT:   %I.impl_witness.loc17: <witness> = impl_witness %I.impl_witness_table.loc17 [concrete = constants.%I.impl_witness.215123.1]
+// CHECK:STDOUT:   %I.impl_witness_table = impl_witness_table (), @impl.7704ae.1 [concrete]
+// CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness %I.impl_witness_table [concrete = constants.%I.impl_witness]
 // CHECK:STDOUT:   impl_decl @impl.7704ae.2 [concrete] {} {
 // CHECK:STDOUT:     %AC.ref: type = name_ref AC, file.%AC [concrete = constants.%C]
 // CHECK:STDOUT:     %AI.ref: type = name_ref AI, file.%AI [concrete = constants.%I.type]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %I.impl_witness_table.loc26 = impl_witness_table (), @impl.7704ae.2 [concrete]
-// CHECK:STDOUT:   %I.impl_witness.loc26: <witness> = impl_witness %I.impl_witness_table.loc26 [concrete = constants.%I.impl_witness.215123.2]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @I {
@@ -74,12 +71,12 @@ impl AC as AI {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl.7704ae.1: %AC.ref as %AI.ref {
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   witness = file.%I.impl_witness.loc17
+// CHECK:STDOUT:   witness = file.%I.impl_witness
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl.7704ae.2: %AC.ref as %AI.ref {
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   witness = file.%I.impl_witness.loc26
+// CHECK:STDOUT:   witness = <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C {

+ 18 - 77
toolchain/check/testdata/impl/no_prelude/import_generic.carbon

@@ -259,17 +259,13 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
 // 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.1a9ed3.1: <witness> = impl_witness imports.%I.impl_witness_table.028, @impl.08450a.1(%T) [symbolic]
+// CHECK:STDOUT:   %I.impl_witness.1a9: <witness> = impl_witness imports.%I.impl_witness_table.028, @impl.08450a.1(%T) [symbolic]
 // CHECK:STDOUT:   %require_complete.cfe: <witness> = require_complete_type %I.type.325 [symbolic]
 // CHECK:STDOUT:   %ptr: type = ptr_type %T [symbolic]
 // CHECK:STDOUT:   %I.type.0e2: type = facet_type <@I, @I(%ptr)> [symbolic]
 // CHECK:STDOUT:   %require_complete.0e6: <witness> = require_complete_type %I.type.0e2 [symbolic]
-// CHECK:STDOUT:   %I.impl_witness.6ad3bf.1: <witness> = impl_witness imports.%I.impl_witness_table.e14, @impl.cd2fdc.1(%T) [symbolic]
+// CHECK:STDOUT:   %I.impl_witness.6ad: <witness> = impl_witness imports.%I.impl_witness_table.e14, @impl.cd2fdc.1(%T) [symbolic]
 // CHECK:STDOUT:   %Self.fb4: %I.type.0e2 = bind_symbolic_name Self, 1 [symbolic]
-// CHECK:STDOUT:   %I.impl_witness.1a9ed3.2: <witness> = impl_witness file.%I.impl_witness_table.loc8, @impl.08450a.2(%T) [symbolic]
-// CHECK:STDOUT:   %I.impl_witness.1a9ed3.3: <witness> = impl_witness file.%I.impl_witness_table.loc14, @impl.08450a.3(%T) [symbolic]
-// CHECK:STDOUT:   %I.impl_witness.6ad3bf.2: <witness> = impl_witness file.%I.impl_witness_table.loc20, @impl.cd2fdc.2(%T) [symbolic]
-// CHECK:STDOUT:   %I.impl_witness.6ad3bf.3: <witness> = impl_witness file.%I.impl_witness_table.loc26, @impl.cd2fdc.3(%T) [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -307,8 +303,6 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT:     %I.type.loc8_32.1: type = facet_type <@I, @I(constants.%T)> [symbolic = %I.type.loc8_32.2 (constants.%I.type.325)]
 // CHECK:STDOUT:     %T.loc8_14.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc8_14.2 (constants.%T)]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %I.impl_witness_table.loc8 = impl_witness_table (), @impl.08450a.2 [concrete]
-// CHECK:STDOUT:   %I.impl_witness.loc8: <witness> = impl_witness %I.impl_witness_table.loc8, @impl.08450a.2(constants.%T) [symbolic = @impl.08450a.2.%I.impl_witness (constants.%I.impl_witness.1a9ed3.2)]
 // CHECK:STDOUT:   impl_decl @impl.08450a.3 [concrete] {
 // CHECK:STDOUT:     %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete]
 // CHECK:STDOUT:   } {
@@ -318,8 +312,6 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT:     %I.type.loc14_32.1: type = facet_type <@I, @I(constants.%T)> [symbolic = %I.type.loc14_32.2 (constants.%I.type.325)]
 // CHECK:STDOUT:     %T.loc14_14.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc14_14.2 (constants.%T)]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %I.impl_witness_table.loc14 = impl_witness_table (), @impl.08450a.3 [concrete]
-// CHECK:STDOUT:   %I.impl_witness.loc14: <witness> = impl_witness %I.impl_witness_table.loc14, @impl.08450a.3(constants.%T) [symbolic = @impl.08450a.3.%I.impl_witness (constants.%I.impl_witness.1a9ed3.3)]
 // CHECK:STDOUT:   impl_decl @impl.cd2fdc.2 [concrete] {
 // CHECK:STDOUT:     %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete]
 // CHECK:STDOUT:   } {
@@ -330,8 +322,6 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT:     %I.type.loc20_33.1: type = facet_type <@I, @I(constants.%ptr)> [symbolic = %I.type.loc20_33.2 (constants.%I.type.0e2)]
 // CHECK:STDOUT:     %T.loc20_14.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc20_14.2 (constants.%T)]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %I.impl_witness_table.loc20 = impl_witness_table (), @impl.cd2fdc.2 [concrete]
-// CHECK:STDOUT:   %I.impl_witness.loc20: <witness> = impl_witness %I.impl_witness_table.loc20, @impl.cd2fdc.2(constants.%T) [symbolic = @impl.cd2fdc.2.%I.impl_witness (constants.%I.impl_witness.6ad3bf.2)]
 // CHECK:STDOUT:   impl_decl @impl.cd2fdc.3 [concrete] {
 // CHECK:STDOUT:     %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete]
 // CHECK:STDOUT:   } {
@@ -342,8 +332,6 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT:     %I.type.loc26_33.1: type = facet_type <@I, @I(constants.%ptr)> [symbolic = %I.type.loc26_33.2 (constants.%I.type.0e2)]
 // CHECK:STDOUT:     %T.loc26_14.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc26_14.2 (constants.%T)]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %I.impl_witness_table.loc26 = impl_witness_table (), @impl.cd2fdc.3 [concrete]
-// CHECK:STDOUT:   %I.impl_witness.loc26: <witness> = impl_witness %I.impl_witness_table.loc26, @impl.cd2fdc.3(constants.%T) [symbolic = @impl.cd2fdc.3.%I.impl_witness (constants.%I.impl_witness.6ad3bf.3)]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic interface @I(imports.%Main.import_ref.5ab3ec.1: type) [from "import_generic.carbon"] {
@@ -363,7 +351,7 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT: generic impl @impl.08450a.1(imports.%Main.import_ref.5ab3ec.2: type) [from "import_generic.carbon"] {
 // CHECK:STDOUT:   %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)]
 // CHECK:STDOUT:   %I.type: type = facet_type <@I, @I(%T)> [symbolic = %I.type (constants.%I.type.325)]
-// CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness imports.%I.impl_witness_table.028, @impl.08450a.1(%T) [symbolic = %I.impl_witness (constants.%I.impl_witness.1a9ed3.1)]
+// CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness imports.%I.impl_witness_table.028, @impl.08450a.1(%T) [symbolic = %I.impl_witness (constants.%I.impl_witness.1a9)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %I.type [symbolic = %require_complete (constants.%require_complete.cfe)]
@@ -379,7 +367,7 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT:   %ptr: type = ptr_type %T [symbolic = %ptr (constants.%ptr)]
 // CHECK:STDOUT:   %I.type: type = facet_type <@I, @I(%ptr)> [symbolic = %I.type (constants.%I.type.0e2)]
 // CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %I.type [symbolic = %require_complete (constants.%require_complete.0e6)]
-// CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness imports.%I.impl_witness_table.e14, @impl.cd2fdc.1(%T) [symbolic = %I.impl_witness (constants.%I.impl_witness.6ad3bf.1)]
+// CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness imports.%I.impl_witness_table.e14, @impl.cd2fdc.1(%T) [symbolic = %I.impl_witness (constants.%I.impl_witness.6ad)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
@@ -392,7 +380,6 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT: generic impl @impl.08450a.2(%T.loc8_14.1: type) {
 // CHECK:STDOUT:   %T.loc8_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc8_14.2 (constants.%T)]
 // CHECK:STDOUT:   %I.type.loc8_32.2: type = facet_type <@I, @I(%T.loc8_14.2)> [symbolic = %I.type.loc8_32.2 (constants.%I.type.325)]
-// CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness file.%I.impl_witness_table.loc8, @impl.08450a.2(%T.loc8_14.2) [symbolic = %I.impl_witness (constants.%I.impl_witness.1a9ed3.2)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   impl: %C.ref as %I.type.loc8_32.1;
 // CHECK:STDOUT: }
@@ -400,14 +387,12 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT: generic impl @impl.08450a.3(%T.loc14_14.1: type) {
 // CHECK:STDOUT:   %T.loc14_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc14_14.2 (constants.%T)]
 // CHECK:STDOUT:   %I.type.loc14_32.2: type = facet_type <@I, @I(%T.loc14_14.2)> [symbolic = %I.type.loc14_32.2 (constants.%I.type.325)]
-// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %I.type.loc14_32.2 [symbolic = %require_complete (constants.%require_complete.cfe)]
-// CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness file.%I.impl_witness_table.loc14, @impl.08450a.3(%T.loc14_14.2) [symbolic = %I.impl_witness (constants.%I.impl_witness.1a9ed3.3)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
 // CHECK:STDOUT:   impl: %C.ref as %I.type.loc14_32.1 {
 // CHECK:STDOUT:   !members:
-// CHECK:STDOUT:     witness = file.%I.impl_witness.loc14
+// CHECK:STDOUT:     witness = <error>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -415,7 +400,6 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT:   %T.loc20_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc20_14.2 (constants.%T)]
 // CHECK:STDOUT:   %ptr.loc20_32.2: type = ptr_type %T.loc20_14.2 [symbolic = %ptr.loc20_32.2 (constants.%ptr)]
 // CHECK:STDOUT:   %I.type.loc20_33.2: type = facet_type <@I, @I(%ptr.loc20_32.2)> [symbolic = %I.type.loc20_33.2 (constants.%I.type.0e2)]
-// CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness file.%I.impl_witness_table.loc20, @impl.cd2fdc.2(%T.loc20_14.2) [symbolic = %I.impl_witness (constants.%I.impl_witness.6ad3bf.2)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   impl: %C.ref as %I.type.loc20_33.1;
 // CHECK:STDOUT: }
@@ -424,14 +408,12 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT:   %T.loc26_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc26_14.2 (constants.%T)]
 // CHECK:STDOUT:   %ptr.loc26_32.2: type = ptr_type %T.loc26_14.2 [symbolic = %ptr.loc26_32.2 (constants.%ptr)]
 // CHECK:STDOUT:   %I.type.loc26_33.2: type = facet_type <@I, @I(%ptr.loc26_32.2)> [symbolic = %I.type.loc26_33.2 (constants.%I.type.0e2)]
-// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %I.type.loc26_33.2 [symbolic = %require_complete (constants.%require_complete.0e6)]
-// CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness file.%I.impl_witness_table.loc26, @impl.cd2fdc.3(%T.loc26_14.2) [symbolic = %I.impl_witness (constants.%I.impl_witness.6ad3bf.3)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
 // CHECK:STDOUT:   impl: %C.ref as %I.type.loc26_33.1 {
 // CHECK:STDOUT:   !members:
-// CHECK:STDOUT:     witness = file.%I.impl_witness.loc26
+// CHECK:STDOUT:     witness = <error>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -453,7 +435,7 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT: specific @impl.08450a.1(constants.%T) {
 // CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT:   %I.type => constants.%I.type.325
-// CHECK:STDOUT:   %I.impl_witness => constants.%I.impl_witness.1a9ed3.1
+// CHECK:STDOUT:   %I.impl_witness => constants.%I.impl_witness.1a9
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @I(constants.%ptr) {
@@ -469,35 +451,29 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT:   %ptr => constants.%ptr
 // CHECK:STDOUT:   %I.type => constants.%I.type.0e2
 // CHECK:STDOUT:   %require_complete => constants.%require_complete.0e6
-// CHECK:STDOUT:   %I.impl_witness => constants.%I.impl_witness.6ad3bf.1
+// CHECK:STDOUT:   %I.impl_witness => constants.%I.impl_witness.6ad
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl.08450a.2(constants.%T) {
 // CHECK:STDOUT:   %T.loc8_14.2 => constants.%T
 // CHECK:STDOUT:   %I.type.loc8_32.2 => constants.%I.type.325
-// CHECK:STDOUT:   %I.impl_witness => constants.%I.impl_witness.1a9ed3.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl.08450a.3(constants.%T) {
 // CHECK:STDOUT:   %T.loc14_14.2 => constants.%T
 // CHECK:STDOUT:   %I.type.loc14_32.2 => constants.%I.type.325
-// CHECK:STDOUT:   %require_complete => constants.%require_complete.cfe
-// CHECK:STDOUT:   %I.impl_witness => constants.%I.impl_witness.1a9ed3.3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl.cd2fdc.2(constants.%T) {
 // CHECK:STDOUT:   %T.loc20_14.2 => constants.%T
 // CHECK:STDOUT:   %ptr.loc20_32.2 => constants.%ptr
 // CHECK:STDOUT:   %I.type.loc20_33.2 => constants.%I.type.0e2
-// CHECK:STDOUT:   %I.impl_witness => constants.%I.impl_witness.6ad3bf.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl.cd2fdc.3(constants.%T) {
 // CHECK:STDOUT:   %T.loc26_14.2 => constants.%T
 // CHECK:STDOUT:   %ptr.loc26_32.2 => constants.%ptr
 // CHECK:STDOUT:   %I.type.loc26_33.2 => constants.%I.type.0e2
-// CHECK:STDOUT:   %require_complete => constants.%require_complete.0e6
-// CHECK:STDOUT:   %I.impl_witness => constants.%I.impl_witness.6ad3bf.3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_import_generic_decl.carbon
@@ -624,22 +600,15 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT:   %J.type.2b8: type = generic_interface_type @J [concrete]
 // CHECK:STDOUT:   %J.generic: %J.type.2b8 = struct_value () [concrete]
 // CHECK:STDOUT:   %J.type.b72: type = facet_type <@J, @J(%T)> [symbolic]
-// CHECK:STDOUT:   %Self.252: %J.type.b72 = bind_symbolic_name Self, 1 [symbolic]
+// CHECK:STDOUT:   %Self: %J.type.b72 = bind_symbolic_name Self, 1 [symbolic]
 // CHECK:STDOUT:   %pattern_type: type = pattern_type type [concrete]
 // CHECK:STDOUT:   %D: type = class_type @D [concrete]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
-// CHECK:STDOUT:   %J.impl_witness.80964e.1: <witness> = impl_witness imports.%J.impl_witness_table.891, @impl.199bba.1(%T) [symbolic]
+// CHECK:STDOUT:   %J.impl_witness.809: <witness> = impl_witness imports.%J.impl_witness_table.891, @impl.199bba.1(%T) [symbolic]
 // CHECK:STDOUT:   %ptr: type = ptr_type %T [symbolic]
 // CHECK:STDOUT:   %J.type.628: type = facet_type <@J, @J(%ptr)> [symbolic]
-// CHECK:STDOUT:   %J.impl_witness.5a859e.1: <witness> = impl_witness imports.%J.impl_witness_table.487, @impl.dfd2f7.1(%T) [symbolic]
-// CHECK:STDOUT:   %J.impl_witness.80964e.2: <witness> = impl_witness file.%J.impl_witness_table.loc8, @impl.199bba.2(%T) [symbolic]
-// CHECK:STDOUT:   %require_complete.287: <witness> = require_complete_type %J.type.b72 [symbolic]
-// CHECK:STDOUT:   %J.impl_witness.80964e.3: <witness> = impl_witness file.%J.impl_witness_table.loc14, @impl.199bba.3(%T) [symbolic]
-// CHECK:STDOUT:   %J.impl_witness.5a859e.2: <witness> = impl_witness file.%J.impl_witness_table.loc20, @impl.dfd2f7.2(%T) [symbolic]
-// CHECK:STDOUT:   %Self.fbe: %J.type.628 = bind_symbolic_name Self, 1 [symbolic]
-// CHECK:STDOUT:   %require_complete.c60: <witness> = require_complete_type %J.type.628 [symbolic]
-// CHECK:STDOUT:   %J.impl_witness.5a859e.3: <witness> = impl_witness file.%J.impl_witness_table.loc26, @impl.dfd2f7.3(%T) [symbolic]
+// CHECK:STDOUT:   %J.impl_witness.5a8: <witness> = impl_witness imports.%J.impl_witness_table.487, @impl.dfd2f7.1(%T) [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -675,8 +644,6 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT:     %J.type.loc8_32.1: type = facet_type <@J, @J(constants.%T)> [symbolic = %J.type.loc8_32.2 (constants.%J.type.b72)]
 // CHECK:STDOUT:     %T.loc8_14.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc8_14.2 (constants.%T)]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %J.impl_witness_table.loc8 = impl_witness_table (), @impl.199bba.2 [concrete]
-// CHECK:STDOUT:   %J.impl_witness.loc8: <witness> = impl_witness %J.impl_witness_table.loc8, @impl.199bba.2(constants.%T) [symbolic = @impl.199bba.2.%J.impl_witness (constants.%J.impl_witness.80964e.2)]
 // CHECK:STDOUT:   impl_decl @impl.199bba.3 [concrete] {
 // CHECK:STDOUT:     %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete]
 // CHECK:STDOUT:   } {
@@ -686,8 +653,6 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT:     %J.type.loc14_32.1: type = facet_type <@J, @J(constants.%T)> [symbolic = %J.type.loc14_32.2 (constants.%J.type.b72)]
 // CHECK:STDOUT:     %T.loc14_14.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc14_14.2 (constants.%T)]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %J.impl_witness_table.loc14 = impl_witness_table (), @impl.199bba.3 [concrete]
-// CHECK:STDOUT:   %J.impl_witness.loc14: <witness> = impl_witness %J.impl_witness_table.loc14, @impl.199bba.3(constants.%T) [symbolic = @impl.199bba.3.%J.impl_witness (constants.%J.impl_witness.80964e.3)]
 // CHECK:STDOUT:   impl_decl @impl.dfd2f7.2 [concrete] {
 // CHECK:STDOUT:     %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete]
 // CHECK:STDOUT:   } {
@@ -698,8 +663,6 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT:     %J.type.loc20_33.1: type = facet_type <@J, @J(constants.%ptr)> [symbolic = %J.type.loc20_33.2 (constants.%J.type.628)]
 // CHECK:STDOUT:     %T.loc20_14.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc20_14.2 (constants.%T)]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %J.impl_witness_table.loc20 = impl_witness_table (), @impl.dfd2f7.2 [concrete]
-// CHECK:STDOUT:   %J.impl_witness.loc20: <witness> = impl_witness %J.impl_witness_table.loc20, @impl.dfd2f7.2(constants.%T) [symbolic = @impl.dfd2f7.2.%J.impl_witness (constants.%J.impl_witness.5a859e.2)]
 // CHECK:STDOUT:   impl_decl @impl.dfd2f7.3 [concrete] {
 // CHECK:STDOUT:     %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete]
 // CHECK:STDOUT:   } {
@@ -710,8 +673,6 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT:     %J.type.loc26_33.1: type = facet_type <@J, @J(constants.%ptr)> [symbolic = %J.type.loc26_33.2 (constants.%J.type.628)]
 // CHECK:STDOUT:     %T.loc26_14.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc26_14.2 (constants.%T)]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %J.impl_witness_table.loc26 = impl_witness_table (), @impl.dfd2f7.3 [concrete]
-// CHECK:STDOUT:   %J.impl_witness.loc26: <witness> = impl_witness %J.impl_witness_table.loc26, @impl.dfd2f7.3(constants.%T) [symbolic = @impl.dfd2f7.3.%J.impl_witness (constants.%J.impl_witness.5a859e.3)]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: generic interface @J(imports.%Main.import_ref.5ab3ec.1: type) [from "fail_import_generic_decl.carbon"] {
@@ -719,7 +680,7 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %J.type: type = facet_type <@J, @J(%T)> [symbolic = %J.type (constants.%J.type.b72)]
-// CHECK:STDOUT:   %Self: @J.%J.type (%J.type.b72) = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self.252)]
+// CHECK:STDOUT:   %Self: @J.%J.type (%J.type.b72) = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   interface {
 // CHECK:STDOUT:   !members:
@@ -731,7 +692,7 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT: generic impl @impl.199bba.1(imports.%Main.import_ref.5ab3ec.2: type) [from "fail_import_generic_decl.carbon"] {
 // CHECK:STDOUT:   %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)]
 // CHECK:STDOUT:   %J.type: type = facet_type <@J, @J(%T)> [symbolic = %J.type (constants.%J.type.b72)]
-// CHECK:STDOUT:   %J.impl_witness: <witness> = impl_witness imports.%J.impl_witness_table.891, @impl.199bba.1(%T) [symbolic = %J.impl_witness (constants.%J.impl_witness.80964e.1)]
+// CHECK:STDOUT:   %J.impl_witness: <witness> = impl_witness imports.%J.impl_witness_table.891, @impl.199bba.1(%T) [symbolic = %J.impl_witness (constants.%J.impl_witness.809)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   impl: imports.%Main.import_ref.aa9f8a.1 as imports.%Main.import_ref.ded;
 // CHECK:STDOUT: }
@@ -740,7 +701,7 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT:   %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)]
 // CHECK:STDOUT:   %ptr: type = ptr_type %T [symbolic = %ptr (constants.%ptr)]
 // CHECK:STDOUT:   %J.type: type = facet_type <@J, @J(%ptr)> [symbolic = %J.type (constants.%J.type.628)]
-// CHECK:STDOUT:   %J.impl_witness: <witness> = impl_witness imports.%J.impl_witness_table.487, @impl.dfd2f7.1(%T) [symbolic = %J.impl_witness (constants.%J.impl_witness.5a859e.1)]
+// CHECK:STDOUT:   %J.impl_witness: <witness> = impl_witness imports.%J.impl_witness_table.487, @impl.dfd2f7.1(%T) [symbolic = %J.impl_witness (constants.%J.impl_witness.5a8)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   impl: imports.%Main.import_ref.aa9f8a.2 as imports.%Main.import_ref.0d3;
 // CHECK:STDOUT: }
@@ -748,7 +709,6 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT: generic impl @impl.199bba.2(%T.loc8_14.1: type) {
 // CHECK:STDOUT:   %T.loc8_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc8_14.2 (constants.%T)]
 // CHECK:STDOUT:   %J.type.loc8_32.2: type = facet_type <@J, @J(%T.loc8_14.2)> [symbolic = %J.type.loc8_32.2 (constants.%J.type.b72)]
-// CHECK:STDOUT:   %J.impl_witness: <witness> = impl_witness file.%J.impl_witness_table.loc8, @impl.199bba.2(%T.loc8_14.2) [symbolic = %J.impl_witness (constants.%J.impl_witness.80964e.2)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   impl: %D.ref as %J.type.loc8_32.1;
 // CHECK:STDOUT: }
@@ -756,14 +716,12 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT: generic impl @impl.199bba.3(%T.loc14_14.1: type) {
 // CHECK:STDOUT:   %T.loc14_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc14_14.2 (constants.%T)]
 // CHECK:STDOUT:   %J.type.loc14_32.2: type = facet_type <@J, @J(%T.loc14_14.2)> [symbolic = %J.type.loc14_32.2 (constants.%J.type.b72)]
-// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %J.type.loc14_32.2 [symbolic = %require_complete (constants.%require_complete.287)]
-// CHECK:STDOUT:   %J.impl_witness: <witness> = impl_witness file.%J.impl_witness_table.loc14, @impl.199bba.3(%T.loc14_14.2) [symbolic = %J.impl_witness (constants.%J.impl_witness.80964e.3)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
 // CHECK:STDOUT:   impl: %D.ref as %J.type.loc14_32.1 {
 // CHECK:STDOUT:   !members:
-// CHECK:STDOUT:     witness = file.%J.impl_witness.loc14
+// CHECK:STDOUT:     witness = <error>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -771,7 +729,6 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT:   %T.loc20_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc20_14.2 (constants.%T)]
 // CHECK:STDOUT:   %ptr.loc20_32.2: type = ptr_type %T.loc20_14.2 [symbolic = %ptr.loc20_32.2 (constants.%ptr)]
 // CHECK:STDOUT:   %J.type.loc20_33.2: type = facet_type <@J, @J(%ptr.loc20_32.2)> [symbolic = %J.type.loc20_33.2 (constants.%J.type.628)]
-// CHECK:STDOUT:   %J.impl_witness: <witness> = impl_witness file.%J.impl_witness_table.loc20, @impl.dfd2f7.2(%T.loc20_14.2) [symbolic = %J.impl_witness (constants.%J.impl_witness.5a859e.2)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   impl: %D.ref as %J.type.loc20_33.1;
 // CHECK:STDOUT: }
@@ -780,14 +737,12 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT:   %T.loc26_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc26_14.2 (constants.%T)]
 // CHECK:STDOUT:   %ptr.loc26_32.2: type = ptr_type %T.loc26_14.2 [symbolic = %ptr.loc26_32.2 (constants.%ptr)]
 // CHECK:STDOUT:   %J.type.loc26_33.2: type = facet_type <@J, @J(%ptr.loc26_32.2)> [symbolic = %J.type.loc26_33.2 (constants.%J.type.628)]
-// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %J.type.loc26_33.2 [symbolic = %require_complete (constants.%require_complete.c60)]
-// CHECK:STDOUT:   %J.impl_witness: <witness> = impl_witness file.%J.impl_witness_table.loc26, @impl.dfd2f7.3(%T.loc26_14.2) [symbolic = %J.impl_witness (constants.%J.impl_witness.5a859e.3)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
 // CHECK:STDOUT:   impl: %D.ref as %J.type.loc26_33.1 {
 // CHECK:STDOUT:   !members:
-// CHECK:STDOUT:     witness = file.%J.impl_witness.loc26
+// CHECK:STDOUT:     witness = <error>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -800,58 +755,44 @@ impl forall [T:! type] D as J(T*) {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @J(constants.%T) {
 // CHECK:STDOUT:   %T => constants.%T
-// CHECK:STDOUT:
-// CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %J.type => constants.%J.type.b72
-// CHECK:STDOUT:   %Self => constants.%Self.252
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl.199bba.1(constants.%T) {
 // CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT:   %J.type => constants.%J.type.b72
-// CHECK:STDOUT:   %J.impl_witness => constants.%J.impl_witness.80964e.1
+// CHECK:STDOUT:   %J.impl_witness => constants.%J.impl_witness.809
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @J(constants.%ptr) {
 // CHECK:STDOUT:   %T => constants.%ptr
-// CHECK:STDOUT:
-// CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %J.type => constants.%J.type.628
-// CHECK:STDOUT:   %Self => constants.%Self.fbe
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl.dfd2f7.1(constants.%T) {
 // CHECK:STDOUT:   %T => constants.%T
 // CHECK:STDOUT:   %ptr => constants.%ptr
 // CHECK:STDOUT:   %J.type => constants.%J.type.628
-// CHECK:STDOUT:   %J.impl_witness => constants.%J.impl_witness.5a859e.1
+// CHECK:STDOUT:   %J.impl_witness => constants.%J.impl_witness.5a8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl.199bba.2(constants.%T) {
 // CHECK:STDOUT:   %T.loc8_14.2 => constants.%T
 // CHECK:STDOUT:   %J.type.loc8_32.2 => constants.%J.type.b72
-// CHECK:STDOUT:   %J.impl_witness => constants.%J.impl_witness.80964e.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl.199bba.3(constants.%T) {
 // CHECK:STDOUT:   %T.loc14_14.2 => constants.%T
 // CHECK:STDOUT:   %J.type.loc14_32.2 => constants.%J.type.b72
-// CHECK:STDOUT:   %require_complete => constants.%require_complete.287
-// CHECK:STDOUT:   %J.impl_witness => constants.%J.impl_witness.80964e.3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl.dfd2f7.2(constants.%T) {
 // CHECK:STDOUT:   %T.loc20_14.2 => constants.%T
 // CHECK:STDOUT:   %ptr.loc20_32.2 => constants.%ptr
 // CHECK:STDOUT:   %J.type.loc20_33.2 => constants.%J.type.628
-// CHECK:STDOUT:   %J.impl_witness => constants.%J.impl_witness.5a859e.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl.dfd2f7.3(constants.%T) {
 // CHECK:STDOUT:   %T.loc26_14.2 => constants.%T
 // CHECK:STDOUT:   %ptr.loc26_32.2 => constants.%ptr
 // CHECK:STDOUT:   %J.type.loc26_33.2 => constants.%J.type.628
-// CHECK:STDOUT:   %require_complete => constants.%require_complete.c60
-// CHECK:STDOUT:   %J.impl_witness => constants.%J.impl_witness.5a859e.3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 10
toolchain/check/testdata/impl/no_prelude/no_definition_in_impl_file.carbon

@@ -138,8 +138,6 @@ impl () as D;
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %A.type: type = facet_type <@A> [concrete]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
-// CHECK:STDOUT:   %A.impl_witness.b6792d.1: <witness> = impl_witness file.%A.impl_witness_table.loc8 [concrete]
-// CHECK:STDOUT:   %A.impl_witness.b6792d.2: <witness> = impl_witness file.%A.impl_witness_table.loc14 [concrete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -160,15 +158,11 @@ impl () as D;
 // CHECK:STDOUT:     %.loc8_7.2: type = converted %.loc8_7.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
 // CHECK:STDOUT:     %A.ref: type = name_ref A, imports.%Main.A [concrete = constants.%A.type]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %A.impl_witness_table.loc8 = impl_witness_table (), @impl.064930.2 [concrete]
-// CHECK:STDOUT:   %A.impl_witness.loc8: <witness> = impl_witness %A.impl_witness_table.loc8 [concrete = constants.%A.impl_witness.b6792d.1]
 // CHECK:STDOUT:   impl_decl @impl.064930.3 [concrete] {} {
 // CHECK:STDOUT:     %.loc14_7.1: %empty_tuple.type = tuple_literal ()
 // CHECK:STDOUT:     %.loc14_7.2: type = converted %.loc14_7.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
 // CHECK:STDOUT:     %A.ref: type = name_ref A, imports.%Main.A [concrete = constants.%A.type]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %A.impl_witness_table.loc14 = impl_witness_table (), @impl.064930.3 [concrete]
-// CHECK:STDOUT:   %A.impl_witness.loc14: <witness> = impl_witness %A.impl_witness_table.loc14 [concrete = constants.%A.impl_witness.b6792d.2]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @A [from "fail_decl_in_api_definition_in_impl.carbon"] {
@@ -183,7 +177,7 @@ impl () as D;
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl.064930.3: %.loc14_7.2 as %A.ref {
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   witness = file.%A.impl_witness.loc14
+// CHECK:STDOUT:   witness = <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- use_decl_in_api.carbon
@@ -307,7 +301,6 @@ impl () as D;
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %C.type: type = facet_type <@C> [concrete]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
-// CHECK:STDOUT:   %C.impl_witness: <witness> = impl_witness file.%C.impl_witness_table [concrete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
@@ -328,8 +321,6 @@ impl () as D;
 // CHECK:STDOUT:     %.loc8_7.2: type = converted %.loc8_7.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
 // CHECK:STDOUT:     %C.ref: type = name_ref C, imports.%Main.C [concrete = constants.%C.type]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %C.impl_witness_table = impl_witness_table (), @impl.590fe9.2 [concrete]
-// CHECK:STDOUT:   %C.impl_witness: <witness> = impl_witness %C.impl_witness_table [concrete = constants.%C.impl_witness]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @C [from "fail_decl_in_api_decl_in_impl.carbon"] {