From d3df61e354ba0a8c6a4a0a528ab0753ac68db9fb Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Thu, 19 Sep 2024 09:43:01 -0700
Subject: [PATCH 1/8] Bump google-protobuf from 4.27.3 to 4.27.5 in /website in
the bundler group across 1 directory (#4325)
Bumps the bundler group with 1 update in the /website directory:
[google-protobuf](https://github.com/protocolbuffers/protobuf).
Updates `google-protobuf` from 4.27.3 to 4.27.5
Commits
[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=google-protobuf&package-manager=bundler&previous-version=4.27.3&new-version=4.27.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore ` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore ` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore ` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/carbon-language/carbon-lang/network/alerts).
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
website/Gemfile.lock | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/website/Gemfile.lock b/website/Gemfile.lock
index 0fdac16ce9da3..725a6529b381d 100644
--- a/website/Gemfile.lock
+++ b/website/Gemfile.lock
@@ -12,10 +12,10 @@ GEM
eventmachine (1.2.7)
ffi (1.17.0)
forwardable-extended (2.6.0)
- google-protobuf (4.27.3-arm64-darwin)
+ google-protobuf (4.27.5-arm64-darwin)
bigdecimal
rake (>= 13)
- google-protobuf (4.27.3-x86_64-linux)
+ google-protobuf (4.27.5-x86_64-linux)
bigdecimal
rake (>= 13)
http_parser.rb (0.8.0)
From 20443666525942717a99a09c07188825ef56d186 Mon Sep 17 00:00:00 2001
From: Richard Smith
Date: Thu, 19 Sep 2024 12:18:32 -0700
Subject: [PATCH 2/8] Support initialization of specific classes from struct
literals (#4320)
Add support for initializing types like `GenericClass(i32)` from a
struct literal. A new kind of instruction, `complete_type_witness`, is
added to the class definition to track the object representation type so
that it's visible to the generics machinery. Accesses to the object
representation of a class have all been updated to pass in the class's
`SpecificId` so that the types of the fields of the specific class are
used instead of the types of the fields of the generic class in places
that look at the object representation -- primarily class
initialization.
---
toolchain/check/context.cpp | 14 +-
toolchain/check/convert.cpp | 35 +-
toolchain/check/eval.cpp | 3 +
toolchain/check/handle_class.cpp | 120 ++++--
toolchain/check/import_ref.cpp | 34 +-
.../alias/no_prelude/alias_of_alias.carbon | 7 +-
.../alias/no_prelude/export_name.carbon | 41 +-
.../fail_aliased_name_in_diag.carbon | 9 +-
.../alias/no_prelude/fail_modifiers.carbon | 3 +
.../no_prelude/fail_name_conflict.carbon | 7 +-
.../testdata/alias/no_prelude/import.carbon | 39 +-
.../alias/no_prelude/import_access.carbon | 10 +-
.../alias/no_prelude/import_order.carbon | 23 +-
.../alias/no_prelude/in_namespace.carbon | 4 +-
.../testdata/as/adapter_conversion.carbon | 136 +++---
toolchain/check/testdata/as/identity.carbon | 25 +-
.../check/testdata/as/no_prelude/tuple.carbon | 49 +--
toolchain/check/testdata/as/overloaded.carbon | 98 ++---
.../check/testdata/builtins/float/eq.carbon | 35 +-
.../testdata/builtins/float/greater.carbon | 81 ++--
.../testdata/builtins/float/greater_eq.carbon | 81 ++--
.../check/testdata/builtins/float/less.carbon | 81 ++--
.../testdata/builtins/float/less_eq.carbon | 81 ++--
.../check/testdata/builtins/float/neq.carbon | 35 +-
.../check/testdata/builtins/int/eq.carbon | 35 +-
.../testdata/builtins/int/greater.carbon | 81 ++--
.../testdata/builtins/int/greater_eq.carbon | 81 ++--
.../check/testdata/builtins/int/less.carbon | 81 ++--
.../testdata/builtins/int/less_eq.carbon | 81 ++--
.../check/testdata/builtins/int/neq.carbon | 35 +-
.../testdata/class/access_modifers.carbon | 32 +-
toolchain/check/testdata/class/adapt.carbon | 13 +-
toolchain/check/testdata/class/base.carbon | 66 +--
.../check/testdata/class/base_field.carbon | 44 +-
.../class/base_function_unqualified.carbon | 12 +-
.../check/testdata/class/base_method.carbon | 34 +-
.../class/base_method_qualified.carbon | 38 +-
.../testdata/class/base_method_shadow.carbon | 95 +++--
toolchain/check/testdata/class/basic.carbon | 8 +-
.../class/complete_in_member_fn.carbon | 4 +-
.../testdata/class/compound_field.carbon | 64 +--
.../class/cross_package_import.carbon | 18 +-
.../testdata/class/derived_to_base.carbon | 148 +++----
.../check/testdata/class/extend_adapt.carbon | 116 +++---
.../check/testdata/class/fail_abstract.carbon | 58 +--
.../testdata/class/fail_adapt_bad_decl.carbon | 7 +
.../testdata/class/fail_adapt_bad_type.carbon | 1 +
.../class/fail_adapt_modifiers.carbon | 13 +-
.../class/fail_adapt_with_subobjects.carbon | 26 +-
.../testdata/class/fail_addr_not_self.carbon | 2 +
.../testdata/class/fail_addr_self.carbon | 52 +--
.../testdata/class/fail_base_bad_type.carbon | 391 +++++++++---------
.../class/fail_base_method_define.carbon | 17 +-
.../testdata/class/fail_base_misplaced.carbon | 5 +-
.../testdata/class/fail_base_modifiers.carbon | 30 +-
.../testdata/class/fail_base_no_extend.carbon | 15 +-
.../testdata/class/fail_base_repeated.carbon | 22 +-
.../testdata/class/fail_base_unbound.carbon | 21 +-
.../class/fail_compound_type_mismatch.carbon | 64 +--
.../class/fail_convert_to_invalid.carbon | 1 +
.../class/fail_derived_to_base.carbon | 145 +++----
.../testdata/class/fail_extend_cycle.carbon | 26 +-
.../class/fail_field_modifiers.carbon | 2 +
.../testdata/class/fail_generic_method.carbon | 8 +-
.../testdata/class/fail_import_misuses.carbon | 14 +-
.../check/testdata/class/fail_init.carbon | 36 +-
.../class/fail_init_as_inplace.carbon | 30 +-
.../class/fail_memaccess_category.carbon | 28 +-
.../testdata/class/fail_member_of_let.carbon | 6 +-
.../check/testdata/class/fail_method.carbon | 4 +-
.../class/fail_method_modifiers.carbon | 4 +
.../class/fail_method_redefinition.carbon | 2 +
.../testdata/class/fail_modifiers.carbon | 7 +
.../class/fail_out_of_line_decl.carbon | 5 +-
.../fail_redeclaration_introducer.carbon | 18 +
.../class/fail_redeclaration_scope.carbon | 15 +-
.../testdata/class/fail_redefinition.carbon | 9 +-
.../check/testdata/class/fail_scope.carbon | 6 +-
.../check/testdata/class/fail_self.carbon | 53 +--
.../class/fail_self_type_member.carbon | 8 +-
.../class/fail_todo_local_class.carbon | 2 +
.../testdata/class/fail_unbound_field.carbon | 4 +-
.../testdata/class/fail_unknown_member.carbon | 4 +-
.../check/testdata/class/field_access.carbon | 12 +-
.../class/field_access_in_value.carbon | 12 +-
.../check/testdata/class/generic/basic.carbon | 8 +-
.../check/testdata/class/generic/call.carbon | 121 +++---
.../check/testdata/class/generic/field.carbon | 32 +-
.../testdata/class/generic/import.carbon | 140 ++++---
.../check/testdata/class/generic/init.carbon | 367 ++++++++--------
.../class/generic/member_access.carbon | 103 +++--
.../class/generic/member_inline.carbon | 10 +-
.../class/generic/member_out_of_line.carbon | 37 +-
.../class/generic/method_deduce.carbon | 72 ++--
.../testdata/class/generic/redeclare.carbon | 18 +
.../check/testdata/class/generic/self.carbon | 4 +-
.../testdata/class/generic_method.carbon | 8 +-
toolchain/check/testdata/class/import.carbon | 96 +++--
.../check/testdata/class/import_base.carbon | 58 +--
.../testdata/class/import_forward_decl.carbon | 3 +
.../testdata/class/import_indirect.carbon | 133 +++---
.../testdata/class/import_member_cycle.carbon | 3 +
.../testdata/class/import_struct_cyle.carbon | 11 +-
.../testdata/class/inheritance_access.carbon | 181 ++++----
toolchain/check/testdata/class/init.carbon | 8 +-
.../check/testdata/class/init_adapt.carbon | 118 +++---
toolchain/check/testdata/class/init_as.carbon | 18 +-
.../check/testdata/class/init_nested.carbon | 22 +-
toolchain/check/testdata/class/method.carbon | 12 +-
toolchain/check/testdata/class/nested.carbon | 34 +-
.../check/testdata/class/nested_name.carbon | 10 +-
.../class/no_prelude/export_name.carbon | 13 +-
.../testdata/class/no_prelude/extern.carbon | 13 +
.../class/no_prelude/generic_vs_params.carbon | 24 +-
.../class/no_prelude/implicit_import.carbon | 22 +-
.../class/no_prelude/import_access.carbon | 22 +-
.../no_prelude/indirect_import_member.carbon | 52 ++-
.../no_definition_in_impl_file.carbon | 3 +
.../class/no_prelude/syntactic_merge.carbon | 162 +++++---
.../check/testdata/class/raw_self.carbon | 6 +-
.../check/testdata/class/raw_self_type.carbon | 25 +-
.../check/testdata/class/redeclaration.carbon | 4 +-
.../class/redeclaration_introducer.carbon | 7 +
.../check/testdata/class/reenter_scope.carbon | 4 +-
toolchain/check/testdata/class/reorder.carbon | 8 +-
.../testdata/class/reorder_qualified.carbon | 72 ++--
toolchain/check/testdata/class/scope.carbon | 12 +-
toolchain/check/testdata/class/self.carbon | 4 +-
.../testdata/class/self_conversion.carbon | 62 +--
.../check/testdata/class/self_type.carbon | 4 +-
.../check/testdata/class/static_method.carbon | 4 +-
.../class/syntactic_merge_literal.carbon | 50 ++-
.../class/todo_access_modifiers.carbon | 2 +
.../testdata/class/virtual_modifiers.carbon | 3 +
.../declaration/no_prelude/extern.carbon | 2 +
.../fail_import_incomplete_return.carbon | 6 +-
.../no_prelude/syntactic_merge.carbon | 131 +++---
.../testdata/function/generic/deduce.carbon | 25 +-
.../function/generic/no_prelude/call.carbon | 10 +-
.../function/generic/return_slot.carbon | 26 +-
.../check/testdata/global/class_obj.carbon | 7 +-
.../testdata/global/class_with_fun.carbon | 7 +-
.../if_expr/fail_not_in_function.carbon | 1 +
.../check/testdata/impl/extend_impl.carbon | 4 +-
.../impl/fail_extend_impl_forall.carbon | 2 +
.../impl/fail_extend_impl_type_as.carbon | 4 +
.../impl/fail_extend_non_interface.carbon | 2 +
..._extend_partially_defined_interface.carbon | 2 +
.../fail_extend_undefined_interface.carbon | 2 +
.../impl/fail_impl_bad_assoc_fn.carbon | 216 +++++-----
toolchain/check/testdata/impl/impl_as.carbon | 4 +-
.../check/testdata/impl/lookup/alias.carbon | 8 +-
.../lookup/fail_alias_impl_not_found.carbon | 4 +-
.../lookup/fail_todo_undefined_impl.carbon | 8 +-
.../check/testdata/impl/lookup/import.carbon | 38 +-
.../impl/lookup/instance_method.carbon | 4 +-
.../impl/lookup/no_prelude/import.carbon | 38 +-
.../testdata/impl/no_prelude/basic.carbon | 7 +-
.../impl/no_prelude/interface_args.carbon | 322 ++++++++-------
.../impl/no_prelude/self_in_class.carbon | 10 +-
.../impl/no_prelude/self_in_signature.carbon | 139 ++++---
.../check/testdata/impl/redeclaration.carbon | 6 +-
..._todo_define_default_fn_out_of_line.carbon | 4 +-
.../interface/no_prelude/default_fn.carbon | 4 +-
.../interface/no_prelude/generic.carbon | 129 +++---
.../no_prelude/generic_import.carbon | 45 +-
.../no_prelude/generic_vs_params.carbon | 34 +-
.../no_prelude/syntactic_merge.carbon | 242 ++++++-----
.../merging_with_indirections.carbon | 17 +-
.../testdata/operators/overloaded/add.carbon | 95 ++---
.../operators/overloaded/bit_and.carbon | 95 ++---
.../overloaded/bit_complement.carbon | 33 +-
.../operators/overloaded/bit_or.carbon | 95 ++---
.../operators/overloaded/bit_xor.carbon | 95 ++---
.../testdata/operators/overloaded/dec.carbon | 59 +--
.../testdata/operators/overloaded/div.carbon | 95 ++---
.../testdata/operators/overloaded/eq.carbon | 177 ++++----
.../overloaded/fail_assign_non_ref.carbon | 105 ++---
.../operators/overloaded/fail_no_impl.carbon | 95 ++---
.../overloaded/fail_no_impl_for_arg.carbon | 141 ++++---
.../operators/overloaded/implicit_as.carbon | 90 ++--
.../testdata/operators/overloaded/inc.carbon | 59 +--
.../operators/overloaded/left_shift.carbon | 95 ++---
.../testdata/operators/overloaded/mod.carbon | 95 ++---
.../testdata/operators/overloaded/mul.carbon | 95 ++---
.../operators/overloaded/negate.carbon | 33 +-
.../operators/overloaded/ordered.carbon | 130 +++---
.../operators/overloaded/right_shift.carbon | 95 ++---
.../testdata/operators/overloaded/sub.carbon | 95 ++---
.../check/testdata/package_expr/syntax.carbon | 4 +-
.../no_prelude/cross_package_export.carbon | 63 +--
.../packages/no_prelude/export_import.carbon | 37 +-
.../packages/no_prelude/export_mixed.carbon | 80 ++--
.../packages/no_prelude/export_name.carbon | 179 ++++----
.../no_prelude/fail_export_name_member.carbon | 3 +
.../implicit_imports_entities.carbon | 43 +-
.../no_prelude/missing_prelude.carbon | 2 +
toolchain/check/testdata/pointer/arrow.carbon | 4 +-
.../fail_return_with_returned_var.carbon | 12 +-
.../check/testdata/return/returned_var.carbon | 22 +-
toolchain/check/testdata/struct/import.carbon | 160 +++----
toolchain/check/testdata/tuple/import.carbon | 136 +++---
.../testdata/var/fail_not_copyable.carbon | 13 +-
.../no_prelude/fail_designator.carbon | 4 +-
toolchain/lower/constant.cpp | 6 +
toolchain/lower/file_context.cpp | 6 +-
toolchain/lower/handle_aggregates.cpp | 15 +-
toolchain/sem_ir/BUILD | 1 +
toolchain/sem_ir/class.cpp | 28 ++
toolchain/sem_ir/class.h | 17 +-
toolchain/sem_ir/file.cpp | 2 +
toolchain/sem_ir/generic.cpp | 13 +-
toolchain/sem_ir/inst_kind.def | 1 +
toolchain/sem_ir/typed_insts.h | 20 +
214 files changed, 5557 insertions(+), 4223 deletions(-)
create mode 100644 toolchain/sem_ir/class.cpp
diff --git a/toolchain/check/context.cpp b/toolchain/check/context.cpp
index bba09498eb57c..fc77e2c582cc0 100644
--- a/toolchain/check/context.cpp
+++ b/toolchain/check/context.cpp
@@ -27,6 +27,7 @@
#include "toolchain/sem_ir/builtin_inst_kind.h"
#include "toolchain/sem_ir/file.h"
#include "toolchain/sem_ir/formatter.h"
+#include "toolchain/sem_ir/generic.h"
#include "toolchain/sem_ir/ids.h"
#include "toolchain/sem_ir/import_ir.h"
#include "toolchain/sem_ir/inst.h"
@@ -873,7 +874,7 @@ class TypeCompleter {
if (inst.specific_id.is_valid()) {
ResolveSpecificDefinition(context_, inst.specific_id);
}
- Push(class_info.object_repr_id);
+ Push(class_info.GetObjectRepr(context_.sem_ir(), inst.specific_id));
break;
}
case CARBON_KIND(SemIR::ConstType inst): {
@@ -1051,14 +1052,19 @@ class TypeCompleter {
// The value representation of an adapter is the value representation of
// its adapted type.
if (class_info.adapt_id.is_valid()) {
- return GetNestedValueRepr(class_info.object_repr_id);
+ return GetNestedValueRepr(SemIR::GetTypeInSpecific(
+ context_.sem_ir(), inst.specific_id,
+ context_.insts()
+ .GetAs(class_info.adapt_id)
+ .adapted_type_id));
}
// Otherwise, the value representation for a class is a pointer to the
// object representation.
// TODO: Support customized value representations for classes.
// TODO: Pick a better value representation when possible.
- return MakePointerValueRepr(class_info.object_repr_id,
- SemIR::ValueRepr::ObjectAggregate);
+ return MakePointerValueRepr(
+ class_info.GetObjectRepr(context_.sem_ir(), inst.specific_id),
+ SemIR::ValueRepr::ObjectAggregate);
}
template
diff --git a/toolchain/check/convert.cpp b/toolchain/check/convert.cpp
index d5908d273ca66..62da182ac013f 100644
--- a/toolchain/check/convert.cpp
+++ b/toolchain/check/convert.cpp
@@ -532,8 +532,8 @@ static auto ConvertStructToClass(Context& context, SemIR::StructType src_type,
SemIR::InstId value_id,
ConversionTarget target) -> SemIR::InstId {
PendingBlock target_block(context);
- auto& class_info = context.classes().Get(dest_type.class_id);
- if (class_info.inheritance_kind == SemIR::Class::Abstract) {
+ auto& dest_class_info = context.classes().Get(dest_type.class_id);
+ if (dest_class_info.inheritance_kind == SemIR::Class::Abstract) {
CARBON_DIAGNOSTIC(ConstructionOfAbstractClass, Error,
"Cannot construct instance of abstract class. "
"Consider using `partial {0}` instead.",
@@ -542,11 +542,13 @@ static auto ConvertStructToClass(Context& context, SemIR::StructType src_type,
target.type_id);
return SemIR::InstId::BuiltinError;
}
- if (class_info.object_repr_id == SemIR::TypeId::Error) {
+ auto object_repr_id =
+ dest_class_info.GetObjectRepr(context.sem_ir(), dest_type.specific_id);
+ if (object_repr_id == SemIR::TypeId::Error) {
return SemIR::InstId::BuiltinError;
}
auto dest_struct_type =
- context.types().GetAs(class_info.object_repr_id);
+ context.types().GetAs(object_repr_id);
// If we're trying to create a class value, form a temporary for the value to
// point to.
@@ -571,9 +573,10 @@ static auto ConvertStructToClass(Context& context, SemIR::StructType src_type,
return result_id;
}
-// An inheritance path is a sequence of `BaseDecl`s in order from derived to
-// base.
-using InheritancePath = llvm::SmallVector;
+// An inheritance path is a sequence of `BaseDecl`s and corresponding base types
+// in order from derived to base.
+using InheritancePath =
+ llvm::SmallVector>;
// Computes the inheritance path from class `derived_id` to class `base_id`.
// Returns nullopt if `derived_id` is not a class derived from `base_id`.
@@ -602,10 +605,13 @@ static auto ComputeInheritancePath(Context& context, SemIR::TypeId derived_id,
result = std::nullopt;
break;
}
- result->push_back(derived_class.base_id);
- derived_id = context.insts()
- .GetAs(derived_class.base_id)
- .base_type_id;
+ auto base_decl =
+ context.insts().GetAs(derived_class.base_id);
+ auto base_type_id = SemIR::GetTypeInSpecific(
+ context.sem_ir(), derived_class_type->specific_id,
+ base_decl.base_type_id);
+ result->push_back({derived_class.base_id, base_type_id});
+ derived_id = base_type_id;
}
return result;
}
@@ -619,10 +625,10 @@ static auto ConvertDerivedToBase(Context& context, SemIR::LocId loc_id,
value_id = ConvertToValueOrRefExpr(context, value_id);
// Add a series of `.base` accesses.
- for (auto base_id : path) {
+ for (auto [base_id, base_type_id] : path) {
auto base_decl = context.insts().GetAs(base_id);
value_id = context.AddInst(
- loc_id, {.type_id = base_decl.base_type_id,
+ loc_id, {.type_id = base_type_id,
.base_id = value_id,
.index = base_decl.index});
}
@@ -677,7 +683,8 @@ static auto GetCompatibleBaseType(Context& context, SemIR::TypeId type_id)
if (auto class_type = context.types().TryGetAs(type_id)) {
auto& class_info = context.classes().Get(class_type->class_id);
if (class_info.adapt_id.is_valid()) {
- return class_info.object_repr_id;
+ return class_info.GetObjectRepr(context.sem_ir(),
+ class_type->specific_id);
}
}
diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp
index 3fe78ad7ddfa4..c53d4afc33e58 100644
--- a/toolchain/check/eval.cpp
+++ b/toolchain/check/eval.cpp
@@ -1166,6 +1166,9 @@ auto TryEvalInstInContext(EvalContext& eval_context, SemIR::InstId inst_id,
case SemIR::ClassType::Kind:
return RebuildIfFieldsAreConstant(eval_context, inst,
&SemIR::ClassType::specific_id);
+ case SemIR::CompleteTypeWitness::Kind:
+ return RebuildIfFieldsAreConstant(
+ eval_context, inst, &SemIR::CompleteTypeWitness::object_repr_id);
case SemIR::FunctionType::Kind:
return RebuildIfFieldsAreConstant(eval_context, inst,
&SemIR::FunctionType::specific_id);
diff --git a/toolchain/check/handle_class.cpp b/toolchain/check/handle_class.cpp
index 32f4fbb4ac45a..ee0c6dbcb64bc 100644
--- a/toolchain/check/handle_class.cpp
+++ b/toolchain/check/handle_class.cpp
@@ -94,7 +94,7 @@ static auto MergeClassRedecl(Context& context, SemIRLoc new_loc,
prev_class.body_block_id = new_class.body_block_id;
prev_class.adapt_id = new_class.adapt_id;
prev_class.base_id = new_class.base_id;
- prev_class.object_repr_id = new_class.object_repr_id;
+ prev_class.complete_type_witness_id = new_class.complete_type_witness_id;
}
if ((prev_import_ir_id.is_valid() && !new_is_import) ||
@@ -561,55 +561,89 @@ auto HandleParseNode(Context& context, Parse::BaseDeclId node_id) -> bool {
return true;
}
-auto HandleParseNode(Context& context, Parse::ClassDefinitionId /*node_id*/)
+// Checks that the specified finished adapter definition is valid and builds and
+// returns a corresponding complete type witness instruction.
+static auto CheckCompleteAdapterClassType(Context& context,
+ Parse::NodeId node_id,
+ SemIR::ClassId class_id,
+ SemIR::InstBlockId fields_id)
+ -> SemIR::InstId {
+ const auto& class_info = context.classes().Get(class_id);
+ if (class_info.base_id.is_valid()) {
+ CARBON_DIAGNOSTIC(AdaptWithBase, Error,
+ "Adapter cannot have a base class.");
+ CARBON_DIAGNOSTIC(AdaptBaseHere, Note, "`base` declaration is here.");
+ context.emitter()
+ .Build(class_info.adapt_id, AdaptWithBase)
+ .Note(class_info.base_id, AdaptBaseHere)
+ .Emit();
+ return SemIR::InstId::BuiltinError;
+ }
+
+ if (!context.inst_blocks().Get(fields_id).empty()) {
+ auto first_field_id = context.inst_blocks().Get(fields_id).front();
+ CARBON_DIAGNOSTIC(AdaptWithFields, Error, "Adapter cannot have fields.");
+ CARBON_DIAGNOSTIC(AdaptFieldHere, Note, "First field declaration is here.");
+ context.emitter()
+ .Build(class_info.adapt_id, AdaptWithFields)
+ .Note(first_field_id, AdaptFieldHere)
+ .Emit();
+ return SemIR::InstId::BuiltinError;
+ }
+
+ // The object representation of the adapter is the object representation
+ // of the adapted type. This is the adapted type itself unless it's a class
+ // type.
+ //
+ // TODO: The object representation of `const T` should also be the object
+ // representation of `T`.
+ auto adapted_type_id = context.insts()
+ .GetAs(class_info.adapt_id)
+ .adapted_type_id;
+ if (auto adapted_class =
+ context.types().TryGetAs(adapted_type_id)) {
+ auto& adapted_class_info = context.classes().Get(adapted_class->class_id);
+ if (adapted_class_info.adapt_id.is_valid()) {
+ return adapted_class_info.complete_type_witness_id;
+ }
+ }
+
+ return context.AddInst(
+ node_id,
+ {.type_id = context.GetBuiltinType(SemIR::BuiltinInstKind::WitnessType),
+ .object_repr_id = adapted_type_id});
+}
+
+// Checks that the specified finished class definition is valid and builds and
+// returns a corresponding complete type witness instruction.
+static auto CheckCompleteClassType(Context& context, Parse::NodeId node_id,
+ SemIR::ClassId class_id,
+ SemIR::InstBlockId fields_id)
+ -> SemIR::InstId {
+ auto& class_info = context.classes().Get(class_id);
+ if (class_info.adapt_id.is_valid()) {
+ return CheckCompleteAdapterClassType(context, node_id, class_id, fields_id);
+ }
+
+ return context.AddInst(
+ node_id,
+ {.type_id = context.GetBuiltinType(SemIR::BuiltinInstKind::WitnessType),
+ .object_repr_id = context.GetStructType(fields_id)});
+}
+
+auto HandleParseNode(Context& context, Parse::ClassDefinitionId node_id)
-> bool {
auto fields_id = context.args_type_info_stack().Pop();
auto class_id =
context.node_stack().Pop();
- context.inst_block_stack().Pop();
// The class type is now fully defined. Compute its object representation.
+ auto complete_type_witness_id =
+ CheckCompleteClassType(context, node_id, class_id, fields_id);
auto& class_info = context.classes().Get(class_id);
- if (class_info.adapt_id.is_valid()) {
- class_info.object_repr_id = SemIR::TypeId::Error;
- if (class_info.base_id.is_valid()) {
- CARBON_DIAGNOSTIC(AdaptWithBase, Error,
- "Adapter cannot have a base class.");
- CARBON_DIAGNOSTIC(AdaptBaseHere, Note, "`base` declaration is here.");
- context.emitter()
- .Build(class_info.adapt_id, AdaptWithBase)
- .Note(class_info.base_id, AdaptBaseHere)
- .Emit();
- } else if (!context.inst_blocks().Get(fields_id).empty()) {
- auto first_field_id = context.inst_blocks().Get(fields_id).front();
- CARBON_DIAGNOSTIC(AdaptWithFields, Error, "Adapter cannot have fields.");
- CARBON_DIAGNOSTIC(AdaptFieldHere, Note,
- "First field declaration is here.");
- context.emitter()
- .Build(class_info.adapt_id, AdaptWithFields)
- .Note(first_field_id, AdaptFieldHere)
- .Emit();
- } else {
- // The object representation of the adapter is the object representation
- // of the adapted type.
- auto adapted_type_id = context.insts()
- .GetAs(class_info.adapt_id)
- .adapted_type_id;
- // If we adapt an adapter, directly track the non-adapter type we're
- // adapting so that we have constant-time access to it.
- if (auto adapted_class =
- context.types().TryGetAs(adapted_type_id)) {
- auto& adapted_class_info =
- context.classes().Get(adapted_class->class_id);
- if (adapted_class_info.adapt_id.is_valid()) {
- adapted_type_id = adapted_class_info.object_repr_id;
- }
- }
- class_info.object_repr_id = adapted_type_id;
- }
- } else {
- class_info.object_repr_id = context.GetStructType(fields_id);
- }
+ class_info.complete_type_witness_id = complete_type_witness_id;
+
+ context.inst_block_stack().Pop();
FinishGenericDefinition(context, class_info.generic_id);
diff --git a/toolchain/check/import_ref.cpp b/toolchain/check/import_ref.cpp
index aa0d334f58ade..952e75d1eab20 100644
--- a/toolchain/check/import_ref.cpp
+++ b/toolchain/check/import_ref.cpp
@@ -16,6 +16,7 @@
#include "toolchain/sem_ir/import_ir.h"
#include "toolchain/sem_ir/inst.h"
#include "toolchain/sem_ir/inst_kind.h"
+#include "toolchain/sem_ir/type_info.h"
#include "toolchain/sem_ir/typed_insts.h"
namespace Carbon::Check {
@@ -1011,6 +1012,9 @@ class ImportRefResolver {
case CARBON_KIND(SemIR::ClassType inst): {
return TryResolveTypedInst(inst);
}
+ case CARBON_KIND(SemIR::CompleteTypeWitness inst): {
+ return TryResolveTypedInst(inst);
+ }
case CARBON_KIND(SemIR::ConstType inst): {
return TryResolveTypedInst(inst);
}
@@ -1228,12 +1232,11 @@ class ImportRefResolver {
// Fills out the class definition for an incomplete class.
auto AddClassDefinition(const SemIR::Class& import_class,
SemIR::Class& new_class,
- SemIR::ConstantId object_repr_const_id,
+ SemIR::InstId complete_type_witness_id,
SemIR::InstId base_id) -> void {
new_class.definition_id = new_class.first_owning_decl_id;
- new_class.object_repr_id =
- context_.GetTypeIdForTypeConstant(object_repr_const_id);
+ new_class.complete_type_witness_id = complete_type_witness_id;
new_class.scope_id = context_.name_scopes().Add(
new_class.first_owning_decl_id, SemIR::NameId::Invalid,
@@ -1312,10 +1315,10 @@ class ImportRefResolver {
auto param_const_ids = GetLocalParamConstantIds(import_class.param_refs_id);
auto generic_data = GetLocalGenericData(import_class.generic_id);
auto self_const_id = GetLocalConstantId(import_class.self_type_id);
- auto object_repr_const_id =
- import_class.object_repr_id.is_valid()
- ? GetLocalConstantId(import_class.object_repr_id)
- : SemIR::ConstantId::Invalid;
+ auto complete_type_witness_id =
+ import_class.complete_type_witness_id.is_valid()
+ ? GetLocalConstantInstId(import_class.complete_type_witness_id)
+ : SemIR::InstId::Invalid;
auto base_id = import_class.base_id.is_valid()
? GetLocalConstantInstId(import_class.base_id)
: SemIR::InstId::Invalid;
@@ -1334,7 +1337,7 @@ class ImportRefResolver {
new_class.self_type_id = context_.GetTypeIdForTypeConstant(self_const_id);
if (import_class.is_defined()) {
- AddClassDefinition(import_class, new_class, object_repr_const_id,
+ AddClassDefinition(import_class, new_class, complete_type_witness_id,
base_id);
}
@@ -1368,6 +1371,21 @@ class ImportRefResolver {
}
}
+ auto TryResolveTypedInst(SemIR::CompleteTypeWitness inst) -> ResolveResult {
+ CARBON_CHECK(import_ir_.types().GetInstId(inst.type_id) ==
+ SemIR::InstId::BuiltinWitnessType);
+ auto object_repr_const_id = GetLocalConstantId(inst.object_repr_id);
+ if (HasNewWork()) {
+ return Retry();
+ }
+ auto object_repr_id =
+ context_.GetTypeIdForTypeConstant(object_repr_const_id);
+ return ResolveAs(
+ {.type_id =
+ context_.GetBuiltinType(SemIR::BuiltinInstKind::WitnessType),
+ .object_repr_id = object_repr_id});
+ }
+
auto TryResolveTypedInst(SemIR::ConstType inst) -> ResolveResult {
CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType);
auto inner_const_id = GetLocalConstantId(inst.inner_id);
diff --git a/toolchain/check/testdata/alias/no_prelude/alias_of_alias.carbon b/toolchain/check/testdata/alias/no_prelude/alias_of_alias.carbon
index 8b66f599344b6..695325091cab1 100644
--- a/toolchain/check/testdata/alias/no_prelude/alias_of_alias.carbon
+++ b/toolchain/check/testdata/alias/no_prelude/alias_of_alias.carbon
@@ -19,8 +19,9 @@ let d: c = {};
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %C: type = class_type @C [template]
// CHECK:STDOUT: %.1: type = struct_type {} [template]
-// CHECK:STDOUT: %.2: type = tuple_type () [template]
-// CHECK:STDOUT: %.3: type = ptr_type %.1 [template]
+// CHECK:STDOUT: %.2: = complete_type_witness %.1 [template]
+// CHECK:STDOUT: %.3: type = tuple_type () [template]
+// CHECK:STDOUT: %.4: type = ptr_type %.1 [template]
// CHECK:STDOUT: %struct: %C = struct_value () [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -43,6 +44,8 @@ let d: c = {};
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @C {
+// CHECK:STDOUT: %.loc11: = complete_type_witness %.1 [template = constants.%.2]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%C
// CHECK:STDOUT: }
diff --git a/toolchain/check/testdata/alias/no_prelude/export_name.carbon b/toolchain/check/testdata/alias/no_prelude/export_name.carbon
index 3826138bcaafc..fce46c348ae03 100644
--- a/toolchain/check/testdata/alias/no_prelude/export_name.carbon
+++ b/toolchain/check/testdata/alias/no_prelude/export_name.carbon
@@ -73,6 +73,7 @@ var d: D* = &c;
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %C: type = class_type @C [template]
// CHECK:STDOUT: %.1: type = struct_type {} [template]
+// CHECK:STDOUT: %.2: = complete_type_witness %.1 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
@@ -86,6 +87,8 @@ var d: D* = &c;
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @C {
+// CHECK:STDOUT: %.loc4: = complete_type_witness %.1 [template = constants.%.2]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%C
// CHECK:STDOUT: }
@@ -95,11 +98,12 @@ var d: D* = &c;
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %C: type = class_type @C [template]
// CHECK:STDOUT: %.1: type = struct_type {} [template]
+// CHECK:STDOUT: %.2: = complete_type_witness %.1 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %import_ref.1 = import_ref Main//base, inst+1, unloaded
-// CHECK:STDOUT: %import_ref.2: type = import_ref Main//base, inst+5, loaded [template = constants.%C]
+// CHECK:STDOUT: %import_ref.2: type = import_ref Main//base, inst+7, loaded [template = constants.%C]
// CHECK:STDOUT: %import_ref.3 = import_ref Main//base, inst+2, unloaded
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -122,11 +126,12 @@ var d: D* = &c;
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %C: type = class_type @C [template]
// CHECK:STDOUT: %.1: type = struct_type {} [template]
+// CHECK:STDOUT: %.2: = complete_type_witness %.1 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %import_ref.1: type = import_ref Main//base, inst+1, loaded [template = constants.%C]
-// CHECK:STDOUT: %import_ref.2 = import_ref Main//base, inst+5, unloaded
+// CHECK:STDOUT: %import_ref.2 = import_ref Main//base, inst+7, unloaded
// CHECK:STDOUT: %import_ref.3 = import_ref Main//base, inst+2, unloaded
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -149,14 +154,15 @@ var d: D* = &c;
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %C: type = class_type @C [template]
// CHECK:STDOUT: %.1: type = struct_type {} [template]
-// CHECK:STDOUT: %.2: type = tuple_type () [template]
-// CHECK:STDOUT: %.3: type = ptr_type %.1 [template]
+// CHECK:STDOUT: %.2: = complete_type_witness %.1 [template]
+// CHECK:STDOUT: %.3: type = tuple_type () [template]
+// CHECK:STDOUT: %.4: type = ptr_type %.1 [template]
// CHECK:STDOUT: %struct: %C = struct_value () [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
-// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export, inst+8, loaded [template = constants.%C]
-// CHECK:STDOUT: %import_ref.2 = import_ref Main//export, inst+7, unloaded
+// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export, inst+9, loaded [template = constants.%C]
+// CHECK:STDOUT: %import_ref.2 = import_ref Main//export, inst+8, unloaded
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
@@ -191,7 +197,7 @@ var d: D* = &c;
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
-// CHECK:STDOUT: %import_ref = import_ref Main//export, inst+8, unloaded
+// CHECK:STDOUT: %import_ref = import_ref Main//export, inst+9, unloaded
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
@@ -217,16 +223,17 @@ var d: D* = &c;
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %C: type = class_type @C [template]
// CHECK:STDOUT: %.1: type = struct_type {} [template]
-// CHECK:STDOUT: %.2: type = tuple_type () [template]
-// CHECK:STDOUT: %.3: type = ptr_type %.1 [template]
+// CHECK:STDOUT: %.2: = complete_type_witness %.1 [template]
+// CHECK:STDOUT: %.3: type = tuple_type () [template]
+// CHECK:STDOUT: %.4: type = ptr_type %.1 [template]
// CHECK:STDOUT: %struct: %C = struct_value () [template]
-// CHECK:STDOUT: %.4: type = ptr_type %C [template]
+// CHECK:STDOUT: %.5: type = ptr_type %C [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
-// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export, inst+8, loaded [template = constants.%C]
-// CHECK:STDOUT: %import_ref.2: type = import_ref Main//export_orig, inst+8, loaded [template = constants.%C]
-// CHECK:STDOUT: %import_ref.3 = import_ref Main//export_orig, inst+7, unloaded
+// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export, inst+9, loaded [template = constants.%C]
+// CHECK:STDOUT: %import_ref.2: type = import_ref Main//export_orig, inst+9, loaded [template = constants.%C]
+// CHECK:STDOUT: %import_ref.3 = import_ref Main//export_orig, inst+8, unloaded
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
@@ -241,9 +248,9 @@ var d: D* = &c;
// CHECK:STDOUT: %c.var: ref %C = var c
// CHECK:STDOUT: %c: ref %C = bind_name c, %c.var
// CHECK:STDOUT: %D.ref: type = name_ref D, imports.%import_ref.1 [template = constants.%C]
-// CHECK:STDOUT: %.loc8: type = ptr_type %C [template = constants.%.4]
-// CHECK:STDOUT: %d.var: ref %.4 = var d
-// CHECK:STDOUT: %d: ref %.4 = bind_name d, %d.var
+// CHECK:STDOUT: %.loc8: type = ptr_type %C [template = constants.%.5]
+// CHECK:STDOUT: %d.var: ref %.5 = var d
+// CHECK:STDOUT: %d: ref %.5 = bind_name d, %d.var
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @C {
@@ -258,7 +265,7 @@ var d: D* = &c;
// CHECK:STDOUT: %.loc7_14: init %C = converted %.loc7_13.1, %.loc7_13.2 [template = constants.%struct]
// CHECK:STDOUT: assign file.%c.var, %.loc7_14
// CHECK:STDOUT: %c.ref: ref %C = name_ref c, file.%c
-// CHECK:STDOUT: %.loc8: %.4 = addr_of %c.ref
+// CHECK:STDOUT: %.loc8: %.5 = addr_of %c.ref
// CHECK:STDOUT: assign file.%d.var, %.loc8
// CHECK:STDOUT: return
// CHECK:STDOUT: }
diff --git a/toolchain/check/testdata/alias/no_prelude/fail_aliased_name_in_diag.carbon b/toolchain/check/testdata/alias/no_prelude/fail_aliased_name_in_diag.carbon
index c841e1a739bad..d6155b6596762 100644
--- a/toolchain/check/testdata/alias/no_prelude/fail_aliased_name_in_diag.carbon
+++ b/toolchain/check/testdata/alias/no_prelude/fail_aliased_name_in_diag.carbon
@@ -24,9 +24,10 @@ let c_var: c = d;
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %C: type = class_type @C [template]
// CHECK:STDOUT: %.1: type = struct_type {} [template]
+// CHECK:STDOUT: %.2: = complete_type_witness %.1 [template]
// CHECK:STDOUT: %D: type = class_type @D [template]
-// CHECK:STDOUT: %.2: type = tuple_type () [template]
-// CHECK:STDOUT: %.3: type = ptr_type %.1 [template]
+// CHECK:STDOUT: %.3: type = tuple_type () [template]
+// CHECK:STDOUT: %.4: type = ptr_type %.1 [template]
// CHECK:STDOUT: %struct: %D = struct_value () [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -49,11 +50,15 @@ let c_var: c = d;
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @C {
+// CHECK:STDOUT: %.loc11: = complete_type_witness %.1 [template = constants.%.2]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%C
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @D {
+// CHECK:STDOUT: %.loc12: = complete_type_witness %.1 [template = constants.%.2]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%D
// CHECK:STDOUT: }
diff --git a/toolchain/check/testdata/alias/no_prelude/fail_modifiers.carbon b/toolchain/check/testdata/alias/no_prelude/fail_modifiers.carbon
index 85677aad24ed0..7d47bba4016d8 100644
--- a/toolchain/check/testdata/alias/no_prelude/fail_modifiers.carbon
+++ b/toolchain/check/testdata/alias/no_prelude/fail_modifiers.carbon
@@ -53,6 +53,7 @@ extern alias C = Class;
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %Class: type = class_type @Class [template]
// CHECK:STDOUT: %.1: type = struct_type {} [template]
+// CHECK:STDOUT: %.2: = complete_type_witness %.1 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
@@ -72,6 +73,8 @@ extern alias C = Class;
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @Class {
+// CHECK:STDOUT: %.loc11: = complete_type_witness %.1 [template = constants.%.2]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%Class
// CHECK:STDOUT: }
diff --git a/toolchain/check/testdata/alias/no_prelude/fail_name_conflict.carbon b/toolchain/check/testdata/alias/no_prelude/fail_name_conflict.carbon
index a7e974b069e21..d1fd15f7c0c2b 100644
--- a/toolchain/check/testdata/alias/no_prelude/fail_name_conflict.carbon
+++ b/toolchain/check/testdata/alias/no_prelude/fail_name_conflict.carbon
@@ -34,8 +34,9 @@ alias b = C;
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %C: type = class_type @C [template]
// CHECK:STDOUT: %.1: type = struct_type {} [template]
-// CHECK:STDOUT: %.2: type = tuple_type () [template]
-// CHECK:STDOUT: %.3: type = ptr_type %.1 [template]
+// CHECK:STDOUT: %.2: = complete_type_witness %.1 [template]
+// CHECK:STDOUT: %.3: type = tuple_type () [template]
+// CHECK:STDOUT: %.4: type = ptr_type %.1 [template]
// CHECK:STDOUT: %struct: %C = struct_value () [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -59,6 +60,8 @@ alias b = C;
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @C {
+// CHECK:STDOUT: %.loc11: = complete_type_witness %.1 [template = constants.%.2]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%C
// CHECK:STDOUT: }
diff --git a/toolchain/check/testdata/alias/no_prelude/import.carbon b/toolchain/check/testdata/alias/no_prelude/import.carbon
index d691dd0a9c682..2494c159a482b 100644
--- a/toolchain/check/testdata/alias/no_prelude/import.carbon
+++ b/toolchain/check/testdata/alias/no_prelude/import.carbon
@@ -73,7 +73,8 @@ var c: () = a_alias_alias;
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %C: type = class_type @C [template]
// CHECK:STDOUT: %.1: type = struct_type {} [template]
-// CHECK:STDOUT: %.2: type = ptr_type %C [template]
+// CHECK:STDOUT: %.2: = complete_type_witness %.1 [template]
+// CHECK:STDOUT: %.3: type = ptr_type %C [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
@@ -86,12 +87,14 @@ var c: () = a_alias_alias;
// CHECK:STDOUT: %C.ref.loc6: type = name_ref C, %C.decl [template = constants.%C]
// CHECK:STDOUT: %c_alias: type = bind_alias c_alias, %C.decl [template = constants.%C]
// CHECK:STDOUT: %C.ref.loc8: type = name_ref C, %C.decl [template = constants.%C]
-// CHECK:STDOUT: %.loc8: type = ptr_type %C [template = constants.%.2]
-// CHECK:STDOUT: %a.var: ref %.2 = var a
-// CHECK:STDOUT: %a: ref %.2 = bind_name a, %a.var
+// CHECK:STDOUT: %.loc8: type = ptr_type %C [template = constants.%.3]
+// CHECK:STDOUT: %a.var: ref %.3 = var a
+// CHECK:STDOUT: %a: ref %.3 = bind_name a, %a.var
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @C {
+// CHECK:STDOUT: %.loc4: = complete_type_witness %.1 [template = constants.%.2]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%C
// CHECK:STDOUT: }
@@ -101,13 +104,14 @@ var c: () = a_alias_alias;
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %C: type = class_type @C [template]
// CHECK:STDOUT: %.1: type = struct_type {} [template]
-// CHECK:STDOUT: %.2: type = ptr_type %C [template]
+// CHECK:STDOUT: %.2: = complete_type_witness %.1 [template]
+// CHECK:STDOUT: %.3: type = ptr_type %C [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %import_ref.1 = import_ref Main//class1, inst+1, unloaded
-// CHECK:STDOUT: %import_ref.2: type = import_ref Main//class1, inst+5, loaded [template = constants.%C]
-// CHECK:STDOUT: %import_ref.3 = import_ref Main//class1, inst+10, unloaded
+// CHECK:STDOUT: %import_ref.2: type = import_ref Main//class1, inst+7, loaded [template = constants.%C]
+// CHECK:STDOUT: %import_ref.3 = import_ref Main//class1, inst+12, unloaded
// CHECK:STDOUT: %import_ref.4 = import_ref Main//class1, inst+2, unloaded
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -123,9 +127,9 @@ var c: () = a_alias_alias;
// CHECK:STDOUT: %c_alias.ref.loc6: type = name_ref c_alias, imports.%import_ref.2 [template = constants.%C]
// CHECK:STDOUT: %c_alias_alias: type = bind_alias c_alias_alias, imports.%import_ref.2 [template = constants.%C]
// CHECK:STDOUT: %c_alias.ref.loc8: type = name_ref c_alias, imports.%import_ref.2 [template = constants.%C]
-// CHECK:STDOUT: %.loc8: type = ptr_type %C [template = constants.%.2]
-// CHECK:STDOUT: %b.var: ref %.2 = var b
-// CHECK:STDOUT: %b: ref %.2 = bind_name b, %b.var
+// CHECK:STDOUT: %.loc8: type = ptr_type %C [template = constants.%.3]
+// CHECK:STDOUT: %b.var: ref %.3 = var b
+// CHECK:STDOUT: %b: ref %.3 = bind_name b, %b.var
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @C {
@@ -138,13 +142,14 @@ var c: () = a_alias_alias;
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %C: type = class_type @C [template]
// CHECK:STDOUT: %.1: type = struct_type {} [template]
-// CHECK:STDOUT: %.2: type = ptr_type %C [template]
+// CHECK:STDOUT: %.2: = complete_type_witness %.1 [template]
+// CHECK:STDOUT: %.3: type = ptr_type %C [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
-// CHECK:STDOUT: %import_ref.1: type = import_ref Main//class2, inst+10, loaded [template = constants.%C]
-// CHECK:STDOUT: %import_ref.2 = import_ref Main//class2, inst+15, unloaded
-// CHECK:STDOUT: %import_ref.3 = import_ref Main//class2, inst+8, unloaded
+// CHECK:STDOUT: %import_ref.1: type = import_ref Main//class2, inst+11, loaded [template = constants.%C]
+// CHECK:STDOUT: %import_ref.2 = import_ref Main//class2, inst+16, unloaded
+// CHECK:STDOUT: %import_ref.3 = import_ref Main//class2, inst+9, unloaded
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
@@ -155,9 +160,9 @@ var c: () = a_alias_alias;
// CHECK:STDOUT: }
// CHECK:STDOUT: %default.import = import
// CHECK:STDOUT: %c_alias_alias.ref: type = name_ref c_alias_alias, imports.%import_ref.1 [template = constants.%C]
-// CHECK:STDOUT: %.loc6: type = ptr_type %C [template = constants.%.2]
-// CHECK:STDOUT: %c.var: ref %.2 = var c
-// CHECK:STDOUT: %c: ref %.2 = bind_name c, %c.var
+// CHECK:STDOUT: %.loc6: type = ptr_type %C [template = constants.%.3]
+// CHECK:STDOUT: %c.var: ref %.3 = var c
+// CHECK:STDOUT: %c: ref %.3 = bind_name c, %c.var
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @C {
diff --git a/toolchain/check/testdata/alias/no_prelude/import_access.carbon b/toolchain/check/testdata/alias/no_prelude/import_access.carbon
index 9feda8afec012..1c4aac6aa407a 100644
--- a/toolchain/check/testdata/alias/no_prelude/import_access.carbon
+++ b/toolchain/check/testdata/alias/no_prelude/import_access.carbon
@@ -57,6 +57,7 @@ var inst: Test.A = {};
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %C: type = class_type @C [template]
// CHECK:STDOUT: %.1: type = struct_type {} [template]
+// CHECK:STDOUT: %.2: = complete_type_witness %.1 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
@@ -70,6 +71,8 @@ var inst: Test.A = {};
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @C {
+// CHECK:STDOUT: %.loc4: = complete_type_witness %.1 [template = constants.%.2]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%C
// CHECK:STDOUT: }
@@ -79,14 +82,15 @@ var inst: Test.A = {};
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %C: type = class_type @C [template]
// CHECK:STDOUT: %.1: type = struct_type {} [template]
-// CHECK:STDOUT: %.2: type = tuple_type () [template]
-// CHECK:STDOUT: %.3: type = ptr_type %.1 [template]
+// CHECK:STDOUT: %.2: = complete_type_witness %.1 [template]
+// CHECK:STDOUT: %.3: type = tuple_type () [template]
+// CHECK:STDOUT: %.4: type = ptr_type %.1 [template]
// CHECK:STDOUT: %struct: %C = struct_value () [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %import_ref.1 = import_ref Test//def, inst+1, unloaded
-// CHECK:STDOUT: %import_ref.2: type = import_ref Test//def, inst+5, loaded [template = constants.%C]
+// CHECK:STDOUT: %import_ref.2: type = import_ref Test//def, inst+7, loaded [template = constants.%C]
// CHECK:STDOUT: %import_ref.3 = import_ref Test//def, inst+2, unloaded
// CHECK:STDOUT: }
// CHECK:STDOUT:
diff --git a/toolchain/check/testdata/alias/no_prelude/import_order.carbon b/toolchain/check/testdata/alias/no_prelude/import_order.carbon
index 913c302343750..b198a10ff0b2f 100644
--- a/toolchain/check/testdata/alias/no_prelude/import_order.carbon
+++ b/toolchain/check/testdata/alias/no_prelude/import_order.carbon
@@ -37,6 +37,7 @@ var a_val: a = {.v = b_val.v};
// CHECK:STDOUT: %.1: type = tuple_type () [template]
// CHECK:STDOUT: %.2: type = unbound_element_type %C, %.1 [template]
// CHECK:STDOUT: %.3: type = struct_type {.v: %.1} [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
@@ -62,6 +63,7 @@ var a_val: a = {.v = b_val.v};
// CHECK:STDOUT: %.loc4_19.1: %.1 = tuple_literal ()
// CHECK:STDOUT: %.loc4_19.2: type = converted %.loc4_19.1, constants.%.1 [template = constants.%.1]
// CHECK:STDOUT: %.loc4_16: %.2 = field_decl v, element0 [template]
+// CHECK:STDOUT: %.loc4_22: = complete_type_witness %.3 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%C
@@ -74,20 +76,21 @@ var a_val: a = {.v = b_val.v};
// CHECK:STDOUT: %C: type = class_type @C [template]
// CHECK:STDOUT: %.1: type = tuple_type () [template]
// CHECK:STDOUT: %.2: type = struct_type {.v: %.1} [template]
-// CHECK:STDOUT: %.3: type = ptr_type %.2 [template]
+// CHECK:STDOUT: %.3: = complete_type_witness %.2 [template]
+// CHECK:STDOUT: %.4: type = ptr_type %.2 [template]
// CHECK:STDOUT: %tuple: %.1 = tuple_value () [template]
// CHECK:STDOUT: %struct: %C = struct_value (%tuple) [template]
-// CHECK:STDOUT: %.4: type = unbound_element_type %C, %.1 [template]
+// CHECK:STDOUT: %.5: type = unbound_element_type %C, %.1 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %import_ref.1 = import_ref Main//a, inst+1, unloaded
-// CHECK:STDOUT: %import_ref.2: type = import_ref Main//a, inst+12, loaded [template = constants.%C]
-// CHECK:STDOUT: %import_ref.3: type = import_ref Main//a, inst+14, loaded [template = constants.%C]
-// CHECK:STDOUT: %import_ref.4: type = import_ref Main//a, inst+16, loaded [template = constants.%C]
-// CHECK:STDOUT: %import_ref.5: type = import_ref Main//a, inst+18, loaded [template = constants.%C]
+// CHECK:STDOUT: %import_ref.2: type = import_ref Main//a, inst+14, loaded [template = constants.%C]
+// CHECK:STDOUT: %import_ref.3: type = import_ref Main//a, inst+16, loaded [template = constants.%C]
+// CHECK:STDOUT: %import_ref.4: type = import_ref Main//a, inst+18, loaded [template = constants.%C]
+// CHECK:STDOUT: %import_ref.5: type = import_ref Main//a, inst+20, loaded [template = constants.%C]
// CHECK:STDOUT: %import_ref.6 = import_ref Main//a, inst+2, unloaded
-// CHECK:STDOUT: %import_ref.7: %.4 = import_ref Main//a, inst+7, loaded [template = %.1]
+// CHECK:STDOUT: %import_ref.7: %.5 = import_ref Main//a, inst+7, loaded [template = %.1]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
@@ -134,7 +137,7 @@ var a_val: a = {.v = b_val.v};
// CHECK:STDOUT: %.loc7_25: init %C = converted %.loc7_24.1, %.loc7_24.4 [template = constants.%struct]
// CHECK:STDOUT: assign file.%d_val.var, %.loc7_25
// CHECK:STDOUT: %d_val.ref: ref %C = name_ref d_val, file.%d_val
-// CHECK:STDOUT: %v.ref.loc8: %.4 = name_ref v, imports.%import_ref.7 [template = imports.%.1]
+// CHECK:STDOUT: %v.ref.loc8: %.5 = name_ref v, imports.%import_ref.7 [template = imports.%.1]
// CHECK:STDOUT: %.loc8_27.1: ref %.1 = class_element_access %d_val.ref, element0
// CHECK:STDOUT: %.loc8_29.1: %.2 = struct_literal (%.loc8_27.1)
// CHECK:STDOUT: %.loc8_29.2: ref %.1 = class_element_access file.%c_val.var, element0
@@ -144,7 +147,7 @@ var a_val: a = {.v = b_val.v};
// CHECK:STDOUT: %.loc8_30: init %C = converted %.loc8_29.1, %.loc8_29.4 [template = constants.%struct]
// CHECK:STDOUT: assign file.%c_val.var, %.loc8_30
// CHECK:STDOUT: %c_val.ref: ref %C = name_ref c_val, file.%c_val
-// CHECK:STDOUT: %v.ref.loc9: %.4 = name_ref v, imports.%import_ref.7 [template = imports.%.1]
+// CHECK:STDOUT: %v.ref.loc9: %.5 = name_ref v, imports.%import_ref.7 [template = imports.%.1]
// CHECK:STDOUT: %.loc9_27.1: ref %.1 = class_element_access %c_val.ref, element0
// CHECK:STDOUT: %.loc9_29.1: %.2 = struct_literal (%.loc9_27.1)
// CHECK:STDOUT: %.loc9_29.2: ref %.1 = class_element_access file.%b_val.var, element0
@@ -154,7 +157,7 @@ var a_val: a = {.v = b_val.v};
// CHECK:STDOUT: %.loc9_30: init %C = converted %.loc9_29.1, %.loc9_29.4 [template = constants.%struct]
// CHECK:STDOUT: assign file.%b_val.var, %.loc9_30
// CHECK:STDOUT: %b_val.ref: ref %C = name_ref b_val, file.%b_val
-// CHECK:STDOUT: %v.ref.loc10: %.4 = name_ref v, imports.%import_ref.7 [template = imports.%.1]
+// CHECK:STDOUT: %v.ref.loc10: %.5 = name_ref v, imports.%import_ref.7 [template = imports.%.1]
// CHECK:STDOUT: %.loc10_27.1: ref %.1 = class_element_access %b_val.ref, element0
// CHECK:STDOUT: %.loc10_29.1: %.2 = struct_literal (%.loc10_27.1)
// CHECK:STDOUT: %.loc10_29.2: ref %.1 = class_element_access file.%a_val.var, element0
diff --git a/toolchain/check/testdata/alias/no_prelude/in_namespace.carbon b/toolchain/check/testdata/alias/no_prelude/in_namespace.carbon
index 3a09375cf3633..b410292129907 100644
--- a/toolchain/check/testdata/alias/no_prelude/in_namespace.carbon
+++ b/toolchain/check/testdata/alias/no_prelude/in_namespace.carbon
@@ -26,7 +26,8 @@ fn F() -> NS.a {
// CHECK:STDOUT: %.1: type = tuple_type () [template]
// CHECK:STDOUT: %.2: type = unbound_element_type %C, %.1 [template]
// CHECK:STDOUT: %.3: type = struct_type {.v: %.1} [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
// CHECK:STDOUT: %tuple: %.1 = tuple_value () [template]
// CHECK:STDOUT: %struct: %C = struct_value (%tuple) [template]
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
@@ -59,6 +60,7 @@ fn F() -> NS.a {
// CHECK:STDOUT: %.loc11_19.1: %.1 = tuple_literal ()
// CHECK:STDOUT: %.loc11_19.2: type = converted %.loc11_19.1, constants.%.1 [template = constants.%.1]
// CHECK:STDOUT: %.loc11_16: %.2 = field_decl v, element0 [template]
+// CHECK:STDOUT: %.loc11_22: = complete_type_witness %.3 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%C
diff --git a/toolchain/check/testdata/as/adapter_conversion.carbon b/toolchain/check/testdata/as/adapter_conversion.carbon
index 2c6a568726819..13fbdcd9ecbd5 100644
--- a/toolchain/check/testdata/as/adapter_conversion.carbon
+++ b/toolchain/check/testdata/as/adapter_conversion.carbon
@@ -116,12 +116,14 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT: %Make.type: type = fn_type @Make [template]
// CHECK:STDOUT: %Make: %Make.type = struct_value () [template]
// CHECK:STDOUT: %.3: type = struct_type {.x: i32, .y: i32} [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
-// CHECK:STDOUT: %.5: i32 = int_literal 1 [template]
-// CHECK:STDOUT: %.6: i32 = int_literal 2 [template]
-// CHECK:STDOUT: %struct: %A = struct_value (%.5, %.6) [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.6: i32 = int_literal 1 [template]
+// CHECK:STDOUT: %.7: i32 = int_literal 2 [template]
+// CHECK:STDOUT: %struct: %A = struct_value (%.6, %.7) [template]
// CHECK:STDOUT: %B: type = class_type @B [template]
-// CHECK:STDOUT: %.7: type = ptr_type %B [template]
+// CHECK:STDOUT: %.8: = complete_type_witness %A [template]
+// CHECK:STDOUT: %.9: type = ptr_type %B [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -159,7 +161,7 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT: %A.ref.loc18: type = name_ref A, %A.decl [template = constants.%A]
// CHECK:STDOUT: %B.ref.loc21: type = name_ref B, %B.decl [template = constants.%B]
// CHECK:STDOUT: %B.ref.loc22: type = name_ref B, %B.decl [template = constants.%B]
-// CHECK:STDOUT: %.loc22: type = ptr_type %B [template = constants.%.7]
+// CHECK:STDOUT: %.loc22: type = ptr_type %B [template = constants.%.9]
// CHECK:STDOUT: %B.ref.loc24: type = name_ref B, %B.decl [template = constants.%B]
// CHECK:STDOUT: %b_factory.var: ref %B = var b_factory
// CHECK:STDOUT: %b_factory: ref %B = bind_name b_factory, %b_factory.var
@@ -178,6 +180,7 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A]
// CHECK:STDOUT: %return.var: ref %A = var
// CHECK:STDOUT: }
+// CHECK:STDOUT: %.loc11: = complete_type_witness %.3 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%A
@@ -189,6 +192,7 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT: class @B {
// CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A]
// CHECK:STDOUT: adapt_decl %A
+// CHECK:STDOUT: %.loc15: = complete_type_witness %A [template = constants.%.8]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%B
@@ -198,13 +202,13 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Make() -> @A.%return.var: %A {
// CHECK:STDOUT: !entry:
-// CHECK:STDOUT: %.loc9_18: i32 = int_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %.loc9_26: i32 = int_literal 2 [template = constants.%.6]
+// CHECK:STDOUT: %.loc9_18: i32 = int_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc9_26: i32 = int_literal 2 [template = constants.%.7]
// CHECK:STDOUT: %.loc9_27.1: %.3 = struct_literal (%.loc9_18, %.loc9_26)
// CHECK:STDOUT: %.loc9_27.2: ref i32 = class_element_access @A.%return.var, element0
-// CHECK:STDOUT: %.loc9_27.3: init i32 = initialize_from %.loc9_18 to %.loc9_27.2 [template = constants.%.5]
+// CHECK:STDOUT: %.loc9_27.3: init i32 = initialize_from %.loc9_18 to %.loc9_27.2 [template = constants.%.6]
// CHECK:STDOUT: %.loc9_27.4: ref i32 = class_element_access @A.%return.var, element1
-// CHECK:STDOUT: %.loc9_27.5: init i32 = initialize_from %.loc9_26 to %.loc9_27.4 [template = constants.%.6]
+// CHECK:STDOUT: %.loc9_27.5: init i32 = initialize_from %.loc9_26 to %.loc9_27.4 [template = constants.%.7]
// CHECK:STDOUT: %.loc9_27.6: init %A = class_init (%.loc9_27.3, %.loc9_27.5), @A.%return.var [template = constants.%struct]
// CHECK:STDOUT: %.loc9_28: init %A = converted %.loc9_27.1, %.loc9_27.6 [template = constants.%struct]
// CHECK:STDOUT: return %.loc9_28 to @A.%return.var
@@ -212,13 +216,13 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT:
// CHECK:STDOUT: fn @__global_init() {
// CHECK:STDOUT: !entry:
-// CHECK:STDOUT: %.loc17_22: i32 = int_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %.loc17_30: i32 = int_literal 2 [template = constants.%.6]
+// CHECK:STDOUT: %.loc17_22: i32 = int_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc17_30: i32 = int_literal 2 [template = constants.%.7]
// CHECK:STDOUT: %.loc17_31.1: %.3 = struct_literal (%.loc17_22, %.loc17_30)
// CHECK:STDOUT: %.loc17_31.2: ref i32 = class_element_access file.%a_ref.var, element0
-// CHECK:STDOUT: %.loc17_31.3: init i32 = initialize_from %.loc17_22 to %.loc17_31.2 [template = constants.%.5]
+// CHECK:STDOUT: %.loc17_31.3: init i32 = initialize_from %.loc17_22 to %.loc17_31.2 [template = constants.%.6]
// CHECK:STDOUT: %.loc17_31.4: ref i32 = class_element_access file.%a_ref.var, element1
-// CHECK:STDOUT: %.loc17_31.5: init i32 = initialize_from %.loc17_30 to %.loc17_31.4 [template = constants.%.6]
+// CHECK:STDOUT: %.loc17_31.5: init i32 = initialize_from %.loc17_30 to %.loc17_31.4 [template = constants.%.7]
// CHECK:STDOUT: %.loc17_31.6: init %A = class_init (%.loc17_31.3, %.loc17_31.5), file.%a_ref.var [template = constants.%struct]
// CHECK:STDOUT: %.loc17_32: init %A = converted %.loc17_31.1, %.loc17_31.6 [template = constants.%struct]
// CHECK:STDOUT: assign file.%a_ref.var, %.loc17_32
@@ -234,8 +238,8 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT: %B.ref.loc22: type = name_ref B, file.%B.decl [template = constants.%B]
// CHECK:STDOUT: %.loc22_25.1: ref %B = as_compatible %a_ref.ref.loc22
// CHECK:STDOUT: %.loc22_25.2: ref %B = converted %a_ref.ref.loc22, %.loc22_25.1
-// CHECK:STDOUT: %.loc22_17: %.7 = addr_of %.loc22_25.2
-// CHECK:STDOUT: %b_ptr: %.7 = bind_name b_ptr, %.loc22_17
+// CHECK:STDOUT: %.loc22_17: %.9 = addr_of %.loc22_25.2
+// CHECK:STDOUT: %b_ptr: %.9 = bind_name b_ptr, %.loc22_17
// CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A]
// CHECK:STDOUT: %Make.ref: %Make.type = name_ref Make, @A.%Make.decl [template = constants.%Make]
// CHECK:STDOUT: %.loc24_5: ref %B = splice_block file.%b_factory.var {}
@@ -254,7 +258,8 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT: %Int32.type: type = fn_type @Int32 [template]
// CHECK:STDOUT: %.1: type = tuple_type () [template]
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
-// CHECK:STDOUT: %.2: i32 = int_literal 1 [template]
+// CHECK:STDOUT: %.2: = complete_type_witness i32 [template]
+// CHECK:STDOUT: %.3: i32 = int_literal 1 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -292,6 +297,7 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT: %.loc5_12.1: type = value_of_initializer %int.make_type_32 [template = i32]
// CHECK:STDOUT: %.loc5_12.2: type = converted %int.make_type_32, %.loc5_12.1 [template = i32]
// CHECK:STDOUT: adapt_decl i32
+// CHECK:STDOUT: %.loc6: = complete_type_witness i32 [template = constants.%.2]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%A
@@ -301,13 +307,13 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT:
// CHECK:STDOUT: fn @__global_init() {
// CHECK:STDOUT: !entry:
-// CHECK:STDOUT: %.loc8_13: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT: %.loc8_13: i32 = int_literal 1 [template = constants.%.3]
// CHECK:STDOUT: %int.make_type_32.loc8: init type = call constants.%Int32() [template = i32]
// CHECK:STDOUT: %.loc8_18.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
// CHECK:STDOUT: %.loc8_18.2: type = converted %int.make_type_32.loc8, %.loc8_18.1 [template = i32]
// CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A]
-// CHECK:STDOUT: %.loc8_23.1: %A = as_compatible %.loc8_13 [template = constants.%.2]
-// CHECK:STDOUT: %.loc8_23.2: %A = converted %.loc8_13, %.loc8_23.1 [template = constants.%.2]
+// CHECK:STDOUT: %.loc8_23.1: %A = as_compatible %.loc8_13 [template = constants.%.3]
+// CHECK:STDOUT: %.loc8_23.2: %A = converted %.loc8_13, %.loc8_23.1 [template = constants.%.3]
// CHECK:STDOUT: %a: %A = bind_name a, %.loc8_23.2
// CHECK:STDOUT: %a.ref: %A = name_ref a, %a
// CHECK:STDOUT: %int.make_type_32.loc9: init type = call constants.%Int32() [template = i32]
@@ -325,6 +331,7 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT: %A: type = class_type @A [template]
// CHECK:STDOUT: %.1: type = struct_type {} [template]
// CHECK:STDOUT: %.2: type = tuple_type () [template]
+// CHECK:STDOUT: %.3: = complete_type_witness %.1 [template]
// CHECK:STDOUT: %B: type = class_type @B [template]
// CHECK:STDOUT: %C: type = class_type @C [template]
// CHECK:STDOUT: %D: type = class_type @D [template]
@@ -365,6 +372,7 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT: %.loc4_18: %.1 = struct_literal ()
// CHECK:STDOUT: %.loc4_19: type = converted %.loc4_18, constants.%.1 [template = constants.%.1]
// CHECK:STDOUT: adapt_decl %.1
+// CHECK:STDOUT: %.loc4_21: = complete_type_witness %.1 [template = constants.%.3]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%A
@@ -414,11 +422,13 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
// CHECK:STDOUT: %.2: type = unbound_element_type %A, i32 [template]
// CHECK:STDOUT: %.3: type = struct_type {.x: i32, .y: i32} [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
// CHECK:STDOUT: %B: type = class_type @B [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
-// CHECK:STDOUT: %.5: i32 = int_literal 1 [template]
-// CHECK:STDOUT: %.6: i32 = int_literal 2 [template]
-// CHECK:STDOUT: %struct: %A = struct_value (%.5, %.6) [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.6: = complete_type_witness %A [template]
+// CHECK:STDOUT: %.7: i32 = int_literal 1 [template]
+// CHECK:STDOUT: %.8: i32 = int_literal 2 [template]
+// CHECK:STDOUT: %struct: %A = struct_value (%.7, %.8) [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -462,6 +472,7 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT: %.loc6_10.1: type = value_of_initializer %int.make_type_32.loc6 [template = i32]
// CHECK:STDOUT: %.loc6_10.2: type = converted %int.make_type_32.loc6, %.loc6_10.1 [template = i32]
// CHECK:STDOUT: %.loc6_8: %.2 = field_decl y, element1 [template]
+// CHECK:STDOUT: %.loc7: = complete_type_witness %.3 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%A
@@ -472,6 +483,7 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT: class @B {
// CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A]
// CHECK:STDOUT: adapt_decl %A
+// CHECK:STDOUT: %.loc11: = complete_type_witness %A [template = constants.%.6]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%B
@@ -481,15 +493,15 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT:
// CHECK:STDOUT: fn @__global_init() {
// CHECK:STDOUT: !entry:
-// CHECK:STDOUT: %.loc13_25: i32 = int_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %.loc13_33: i32 = int_literal 2 [template = constants.%.6]
+// CHECK:STDOUT: %.loc13_25: i32 = int_literal 1 [template = constants.%.7]
+// CHECK:STDOUT: %.loc13_33: i32 = int_literal 2 [template = constants.%.8]
// CHECK:STDOUT: %.loc13_34.1: %.3 = struct_literal (%.loc13_25, %.loc13_33)
// CHECK:STDOUT: %A.ref.loc13: type = name_ref A, file.%A.decl [template = constants.%A]
// CHECK:STDOUT: %.loc13_34.2: ref %A = temporary_storage
// CHECK:STDOUT: %.loc13_34.3: ref i32 = class_element_access %.loc13_34.2, element0
-// CHECK:STDOUT: %.loc13_34.4: init i32 = initialize_from %.loc13_25 to %.loc13_34.3 [template = constants.%.5]
+// CHECK:STDOUT: %.loc13_34.4: init i32 = initialize_from %.loc13_25 to %.loc13_34.3 [template = constants.%.7]
// CHECK:STDOUT: %.loc13_34.5: ref i32 = class_element_access %.loc13_34.2, element1
-// CHECK:STDOUT: %.loc13_34.6: init i32 = initialize_from %.loc13_33 to %.loc13_34.5 [template = constants.%.6]
+// CHECK:STDOUT: %.loc13_34.6: init i32 = initialize_from %.loc13_33 to %.loc13_34.5 [template = constants.%.8]
// CHECK:STDOUT: %.loc13_34.7: init %A = class_init (%.loc13_34.4, %.loc13_34.6), %.loc13_34.2 [template = constants.%struct]
// CHECK:STDOUT: %.loc13_34.8: ref %A = temporary %.loc13_34.2, %.loc13_34.7
// CHECK:STDOUT: %.loc13_36: ref %A = converted %.loc13_34.1, %.loc13_34.8
@@ -498,15 +510,15 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT: %.loc13_42.2: ref %B = converted %.loc13_36, %.loc13_42.1
// CHECK:STDOUT: %.loc13_42.3: %B = bind_value %.loc13_42.2
// CHECK:STDOUT: %b_value: %B = bind_name b_value, %.loc13_42.3
-// CHECK:STDOUT: %.loc24_24: i32 = int_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %.loc24_32: i32 = int_literal 2 [template = constants.%.6]
+// CHECK:STDOUT: %.loc24_24: i32 = int_literal 1 [template = constants.%.7]
+// CHECK:STDOUT: %.loc24_32: i32 = int_literal 2 [template = constants.%.8]
// CHECK:STDOUT: %.loc24_33.1: %.3 = struct_literal (%.loc24_24, %.loc24_32)
// CHECK:STDOUT: %A.ref.loc24: type = name_ref A, file.%A.decl [template = constants.%A]
// CHECK:STDOUT: %.loc24_33.2: ref %A = temporary_storage
// CHECK:STDOUT: %.loc24_33.3: ref i32 = class_element_access %.loc24_33.2, element0
-// CHECK:STDOUT: %.loc24_33.4: init i32 = initialize_from %.loc24_24 to %.loc24_33.3 [template = constants.%.5]
+// CHECK:STDOUT: %.loc24_33.4: init i32 = initialize_from %.loc24_24 to %.loc24_33.3 [template = constants.%.7]
// CHECK:STDOUT: %.loc24_33.5: ref i32 = class_element_access %.loc24_33.2, element1
-// CHECK:STDOUT: %.loc24_33.6: init i32 = initialize_from %.loc24_32 to %.loc24_33.5 [template = constants.%.6]
+// CHECK:STDOUT: %.loc24_33.6: init i32 = initialize_from %.loc24_32 to %.loc24_33.5 [template = constants.%.8]
// CHECK:STDOUT: %.loc24_33.7: init %A = class_init (%.loc24_33.4, %.loc24_33.6), %.loc24_33.2 [template = constants.%struct]
// CHECK:STDOUT: %.loc24_33.8: ref %A = temporary %.loc24_33.2, %.loc24_33.7
// CHECK:STDOUT: %.loc24_35: ref %A = converted %.loc24_33.1, %.loc24_33.8
@@ -527,26 +539,28 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
// CHECK:STDOUT: %.2: type = unbound_element_type %A, i32 [template]
// CHECK:STDOUT: %.3: type = struct_type {.x: i32} [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
// CHECK:STDOUT: %B: type = class_type @B [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
-// CHECK:STDOUT: %.5: i32 = int_literal 1 [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.6: = complete_type_witness %A [template]
+// CHECK:STDOUT: %.7: i32 = int_literal 1 [template]
// CHECK:STDOUT: %As.type: type = generic_interface_type @As [template]
// CHECK:STDOUT: %As: %As.type = struct_value () [template]
// CHECK:STDOUT: %Dest: type = bind_symbolic_name Dest 0 [symbolic]
-// CHECK:STDOUT: %.6: type = interface_type @As, @As(%Dest) [symbolic]
-// CHECK:STDOUT: %Self.1: @As.%.1 (%.6) = bind_symbolic_name Self 1 [symbolic]
-// CHECK:STDOUT: %Self.2: %.6 = bind_symbolic_name Self 1 [symbolic]
+// CHECK:STDOUT: %.8: type = interface_type @As, @As(%Dest) [symbolic]
+// CHECK:STDOUT: %Self.1: @As.%.1 (%.8) = bind_symbolic_name Self 1 [symbolic]
+// CHECK:STDOUT: %Self.2: %.8 = bind_symbolic_name Self 1 [symbolic]
// CHECK:STDOUT: %Convert.type.1: type = fn_type @Convert, @As(%Dest) [symbolic]
// CHECK:STDOUT: %Convert.1: %Convert.type.1 = struct_value () [symbolic]
-// CHECK:STDOUT: %.7: type = assoc_entity_type %.6, %Convert.type.1 [symbolic]
-// CHECK:STDOUT: %.8: %.7 = assoc_entity element0, imports.%import_ref.6 [symbolic]
-// CHECK:STDOUT: %.9: type = interface_type @As, @As(%B) [template]
+// CHECK:STDOUT: %.9: type = assoc_entity_type %.8, %Convert.type.1 [symbolic]
+// CHECK:STDOUT: %.10: %.9 = assoc_entity element0, imports.%import_ref.6 [symbolic]
+// CHECK:STDOUT: %.11: type = interface_type @As, @As(%B) [template]
// CHECK:STDOUT: %Convert.type.2: type = fn_type @Convert, @As(%B) [template]
// CHECK:STDOUT: %Convert.2: %Convert.type.2 = struct_value () [template]
-// CHECK:STDOUT: %.10: type = assoc_entity_type %.9, %Convert.type.2 [template]
-// CHECK:STDOUT: %.11: %.10 = assoc_entity element0, imports.%import_ref.6 [template]
-// CHECK:STDOUT: %.12: %.7 = assoc_entity element0, imports.%import_ref.7 [symbolic]
-// CHECK:STDOUT: %struct: %.3 = struct_value (%.5) [template]
+// CHECK:STDOUT: %.12: type = assoc_entity_type %.11, %Convert.type.2 [template]
+// CHECK:STDOUT: %.13: %.12 = assoc_entity element0, imports.%import_ref.6 [template]
+// CHECK:STDOUT: %.14: %.9 = assoc_entity element0, imports.%import_ref.7 [symbolic]
+// CHECK:STDOUT: %struct: %.3 = struct_value (%.7) [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -565,7 +579,7 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT: %import_ref.1: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
// CHECK:STDOUT: %import_ref.2: %As.type = import_ref Core//prelude/operators/as, inst+4, loaded [template = constants.%As]
// CHECK:STDOUT: %import_ref.3 = import_ref Core//prelude/operators/as, inst+10, unloaded
-// CHECK:STDOUT: %import_ref.4: @As.%.2 (%.7) = import_ref Core//prelude/operators/as, inst+27, loaded [symbolic = @As.%.3 (constants.%.12)]
+// CHECK:STDOUT: %import_ref.4: @As.%.2 (%.9) = import_ref Core//prelude/operators/as, inst+27, loaded [symbolic = @As.%.3 (constants.%.14)]
// CHECK:STDOUT: %import_ref.5 = import_ref Core//prelude/operators/as, inst+20, unloaded
// CHECK:STDOUT: %import_ref.6 = import_ref Core//prelude/operators/as, inst+20, unloaded
// CHECK:STDOUT: %import_ref.7 = import_ref Core//prelude/operators/as, inst+20, unloaded
@@ -590,12 +604,12 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT: %Dest: type = bind_symbolic_name Dest 0 [symbolic = %Dest (constants.%Dest)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
-// CHECK:STDOUT: %.1: type = interface_type @As, @As(%Dest) [symbolic = %.1 (constants.%.6)]
-// CHECK:STDOUT: %Self: %.6 = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self.2)]
+// CHECK:STDOUT: %.1: type = interface_type @As, @As(%Dest) [symbolic = %.1 (constants.%.8)]
+// CHECK:STDOUT: %Self: %.8 = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self.2)]
// CHECK:STDOUT: %Convert.type: type = fn_type @Convert, @As(%Dest) [symbolic = %Convert.type (constants.%Convert.type.1)]
// CHECK:STDOUT: %Convert: @As.%Convert.type (%Convert.type.1) = struct_value () [symbolic = %Convert (constants.%Convert.1)]
-// CHECK:STDOUT: %.2: type = assoc_entity_type @As.%.1 (%.6), @As.%Convert.type (%Convert.type.1) [symbolic = %.2 (constants.%.7)]
-// CHECK:STDOUT: %.3: @As.%.2 (%.7) = assoc_entity element0, imports.%import_ref.6 [symbolic = %.3 (constants.%.8)]
+// CHECK:STDOUT: %.2: type = assoc_entity_type @As.%.1 (%.8), @As.%Convert.type (%Convert.type.1) [symbolic = %.2 (constants.%.9)]
+// CHECK:STDOUT: %.3: @As.%.2 (%.9) = assoc_entity element0, imports.%import_ref.6 [symbolic = %.3 (constants.%.10)]
// CHECK:STDOUT:
// CHECK:STDOUT: interface {
// CHECK:STDOUT: !members:
@@ -610,6 +624,7 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT: %.loc5_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
// CHECK:STDOUT: %.loc5_10.2: type = converted %int.make_type_32, %.loc5_10.1 [template = i32]
// CHECK:STDOUT: %.loc5_8: %.2 = field_decl x, element0 [template]
+// CHECK:STDOUT: %.loc6: = complete_type_witness %.3 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%A
@@ -619,6 +634,7 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT: class @B {
// CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A]
// CHECK:STDOUT: adapt_decl %A
+// CHECK:STDOUT: %.loc10: = complete_type_witness %A [template = constants.%.6]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%B
@@ -626,22 +642,22 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
// CHECK:STDOUT:
-// CHECK:STDOUT: generic fn @Convert(constants.%Dest: type, constants.%Self.1: @As.%.1 (%.6)) {
+// CHECK:STDOUT: generic fn @Convert(constants.%Dest: type, constants.%Self.1: @As.%.1 (%.8)) {
// CHECK:STDOUT: %Dest: type = bind_symbolic_name Dest 0 [symbolic = %Dest (constants.%Dest)]
-// CHECK:STDOUT: %.1: type = interface_type @As, @As(%Dest) [symbolic = %.1 (constants.%.6)]
-// CHECK:STDOUT: %Self: %.6 = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self.2)]
+// CHECK:STDOUT: %.1: type = interface_type @As, @As(%Dest) [symbolic = %.1 (constants.%.8)]
+// CHECK:STDOUT: %Self: %.8 = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self.2)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn[%self: @Convert.%Self (%Self.2)]() -> @Convert.%Dest (%Dest);
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @__global_init() {
// CHECK:STDOUT: !entry:
-// CHECK:STDOUT: %.loc21_18: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %.loc21_18: i32 = int_literal 1 [template = constants.%.7]
// CHECK:STDOUT: %.loc21_19.1: %.3 = struct_literal (%.loc21_18)
// CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B]
-// CHECK:STDOUT: %.loc21_21.1: type = interface_type @As, @As(constants.%B) [template = constants.%.9]
-// CHECK:STDOUT: %.loc21_21.2: %.10 = specific_constant imports.%import_ref.4, @As(constants.%B) [template = constants.%.11]
-// CHECK:STDOUT: %Convert.ref: %.10 = name_ref Convert, %.loc21_21.2 [template = constants.%.11]
+// CHECK:STDOUT: %.loc21_21.1: type = interface_type @As, @As(constants.%B) [template = constants.%.11]
+// CHECK:STDOUT: %.loc21_21.2: %.12 = specific_constant imports.%import_ref.4, @As(constants.%B) [template = constants.%.13]
+// CHECK:STDOUT: %Convert.ref: %.12 = name_ref Convert, %.loc21_21.2 [template = constants.%.13]
// CHECK:STDOUT: %struct: %.3 = struct_value (%.loc21_18) [template = constants.%struct]
// CHECK:STDOUT: %.loc21_19.2: %.3 = converted %.loc21_19.1, %struct [template = constants.%struct]
// CHECK:STDOUT: %.loc21_21.3: %B = converted %.loc21_19.1, [template = ]
@@ -663,7 +679,7 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT:
// CHECK:STDOUT: specific @Convert(constants.%Dest, constants.%Self.1) {
// CHECK:STDOUT: %Dest => constants.%Dest
-// CHECK:STDOUT: %.1 => constants.%.6
+// CHECK:STDOUT: %.1 => constants.%.8
// CHECK:STDOUT: %Self => constants.%Self.1
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -671,11 +687,11 @@ var b: B = {.x = 1} as B;
// CHECK:STDOUT: %Dest => constants.%B
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
-// CHECK:STDOUT: %.1 => constants.%.9
+// CHECK:STDOUT: %.1 => constants.%.11
// CHECK:STDOUT: %Self => constants.%Self.2
// CHECK:STDOUT: %Convert.type => constants.%Convert.type.2
// CHECK:STDOUT: %Convert => constants.%Convert.2
-// CHECK:STDOUT: %.2 => constants.%.10
-// CHECK:STDOUT: %.3 => constants.%.11
+// CHECK:STDOUT: %.2 => constants.%.12
+// CHECK:STDOUT: %.3 => constants.%.13
// CHECK:STDOUT: }
// CHECK:STDOUT:
diff --git a/toolchain/check/testdata/as/identity.carbon b/toolchain/check/testdata/as/identity.carbon
index a05b981a76953..fc949a3abf990 100644
--- a/toolchain/check/testdata/as/identity.carbon
+++ b/toolchain/check/testdata/as/identity.carbon
@@ -33,11 +33,12 @@ fn Initializing() {
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %X: type = class_type @X [template]
// CHECK:STDOUT: %.1: type = struct_type {} [template]
+// CHECK:STDOUT: %.2: = complete_type_witness %.1 [template]
// CHECK:STDOUT: %Value.type: type = fn_type @Value [template]
-// CHECK:STDOUT: %.2: type = tuple_type () [template]
+// CHECK:STDOUT: %.3: type = tuple_type () [template]
// CHECK:STDOUT: %Value: %Value.type = struct_value () [template]
-// CHECK:STDOUT: %.3: type = ptr_type %.1 [template]
-// CHECK:STDOUT: %.4: type = ptr_type %X [template]
+// CHECK:STDOUT: %.4: type = ptr_type %.1 [template]
+// CHECK:STDOUT: %.5: type = ptr_type %X [template]
// CHECK:STDOUT: %Reference.type: type = fn_type @Reference [template]
// CHECK:STDOUT: %Reference: %Reference.type = struct_value () [template]
// CHECK:STDOUT: %Make.type: type = fn_type @Make [template]
@@ -77,9 +78,9 @@ fn Initializing() {
// CHECK:STDOUT: }
// CHECK:STDOUT: %Reference.decl: %Reference.type = fn_decl @Reference [template = constants.%Reference] {
// CHECK:STDOUT: %X.ref.loc21: type = name_ref X, %X.decl [template = constants.%X]
-// CHECK:STDOUT: %.loc21: type = ptr_type %X [template = constants.%.4]
-// CHECK:STDOUT: %p.loc21_14.1: %.4 = param p, runtime_param0
-// CHECK:STDOUT: @Reference.%p: %.4 = bind_name p, %p.loc21_14.1
+// CHECK:STDOUT: %.loc21: type = ptr_type %X [template = constants.%.5]
+// CHECK:STDOUT: %p.loc21_14.1: %.5 = param p, runtime_param0
+// CHECK:STDOUT: @Reference.%p: %.5 = bind_name p, %p.loc21_14.1
// CHECK:STDOUT: }
// CHECK:STDOUT: %Make.decl: %Make.type = fn_decl @Make [template = constants.%Make] {
// CHECK:STDOUT: %X.ref.loc25: type = name_ref X, %X.decl [template = constants.%X]
@@ -89,6 +90,8 @@ fn Initializing() {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @X {
+// CHECK:STDOUT: %.loc15: = complete_type_witness %.1 [template = constants.%.2]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%X
// CHECK:STDOUT: }
@@ -102,15 +105,15 @@ fn Initializing() {
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
-// CHECK:STDOUT: fn @Reference(%p: %.4) {
+// CHECK:STDOUT: fn @Reference(%p: %.5) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %X.ref.loc22_10: type = name_ref X, file.%X.decl [template = constants.%X]
-// CHECK:STDOUT: %.loc22_11: type = ptr_type %X [template = constants.%.4]
-// CHECK:STDOUT: %p.ref: %.4 = name_ref p, %p
+// CHECK:STDOUT: %.loc22_11: type = ptr_type %X [template = constants.%.5]
+// CHECK:STDOUT: %p.ref: %.5 = name_ref p, %p
// CHECK:STDOUT: %.loc22_17: ref %X = deref %p.ref
// CHECK:STDOUT: %X.ref.loc22_23: type = name_ref X, file.%X.decl [template = constants.%X]
-// CHECK:STDOUT: %.loc22_15: %.4 = addr_of %.loc22_17
-// CHECK:STDOUT: %q: %.4 = bind_name q, %.loc22_15
+// CHECK:STDOUT: %.loc22_15: %.5 = addr_of %.loc22_17
+// CHECK:STDOUT: %q: %.5 = bind_name q, %.loc22_15
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
diff --git a/toolchain/check/testdata/as/no_prelude/tuple.carbon b/toolchain/check/testdata/as/no_prelude/tuple.carbon
index 438a34b6f4e15..322e9391168ca 100644
--- a/toolchain/check/testdata/as/no_prelude/tuple.carbon
+++ b/toolchain/check/testdata/as/no_prelude/tuple.carbon
@@ -29,16 +29,17 @@ fn Var() {
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %X: type = class_type @X [template]
// CHECK:STDOUT: %.1: type = struct_type {} [template]
+// CHECK:STDOUT: %.2: = complete_type_witness %.1 [template]
// CHECK:STDOUT: %Make.type: type = fn_type @Make [template]
-// CHECK:STDOUT: %.2: type = tuple_type () [template]
+// CHECK:STDOUT: %.3: type = tuple_type () [template]
// CHECK:STDOUT: %Make: %Make.type = struct_value () [template]
// CHECK:STDOUT: %Let.type: type = fn_type @Let [template]
// CHECK:STDOUT: %Let: %Let.type = struct_value () [template]
-// CHECK:STDOUT: %.3: type = tuple_type (type, type) [template]
-// CHECK:STDOUT: %.4: type = tuple_type (%X, %X) [template]
-// CHECK:STDOUT: %.5: type = ptr_type %.1 [template]
-// CHECK:STDOUT: %.6: type = tuple_type (%.5, %.5) [template]
-// CHECK:STDOUT: %.7: type = ptr_type %.6 [template]
+// CHECK:STDOUT: %.4: type = tuple_type (type, type) [template]
+// CHECK:STDOUT: %.5: type = tuple_type (%X, %X) [template]
+// CHECK:STDOUT: %.6: type = ptr_type %.1 [template]
+// CHECK:STDOUT: %.7: type = tuple_type (%.6, %.6) [template]
+// CHECK:STDOUT: %.8: type = ptr_type %.7 [template]
// CHECK:STDOUT: %Var.type: type = fn_type @Var [template]
// CHECK:STDOUT: %Var: %Var.type = struct_value () [template]
// CHECK:STDOUT: }
@@ -60,6 +61,8 @@ fn Var() {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @X {
+// CHECK:STDOUT: %.loc13: = complete_type_witness %.1 [template = constants.%.2]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%X
// CHECK:STDOUT: }
@@ -70,26 +73,26 @@ fn Var() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %X.ref.loc19_11: type = name_ref X, file.%X.decl [template = constants.%X]
// CHECK:STDOUT: %X.ref.loc19_14: type = name_ref X, file.%X.decl [template = constants.%X]
-// CHECK:STDOUT: %.loc19_15.1: %.3 = tuple_literal (%X.ref.loc19_11, %X.ref.loc19_14)
-// CHECK:STDOUT: %.loc19_15.2: type = converted %.loc19_15.1, constants.%.4 [template = constants.%.4]
+// CHECK:STDOUT: %.loc19_15.1: %.4 = tuple_literal (%X.ref.loc19_11, %X.ref.loc19_14)
+// CHECK:STDOUT: %.loc19_15.2: type = converted %.loc19_15.1, constants.%.5 [template = constants.%.5]
// CHECK:STDOUT: %Make.ref.loc19_20: %Make.type = name_ref Make, file.%Make.decl [template = constants.%Make]
// CHECK:STDOUT: %.loc19_24.1: ref %X = temporary_storage
// CHECK:STDOUT: %Make.call.loc19_24: init %X = call %Make.ref.loc19_20() to %.loc19_24.1
// CHECK:STDOUT: %Make.ref.loc19_28: %Make.type = name_ref Make, file.%Make.decl [template = constants.%Make]
// CHECK:STDOUT: %.loc19_32.1: ref %X = temporary_storage
// CHECK:STDOUT: %Make.call.loc19_32: init %X = call %Make.ref.loc19_28() to %.loc19_32.1
-// CHECK:STDOUT: %.loc19_34: %.4 = tuple_literal (%Make.call.loc19_24, %Make.call.loc19_32)
+// CHECK:STDOUT: %.loc19_34: %.5 = tuple_literal (%Make.call.loc19_24, %Make.call.loc19_32)
// CHECK:STDOUT: %X.ref.loc19_40: type = name_ref X, file.%X.decl [template = constants.%X]
// CHECK:STDOUT: %X.ref.loc19_43: type = name_ref X, file.%X.decl [template = constants.%X]
-// CHECK:STDOUT: %.loc19_44.1: %.3 = tuple_literal (%X.ref.loc19_40, %X.ref.loc19_43)
-// CHECK:STDOUT: %.loc19_44.2: type = converted %.loc19_44.1, constants.%.4 [template = constants.%.4]
+// CHECK:STDOUT: %.loc19_44.1: %.4 = tuple_literal (%X.ref.loc19_40, %X.ref.loc19_43)
+// CHECK:STDOUT: %.loc19_44.2: type = converted %.loc19_44.1, constants.%.5 [template = constants.%.5]
// CHECK:STDOUT: %.loc19_24.2: ref %X = temporary %.loc19_24.1, %Make.call.loc19_24
// CHECK:STDOUT: %.loc19_24.3: %X = bind_value %.loc19_24.2
// CHECK:STDOUT: %.loc19_32.2: ref %X = temporary %.loc19_32.1, %Make.call.loc19_32
// CHECK:STDOUT: %.loc19_32.3: %X = bind_value %.loc19_32.2
-// CHECK:STDOUT: %tuple: %.4 = tuple_value (%.loc19_24.3, %.loc19_32.3)
-// CHECK:STDOUT: %.loc19_45: %.4 = converted %.loc19_34, %tuple
-// CHECK:STDOUT: %a: %.4 = bind_name a, %.loc19_45
+// CHECK:STDOUT: %tuple: %.5 = tuple_value (%.loc19_24.3, %.loc19_32.3)
+// CHECK:STDOUT: %.loc19_45: %.5 = converted %.loc19_34, %tuple
+// CHECK:STDOUT: %a: %.5 = bind_name a, %.loc19_45
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -97,23 +100,23 @@ fn Var() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %X.ref.loc24_11: type = name_ref X, file.%X.decl [template = constants.%X]
// CHECK:STDOUT: %X.ref.loc24_14: type = name_ref X, file.%X.decl [template = constants.%X]
-// CHECK:STDOUT: %.loc24_15.1: %.3 = tuple_literal (%X.ref.loc24_11, %X.ref.loc24_14)
-// CHECK:STDOUT: %.loc24_15.2: type = converted %.loc24_15.1, constants.%.4 [template = constants.%.4]
-// CHECK:STDOUT: %b.var: ref %.4 = var b
-// CHECK:STDOUT: %b: ref %.4 = bind_name b, %b.var
+// CHECK:STDOUT: %.loc24_15.1: %.4 = tuple_literal (%X.ref.loc24_11, %X.ref.loc24_14)
+// CHECK:STDOUT: %.loc24_15.2: type = converted %.loc24_15.1, constants.%.5 [template = constants.%.5]
+// CHECK:STDOUT: %b.var: ref %.5 = var b
+// CHECK:STDOUT: %b: ref %.5 = bind_name b, %b.var
// CHECK:STDOUT: %Make.ref.loc24_20: %Make.type = name_ref Make, file.%Make.decl [template = constants.%Make]
// CHECK:STDOUT: %.loc24_34.1: ref %X = tuple_access %b.var, element0
// CHECK:STDOUT: %Make.call.loc24_24: init %X = call %Make.ref.loc24_20() to %.loc24_34.1
// CHECK:STDOUT: %Make.ref.loc24_28: %Make.type = name_ref Make, file.%Make.decl [template = constants.%Make]
// CHECK:STDOUT: %.loc24_34.2: ref %X = tuple_access %b.var, element1
// CHECK:STDOUT: %Make.call.loc24_32: init %X = call %Make.ref.loc24_28() to %.loc24_34.2
-// CHECK:STDOUT: %.loc24_34.3: %.4 = tuple_literal (%Make.call.loc24_24, %Make.call.loc24_32)
+// CHECK:STDOUT: %.loc24_34.3: %.5 = tuple_literal (%Make.call.loc24_24, %Make.call.loc24_32)
// CHECK:STDOUT: %X.ref.loc24_40: type = name_ref X, file.%X.decl [template = constants.%X]
// CHECK:STDOUT: %X.ref.loc24_43: type = name_ref X, file.%X.decl [template = constants.%X]
-// CHECK:STDOUT: %.loc24_44.1: %.3 = tuple_literal (%X.ref.loc24_40, %X.ref.loc24_43)
-// CHECK:STDOUT: %.loc24_44.2: type = converted %.loc24_44.1, constants.%.4 [template = constants.%.4]
-// CHECK:STDOUT: %.loc24_34.4: init %.4 = tuple_init (%Make.call.loc24_24, %Make.call.loc24_32) to %b.var
-// CHECK:STDOUT: %.loc24_45: init %.4 = converted %.loc24_34.3, %.loc24_34.4
+// CHECK:STDOUT: %.loc24_44.1: %.4 = tuple_literal (%X.ref.loc24_40, %X.ref.loc24_43)
+// CHECK:STDOUT: %.loc24_44.2: type = converted %.loc24_44.1, constants.%.5 [template = constants.%.5]
+// CHECK:STDOUT: %.loc24_34.4: init %.5 = tuple_init (%Make.call.loc24_24, %Make.call.loc24_32) to %b.var
+// CHECK:STDOUT: %.loc24_45: init %.5 = converted %.loc24_34.3, %.loc24_34.4
// CHECK:STDOUT: assign %b.var, %.loc24_45
// CHECK:STDOUT: return
// CHECK:STDOUT: }
diff --git a/toolchain/check/testdata/as/overloaded.carbon b/toolchain/check/testdata/as/overloaded.carbon
index 8b45fd24c8734..07cea00dc941c 100644
--- a/toolchain/check/testdata/as/overloaded.carbon
+++ b/toolchain/check/testdata/as/overloaded.carbon
@@ -31,36 +31,37 @@ let n: i32 = ((4 as i32) as X) as i32;
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
// CHECK:STDOUT: %.2: type = unbound_element_type %X, i32 [template]
// CHECK:STDOUT: %.3: type = struct_type {.n: i32} [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
// CHECK:STDOUT: %As.type: type = generic_interface_type @As [template]
// CHECK:STDOUT: %As: %As.type = struct_value () [template]
// CHECK:STDOUT: %Dest: type = bind_symbolic_name Dest 0 [symbolic]
-// CHECK:STDOUT: %.4: type = interface_type @As, @As(%Dest) [symbolic]
-// CHECK:STDOUT: %Self.1: @As.%.1 (%.4) = bind_symbolic_name Self 1 [symbolic]
-// CHECK:STDOUT: %Self.2: %.4 = bind_symbolic_name Self 1 [symbolic]
+// CHECK:STDOUT: %.5: type = interface_type @As, @As(%Dest) [symbolic]
+// CHECK:STDOUT: %Self.1: @As.%.1 (%.5) = bind_symbolic_name Self 1 [symbolic]
+// CHECK:STDOUT: %Self.2: %.5 = bind_symbolic_name Self 1 [symbolic]
// CHECK:STDOUT: %Convert.type.1: type = fn_type @Convert.1, @As(%Dest) [symbolic]
// CHECK:STDOUT: %Convert.1: %Convert.type.1 = struct_value () [symbolic]
-// CHECK:STDOUT: %.5: type = assoc_entity_type %.4, %Convert.type.1 [symbolic]
-// CHECK:STDOUT: %.6: %.5 = assoc_entity element0, imports.%import_ref.6 [symbolic]
-// CHECK:STDOUT: %.7: type = interface_type @As, @As(%X) [template]
+// CHECK:STDOUT: %.6: type = assoc_entity_type %.5, %Convert.type.1 [symbolic]
+// CHECK:STDOUT: %.7: %.6 = assoc_entity element0, imports.%import_ref.6 [symbolic]
+// CHECK:STDOUT: %.8: type = interface_type @As, @As(%X) [template]
// CHECK:STDOUT: %Convert.type.2: type = fn_type @Convert.2 [template]
// CHECK:STDOUT: %Convert.2: %Convert.type.2 = struct_value () [template]
// CHECK:STDOUT: %Convert.type.3: type = fn_type @Convert.1, @As(%X) [template]
// CHECK:STDOUT: %Convert.3: %Convert.type.3 = struct_value () [template]
-// CHECK:STDOUT: %.8: type = assoc_entity_type %.7, %Convert.type.3 [template]
-// CHECK:STDOUT: %.9: %.8 = assoc_entity element0, imports.%import_ref.6 [template]
-// CHECK:STDOUT: %.10: = interface_witness (%Convert.2) [template]
-// CHECK:STDOUT: %.11: type = ptr_type %.3 [template]
-// CHECK:STDOUT: %.12: type = interface_type @As, @As(i32) [template]
+// CHECK:STDOUT: %.9: type = assoc_entity_type %.8, %Convert.type.3 [template]
+// CHECK:STDOUT: %.10: %.9 = assoc_entity element0, imports.%import_ref.6 [template]
+// CHECK:STDOUT: %.11: = interface_witness (%Convert.2) [template]
+// CHECK:STDOUT: %.12: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.13: type = interface_type @As, @As(i32) [template]
// CHECK:STDOUT: %Convert.type.4: type = fn_type @Convert.3 [template]
// CHECK:STDOUT: %Convert.4: %Convert.type.4 = struct_value () [template]
// CHECK:STDOUT: %Convert.type.5: type = fn_type @Convert.1, @As(i32) [template]
// CHECK:STDOUT: %Convert.5: %Convert.type.5 = struct_value () [template]
-// CHECK:STDOUT: %.13: type = assoc_entity_type %.12, %Convert.type.5 [template]
-// CHECK:STDOUT: %.14: %.13 = assoc_entity element0, imports.%import_ref.6 [template]
-// CHECK:STDOUT: %.15: = interface_witness (%Convert.4) [template]
-// CHECK:STDOUT: %.16: i32 = int_literal 4 [template]
-// CHECK:STDOUT: %.17: %.5 = assoc_entity element0, imports.%import_ref.7 [symbolic]
-// CHECK:STDOUT: %.18: = bound_method %.16, %Convert.2 [template]
+// CHECK:STDOUT: %.14: type = assoc_entity_type %.13, %Convert.type.5 [template]
+// CHECK:STDOUT: %.15: %.14 = assoc_entity element0, imports.%import_ref.6 [template]
+// CHECK:STDOUT: %.16: = interface_witness (%Convert.4) [template]
+// CHECK:STDOUT: %.17: i32 = int_literal 4 [template]
+// CHECK:STDOUT: %.18: %.6 = assoc_entity element0, imports.%import_ref.7 [symbolic]
+// CHECK:STDOUT: %.19: = bound_method %.17, %Convert.2 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -79,7 +80,7 @@ let n: i32 = ((4 as i32) as X) as i32;
// CHECK:STDOUT: %import_ref.1: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
// CHECK:STDOUT: %import_ref.2: %As.type = import_ref Core//prelude/operators/as, inst+4, loaded [template = constants.%As]
// CHECK:STDOUT: %import_ref.3 = import_ref Core//prelude/operators/as, inst+10, unloaded
-// CHECK:STDOUT: %import_ref.4: @As.%.2 (%.5) = import_ref Core//prelude/operators/as, inst+27, loaded [symbolic = @As.%.3 (constants.%.17)]
+// CHECK:STDOUT: %import_ref.4: @As.%.2 (%.6) = import_ref Core//prelude/operators/as, inst+27, loaded [symbolic = @As.%.3 (constants.%.18)]
// CHECK:STDOUT: %import_ref.5: @As.%Convert.type (%Convert.type.1) = import_ref Core//prelude/operators/as, inst+20, loaded [symbolic = @As.%Convert (constants.%Convert.1)]
// CHECK:STDOUT: %import_ref.6 = import_ref Core//prelude/operators/as, inst+20, unloaded
// CHECK:STDOUT: %import_ref.7 = import_ref Core//prelude/operators/as, inst+20, unloaded
@@ -100,7 +101,7 @@ let n: i32 = ((4 as i32) as X) as i32;
// CHECK:STDOUT: %Core.ref.loc15: = name_ref Core, imports.%Core [template = imports.%Core]
// CHECK:STDOUT: %As.ref.loc15: %As.type = name_ref As, imports.%import_ref.2 [template = constants.%As]
// CHECK:STDOUT: %X.ref.loc15: type = name_ref X, %X.decl [template = constants.%X]
-// CHECK:STDOUT: %.loc15_20: type = interface_type @As, @As(constants.%X) [template = constants.%.7]
+// CHECK:STDOUT: %.loc15_20: type = interface_type @As, @As(constants.%X) [template = constants.%.8]
// CHECK:STDOUT: }
// CHECK:STDOUT: impl_decl @impl.2 {
// CHECK:STDOUT: %X.ref.loc19: type = name_ref X, %X.decl [template = constants.%X]
@@ -109,7 +110,7 @@ let n: i32 = ((4 as i32) as X) as i32;
// CHECK:STDOUT: %int.make_type_32.loc19: init type = call constants.%Int32() [template = i32]
// CHECK:STDOUT: %.loc19_18.1: type = value_of_initializer %int.make_type_32.loc19 [template = i32]
// CHECK:STDOUT: %.loc19_18.2: type = converted %int.make_type_32.loc19, %.loc19_18.1 [template = i32]
-// CHECK:STDOUT: %.loc19_18.3: type = interface_type @As, @As(i32) [template = constants.%.12]
+// CHECK:STDOUT: %.loc19_18.3: type = interface_type @As, @As(i32) [template = constants.%.13]
// CHECK:STDOUT: }
// CHECK:STDOUT: %int.make_type_32.loc23: init type = call constants.%Int32() [template = i32]
// CHECK:STDOUT: %.loc23_8.1: type = value_of_initializer %int.make_type_32.loc23 [template = i32]
@@ -120,12 +121,12 @@ let n: i32 = ((4 as i32) as X) as i32;
// CHECK:STDOUT: %Dest: type = bind_symbolic_name Dest 0 [symbolic = %Dest (constants.%Dest)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
-// CHECK:STDOUT: %.1: type = interface_type @As, @As(%Dest) [symbolic = %.1 (constants.%.4)]
-// CHECK:STDOUT: %Self: %.4 = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self.2)]
+// CHECK:STDOUT: %.1: type = interface_type @As, @As(%Dest) [symbolic = %.1 (constants.%.5)]
+// CHECK:STDOUT: %Self: %.5 = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self.2)]
// CHECK:STDOUT: %Convert.type: type = fn_type @Convert.1, @As(%Dest) [symbolic = %Convert.type (constants.%Convert.type.1)]
// CHECK:STDOUT: %Convert: @As.%Convert.type (%Convert.type.1) = struct_value () [symbolic = %Convert (constants.%Convert.1)]
-// CHECK:STDOUT: %.2: type = assoc_entity_type @As.%.1 (%.4), @As.%Convert.type (%Convert.type.1) [symbolic = %.2 (constants.%.5)]
-// CHECK:STDOUT: %.3: @As.%.2 (%.5) = assoc_entity element0, imports.%import_ref.6 [symbolic = %.3 (constants.%.6)]
+// CHECK:STDOUT: %.2: type = assoc_entity_type @As.%.1 (%.5), @As.%Convert.type (%Convert.type.1) [symbolic = %.2 (constants.%.6)]
+// CHECK:STDOUT: %.3: @As.%.2 (%.6) = assoc_entity element0, imports.%import_ref.6 [symbolic = %.3 (constants.%.7)]
// CHECK:STDOUT:
// CHECK:STDOUT: interface {
// CHECK:STDOUT: !members:
@@ -135,7 +136,7 @@ let n: i32 = ((4 as i32) as X) as i32;
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
-// CHECK:STDOUT: impl @impl.1: i32 as %.7 {
+// CHECK:STDOUT: impl @impl.1: i32 as %.8 {
// CHECK:STDOUT: %Convert.decl: %Convert.type.2 = fn_decl @Convert.2 [template = constants.%Convert.2] {
// CHECK:STDOUT: %int.make_type_32: init type = call constants.%Int32() [template = i32]
// CHECK:STDOUT: %.loc16_20.1: type = value_of_initializer %int.make_type_32 [template = i32]
@@ -145,14 +146,14 @@ let n: i32 = ((4 as i32) as X) as i32;
// CHECK:STDOUT: %X.ref: type = name_ref X, file.%X.decl [template = constants.%X]
// CHECK:STDOUT: %return.var: ref %X = var
// CHECK:STDOUT: }
-// CHECK:STDOUT: %.loc15: = interface_witness (%Convert.decl) [template = constants.%.10]
+// CHECK:STDOUT: %.loc15: = interface_witness (%Convert.decl) [template = constants.%.11]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Convert = %Convert.decl
// CHECK:STDOUT: witness = %.loc15
// CHECK:STDOUT: }
// CHECK:STDOUT:
-// CHECK:STDOUT: impl @impl.2: %X as %.12 {
+// CHECK:STDOUT: impl @impl.2: %X as %.13 {
// CHECK:STDOUT: %Convert.decl: %Convert.type.4 = fn_decl @Convert.3 [template = constants.%Convert.4] {
// CHECK:STDOUT: %X.ref: type = name_ref X, file.%X.decl [template = constants.%X]
// CHECK:STDOUT: %self.loc20_14.1: %X = param self, runtime_param0
@@ -162,7 +163,7 @@ let n: i32 = ((4 as i32) as X) as i32;
// CHECK:STDOUT: %.loc20_28.2: type = converted %int.make_type_32, %.loc20_28.1 [template = i32]
// CHECK:STDOUT: %return.var: ref i32 = var
// CHECK:STDOUT: }
-// CHECK:STDOUT: %.loc19: = interface_witness (%Convert.decl) [template = constants.%.15]
+// CHECK:STDOUT: %.loc19: = interface_witness (%Convert.decl) [template = constants.%.16]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Convert = %Convert.decl
@@ -174,6 +175,7 @@ let n: i32 = ((4 as i32) as X) as i32;
// CHECK:STDOUT: %.loc12_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
// CHECK:STDOUT: %.loc12_10.2: type = converted %int.make_type_32, %.loc12_10.1 [template = i32]
// CHECK:STDOUT: %.loc12_8: %.2 = field_decl n, element0 [template]
+// CHECK:STDOUT: %.loc13: = complete_type_witness %.3 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%X
@@ -182,10 +184,10 @@ let n: i32 = ((4 as i32) as X) as i32;
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
// CHECK:STDOUT:
-// CHECK:STDOUT: generic fn @Convert.1(constants.%Dest: type, constants.%Self.1: @As.%.1 (%.4)) {
+// CHECK:STDOUT: generic fn @Convert.1(constants.%Dest: type, constants.%Self.1: @As.%.1 (%.5)) {
// CHECK:STDOUT: %Dest: type = bind_symbolic_name Dest 0 [symbolic = %Dest (constants.%Dest)]
-// CHECK:STDOUT: %.1: type = interface_type @As, @As(%Dest) [symbolic = %.1 (constants.%.4)]
-// CHECK:STDOUT: %Self: %.4 = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self.2)]
+// CHECK:STDOUT: %.1: type = interface_type @As, @As(%Dest) [symbolic = %.1 (constants.%.5)]
+// CHECK:STDOUT: %Self: %.5 = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self.2)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn[%self: @Convert.1.%Self (%Self.2)]() -> @Convert.1.%Dest (%Dest);
// CHECK:STDOUT: }
@@ -212,25 +214,25 @@ let n: i32 = ((4 as i32) as X) as i32;
// CHECK:STDOUT:
// CHECK:STDOUT: fn @__global_init() {
// CHECK:STDOUT: !entry:
-// CHECK:STDOUT: %.loc23_16: i32 = int_literal 4 [template = constants.%.16]
+// CHECK:STDOUT: %.loc23_16: i32 = int_literal 4 [template = constants.%.17]
// CHECK:STDOUT: %int.make_type_32.loc23_21: init type = call constants.%Int32() [template = i32]
// CHECK:STDOUT: %.loc23_21.1: type = value_of_initializer %int.make_type_32.loc23_21 [template = i32]
// CHECK:STDOUT: %.loc23_21.2: type = converted %int.make_type_32.loc23_21, %.loc23_21.1 [template = i32]
// CHECK:STDOUT: %X.ref: type = name_ref X, file.%X.decl [template = constants.%X]
-// CHECK:STDOUT: %.loc23_26.1: type = interface_type @As, @As(constants.%X) [template = constants.%.7]
-// CHECK:STDOUT: %.loc23_26.2: %.8 = specific_constant imports.%import_ref.4, @As(constants.%X) [template = constants.%.9]
-// CHECK:STDOUT: %Convert.ref.loc23_26: %.8 = name_ref Convert, %.loc23_26.2 [template = constants.%.9]
+// CHECK:STDOUT: %.loc23_26.1: type = interface_type @As, @As(constants.%X) [template = constants.%.8]
+// CHECK:STDOUT: %.loc23_26.2: %.9 = specific_constant imports.%import_ref.4, @As(constants.%X) [template = constants.%.10]
+// CHECK:STDOUT: %Convert.ref.loc23_26: %.9 = name_ref Convert, %.loc23_26.2 [template = constants.%.10]
// CHECK:STDOUT: %.loc23_26.3: %Convert.type.3 = interface_witness_access @impl.1.%.loc15, element0 [template = constants.%Convert.2]
-// CHECK:STDOUT: %.loc23_26.4: = bound_method %.loc23_16, %.loc23_26.3 [template = constants.%.18]
+// CHECK:STDOUT: %.loc23_26.4: = bound_method %.loc23_16, %.loc23_26.3 [template = constants.%.19]
// CHECK:STDOUT: %.loc23_26.5: ref %X = temporary_storage
// CHECK:STDOUT: %Convert.call.loc23_26: init %X = call %.loc23_26.4(%.loc23_16) to %.loc23_26.5
// CHECK:STDOUT: %.loc23_26.6: init %X = converted %.loc23_16, %Convert.call.loc23_26
// CHECK:STDOUT: %int.make_type_32.loc23_35: init type = call constants.%Int32() [template = i32]
// CHECK:STDOUT: %.loc23_35.1: type = value_of_initializer %int.make_type_32.loc23_35 [template = i32]
// CHECK:STDOUT: %.loc23_35.2: type = converted %int.make_type_32.loc23_35, %.loc23_35.1 [template = i32]
-// CHECK:STDOUT: %.loc23_32.1: type = interface_type @As, @As(i32) [template = constants.%.12]
-// CHECK:STDOUT: %.loc23_32.2: %.13 = specific_constant imports.%import_ref.4, @As(i32) [template = constants.%.14]
-// CHECK:STDOUT: %Convert.ref.loc23_32: %.13 = name_ref Convert, %.loc23_32.2 [template = constants.%.14]
+// CHECK:STDOUT: %.loc23_32.1: type = interface_type @As, @As(i32) [template = constants.%.13]
+// CHECK:STDOUT: %.loc23_32.2: %.14 = specific_constant imports.%import_ref.4, @As(i32) [template = constants.%.15]
+// CHECK:STDOUT: %Convert.ref.loc23_32: %.14 = name_ref Convert, %.loc23_32.2 [template = constants.%.15]
// CHECK:STDOUT: %.loc23_26.7: ref %X = temporary %.loc23_26.5, %.loc23_26.6
// CHECK:STDOUT: %.loc23_32.3: %Convert.type.5 = interface_witness_access @impl.2.%.loc19, element0 [template = constants.%Convert.4]
// CHECK:STDOUT: %.loc23_32.4: = bound_method %.loc23_26.7, %.loc23_32.3
@@ -257,7 +259,7 @@ let n: i32 = ((4 as i32) as X) as i32;
// CHECK:STDOUT:
// CHECK:STDOUT: specific @Convert.1(constants.%Dest, constants.%Self.1) {
// CHECK:STDOUT: %Dest => constants.%Dest
-// CHECK:STDOUT: %.1 => constants.%.4
+// CHECK:STDOUT: %.1 => constants.%.5
// CHECK:STDOUT: %Self => constants.%Self.1
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -265,17 +267,17 @@ let n: i32 = ((4 as i32) as X) as i32;
// CHECK:STDOUT: %Dest => constants.%X
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
-// CHECK:STDOUT: %.1 => constants.%.7
+// CHECK:STDOUT: %.1 => constants.%.8
// CHECK:STDOUT: %Self => constants.%Self.2
// CHECK:STDOUT: %Convert.type => constants.%Convert.type.3
// CHECK:STDOUT: %Convert => constants.%Convert.3
-// CHECK:STDOUT: %.2 => constants.%.8
-// CHECK:STDOUT: %.3 => constants.%.9
+// CHECK:STDOUT: %.2 => constants.%.9
+// CHECK:STDOUT: %.3 => constants.%.10
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @Convert.1(constants.%X, i32) {
// CHECK:STDOUT: %Dest => constants.%X
-// CHECK:STDOUT: %.1 => constants.%.7
+// CHECK:STDOUT: %.1 => constants.%.8
// CHECK:STDOUT: %Self => i32
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -283,17 +285,17 @@ let n: i32 = ((4 as i32) as X) as i32;
// CHECK:STDOUT: %Dest => i32
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
-// CHECK:STDOUT: %.1 => constants.%.12
+// CHECK:STDOUT: %.1 => constants.%.13
// CHECK:STDOUT: %Self => constants.%Self.2
// CHECK:STDOUT: %Convert.type => constants.%Convert.type.5
// CHECK:STDOUT: %Convert => constants.%Convert.5
-// CHECK:STDOUT: %.2 => constants.%.13
-// CHECK:STDOUT: %.3 => constants.%.14
+// CHECK:STDOUT: %.2 => constants.%.14
+// CHECK:STDOUT: %.3 => constants.%.15
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @Convert.1(i32, constants.%X) {
// CHECK:STDOUT: %Dest => i32
-// CHECK:STDOUT: %.1 => constants.%.12
+// CHECK:STDOUT: %.1 => constants.%.13
// CHECK:STDOUT: %Self => constants.%X
// CHECK:STDOUT: }
// CHECK:STDOUT:
diff --git a/toolchain/check/testdata/builtins/float/eq.carbon b/toolchain/check/testdata/builtins/float/eq.carbon
index 561d74ef1d2ef..be57cdec19872 100644
--- a/toolchain/check/testdata/builtins/float/eq.carbon
+++ b/toolchain/check/testdata/builtins/float/eq.carbon
@@ -46,14 +46,15 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.eq";
// CHECK:STDOUT: %Eq: %Eq.type = struct_value () [template]
// CHECK:STDOUT: %True: type = class_type @True [template]
// CHECK:STDOUT: %.3: type = struct_type {} [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
// CHECK:STDOUT: %False: type = class_type @False [template]
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
-// CHECK:STDOUT: %.5: f64 = float_literal 1 [template]
-// CHECK:STDOUT: %.6: bool = bool_literal true [template]
-// CHECK:STDOUT: %.7: f64 = float_literal 2 [template]
-// CHECK:STDOUT: %.8: bool = bool_literal false [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.6: f64 = float_literal 1 [template]
+// CHECK:STDOUT: %.7: bool = bool_literal true [template]
+// CHECK:STDOUT: %.8: f64 = float_literal 2 [template]
+// CHECK:STDOUT: %.9: bool = bool_literal false [template]
// CHECK:STDOUT: %RuntimeCall.type: type = fn_type @RuntimeCall [template]
// CHECK:STDOUT: %RuntimeCall: %RuntimeCall.type = struct_value () [template]
// CHECK:STDOUT: }
@@ -134,11 +135,15 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.eq";
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @True {
+// CHECK:STDOUT: %.loc4: = complete_type_witness %.3 [template = constants.%.4]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%True
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @False {
+// CHECK:STDOUT: %.loc5: = complete_type_witness %.3 [template = constants.%.4]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%False
// CHECK:STDOUT: }
@@ -153,11 +158,11 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.eq";
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %true_.ref: %True = name_ref true_, %true_
// CHECK:STDOUT: %Eq.ref.loc8: %Eq.type = name_ref Eq, file.%Eq.decl [template = constants.%Eq]
-// CHECK:STDOUT: %.loc8_19: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %.loc8_24: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %float.eq.loc8: init bool = call %Eq.ref.loc8(%.loc8_19, %.loc8_24) [template = constants.%.6]
-// CHECK:STDOUT: %.loc8_13.1: bool = value_of_initializer %float.eq.loc8 [template = constants.%.6]
-// CHECK:STDOUT: %.loc8_13.2: bool = converted %float.eq.loc8, %.loc8_13.1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc8_19: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc8_24: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %float.eq.loc8: init bool = call %Eq.ref.loc8(%.loc8_19, %.loc8_24) [template = constants.%.7]
+// CHECK:STDOUT: %.loc8_13.1: bool = value_of_initializer %float.eq.loc8 [template = constants.%.7]
+// CHECK:STDOUT: %.loc8_13.2: bool = converted %float.eq.loc8, %.loc8_13.1 [template = constants.%.7]
// CHECK:STDOUT: if %.loc8_13.2 br !if.expr.then.loc8 else br !if.expr.else.loc8
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc8:
@@ -172,11 +177,11 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.eq";
// CHECK:STDOUT: %.loc8_13.3: type = block_arg !if.expr.result.loc8 [template = constants.%True]
// CHECK:STDOUT: %false_.ref: %False = name_ref false_, %false_
// CHECK:STDOUT: %Eq.ref.loc9: %Eq.type = name_ref Eq, file.%Eq.decl [template = constants.%Eq]
-// CHECK:STDOUT: %.loc9_20: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %.loc9_25: f64 = float_literal 2 [template = constants.%.7]
-// CHECK:STDOUT: %float.eq.loc9: init bool = call %Eq.ref.loc9(%.loc9_20, %.loc9_25) [template = constants.%.8]
-// CHECK:STDOUT: %.loc9_14.1: bool = value_of_initializer %float.eq.loc9 [template = constants.%.8]
-// CHECK:STDOUT: %.loc9_14.2: bool = converted %float.eq.loc9, %.loc9_14.1 [template = constants.%.8]
+// CHECK:STDOUT: %.loc9_20: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc9_25: f64 = float_literal 2 [template = constants.%.8]
+// CHECK:STDOUT: %float.eq.loc9: init bool = call %Eq.ref.loc9(%.loc9_20, %.loc9_25) [template = constants.%.9]
+// CHECK:STDOUT: %.loc9_14.1: bool = value_of_initializer %float.eq.loc9 [template = constants.%.9]
+// CHECK:STDOUT: %.loc9_14.2: bool = converted %float.eq.loc9, %.loc9_14.1 [template = constants.%.9]
// CHECK:STDOUT: if %.loc9_14.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc9:
diff --git a/toolchain/check/testdata/builtins/float/greater.carbon b/toolchain/check/testdata/builtins/float/greater.carbon
index 7f18ba112701c..712ad6639e789 100644
--- a/toolchain/check/testdata/builtins/float/greater.carbon
+++ b/toolchain/check/testdata/builtins/float/greater.carbon
@@ -43,16 +43,17 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: %Negate: %Negate.type = struct_value () [template]
// CHECK:STDOUT: %True: type = class_type @True [template]
// CHECK:STDOUT: %.3: type = struct_type {} [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
// CHECK:STDOUT: %False: type = class_type @False [template]
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
-// CHECK:STDOUT: %.5: f64 = float_literal 1 [template]
-// CHECK:STDOUT: %.6: f64 = float_literal 2 [template]
-// CHECK:STDOUT: %.7: bool = bool_literal false [template]
-// CHECK:STDOUT: %.8: f64 = float_literal 0 [template]
-// CHECK:STDOUT: %.9: bool = bool_literal true [template]
-// CHECK:STDOUT: %.10: f64 = float_literal -1 [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.6: f64 = float_literal 1 [template]
+// CHECK:STDOUT: %.7: f64 = float_literal 2 [template]
+// CHECK:STDOUT: %.8: bool = bool_literal false [template]
+// CHECK:STDOUT: %.9: f64 = float_literal 0 [template]
+// CHECK:STDOUT: %.10: bool = bool_literal true [template]
+// CHECK:STDOUT: %.11: f64 = float_literal -1 [template]
// CHECK:STDOUT: %RuntimeCall.type: type = fn_type @RuntimeCall [template]
// CHECK:STDOUT: %RuntimeCall: %RuntimeCall.type = struct_value () [template]
// CHECK:STDOUT: }
@@ -147,11 +148,15 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @True {
+// CHECK:STDOUT: %.loc5: = complete_type_witness %.3 [template = constants.%.4]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%True
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @False {
+// CHECK:STDOUT: %.loc6: = complete_type_witness %.3 [template = constants.%.4]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%False
// CHECK:STDOUT: }
@@ -168,11 +173,11 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %false_.ref.loc9: %False = name_ref false_, %false_
// CHECK:STDOUT: %Greater.ref.loc9: %Greater.type = name_ref Greater, file.%Greater.decl [template = constants.%Greater]
-// CHECK:STDOUT: %.loc9_25: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %.loc9_30: f64 = float_literal 2 [template = constants.%.6]
-// CHECK:STDOUT: %float.greater.loc9: init bool = call %Greater.ref.loc9(%.loc9_25, %.loc9_30) [template = constants.%.7]
-// CHECK:STDOUT: %.loc9_14.1: bool = value_of_initializer %float.greater.loc9 [template = constants.%.7]
-// CHECK:STDOUT: %.loc9_14.2: bool = converted %float.greater.loc9, %.loc9_14.1 [template = constants.%.7]
+// CHECK:STDOUT: %.loc9_25: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc9_30: f64 = float_literal 2 [template = constants.%.7]
+// CHECK:STDOUT: %float.greater.loc9: init bool = call %Greater.ref.loc9(%.loc9_25, %.loc9_30) [template = constants.%.8]
+// CHECK:STDOUT: %.loc9_14.1: bool = value_of_initializer %float.greater.loc9 [template = constants.%.8]
+// CHECK:STDOUT: %.loc9_14.2: bool = converted %float.greater.loc9, %.loc9_14.1 [template = constants.%.8]
// CHECK:STDOUT: if %.loc9_14.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc9:
@@ -187,11 +192,11 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: %.loc9_14.3: type = block_arg !if.expr.result.loc9 [template = constants.%False]
// CHECK:STDOUT: %false_.ref.loc10: %False = name_ref false_, %false_
// CHECK:STDOUT: %Greater.ref.loc10: %Greater.type = name_ref Greater, file.%Greater.decl [template = constants.%Greater]
-// CHECK:STDOUT: %.loc10_25: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %.loc10_30: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %float.greater.loc10: init bool = call %Greater.ref.loc10(%.loc10_25, %.loc10_30) [template = constants.%.7]
-// CHECK:STDOUT: %.loc10_14.1: bool = value_of_initializer %float.greater.loc10 [template = constants.%.7]
-// CHECK:STDOUT: %.loc10_14.2: bool = converted %float.greater.loc10, %.loc10_14.1 [template = constants.%.7]
+// CHECK:STDOUT: %.loc10_25: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc10_30: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %float.greater.loc10: init bool = call %Greater.ref.loc10(%.loc10_25, %.loc10_30) [template = constants.%.8]
+// CHECK:STDOUT: %.loc10_14.1: bool = value_of_initializer %float.greater.loc10 [template = constants.%.8]
+// CHECK:STDOUT: %.loc10_14.2: bool = converted %float.greater.loc10, %.loc10_14.1 [template = constants.%.8]
// CHECK:STDOUT: if %.loc10_14.2 br !if.expr.then.loc10 else br !if.expr.else.loc10
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc10:
@@ -206,11 +211,11 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: %.loc10_14.3: type = block_arg !if.expr.result.loc10 [template = constants.%False]
// CHECK:STDOUT: %true_.ref.loc11: %True = name_ref true_, %true_
// CHECK:STDOUT: %Greater.ref.loc11: %Greater.type = name_ref Greater, file.%Greater.decl [template = constants.%Greater]
-// CHECK:STDOUT: %.loc11_24: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %.loc11_29: f64 = float_literal 0 [template = constants.%.8]
-// CHECK:STDOUT: %float.greater.loc11: init bool = call %Greater.ref.loc11(%.loc11_24, %.loc11_29) [template = constants.%.9]
-// CHECK:STDOUT: %.loc11_13.1: bool = value_of_initializer %float.greater.loc11 [template = constants.%.9]
-// CHECK:STDOUT: %.loc11_13.2: bool = converted %float.greater.loc11, %.loc11_13.1 [template = constants.%.9]
+// CHECK:STDOUT: %.loc11_24: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc11_29: f64 = float_literal 0 [template = constants.%.9]
+// CHECK:STDOUT: %float.greater.loc11: init bool = call %Greater.ref.loc11(%.loc11_24, %.loc11_29) [template = constants.%.10]
+// CHECK:STDOUT: %.loc11_13.1: bool = value_of_initializer %float.greater.loc11 [template = constants.%.10]
+// CHECK:STDOUT: %.loc11_13.2: bool = converted %float.greater.loc11, %.loc11_13.1 [template = constants.%.10]
// CHECK:STDOUT: if %.loc11_13.2 br !if.expr.then.loc11 else br !if.expr.else.loc11
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc11:
@@ -226,14 +231,14 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: %false_.ref.loc12: %False = name_ref false_, %false_
// CHECK:STDOUT: %Greater.ref.loc12: %Greater.type = name_ref Greater, file.%Greater.decl [template = constants.%Greater]
// CHECK:STDOUT: %Negate.ref.loc12: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT: %.loc12_32: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %float.negate.loc12: init f64 = call %Negate.ref.loc12(%.loc12_32) [template = constants.%.10]
-// CHECK:STDOUT: %.loc12_38: f64 = float_literal 0 [template = constants.%.8]
-// CHECK:STDOUT: %.loc12_24.1: f64 = value_of_initializer %float.negate.loc12 [template = constants.%.10]
-// CHECK:STDOUT: %.loc12_24.2: f64 = converted %float.negate.loc12, %.loc12_24.1 [template = constants.%.10]
-// CHECK:STDOUT: %float.greater.loc12: init bool = call %Greater.ref.loc12(%.loc12_24.2, %.loc12_38) [template = constants.%.7]
-// CHECK:STDOUT: %.loc12_14.1: bool = value_of_initializer %float.greater.loc12 [template = constants.%.7]
-// CHECK:STDOUT: %.loc12_14.2: bool = converted %float.greater.loc12, %.loc12_14.1 [template = constants.%.7]
+// CHECK:STDOUT: %.loc12_32: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %float.negate.loc12: init f64 = call %Negate.ref.loc12(%.loc12_32) [template = constants.%.11]
+// CHECK:STDOUT: %.loc12_38: f64 = float_literal 0 [template = constants.%.9]
+// CHECK:STDOUT: %.loc12_24.1: f64 = value_of_initializer %float.negate.loc12 [template = constants.%.11]
+// CHECK:STDOUT: %.loc12_24.2: f64 = converted %float.negate.loc12, %.loc12_24.1 [template = constants.%.11]
+// CHECK:STDOUT: %float.greater.loc12: init bool = call %Greater.ref.loc12(%.loc12_24.2, %.loc12_38) [template = constants.%.8]
+// CHECK:STDOUT: %.loc12_14.1: bool = value_of_initializer %float.greater.loc12 [template = constants.%.8]
+// CHECK:STDOUT: %.loc12_14.2: bool = converted %float.greater.loc12, %.loc12_14.1 [template = constants.%.8]
// CHECK:STDOUT: if %.loc12_14.2 br !if.expr.then.loc12 else br !if.expr.else.loc12
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc12:
@@ -248,15 +253,15 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: %.loc12_14.3: type = block_arg !if.expr.result.loc12 [template = constants.%False]
// CHECK:STDOUT: %true_.ref.loc13: %True = name_ref true_, %true_
// CHECK:STDOUT: %Greater.ref.loc13: %Greater.type = name_ref Greater, file.%Greater.decl [template = constants.%Greater]
-// CHECK:STDOUT: %.loc13_24: f64 = float_literal 0 [template = constants.%.8]
+// CHECK:STDOUT: %.loc13_24: f64 = float_literal 0 [template = constants.%.9]
// CHECK:STDOUT: %Negate.ref.loc13: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT: %.loc13_36: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %float.negate.loc13: init f64 = call %Negate.ref.loc13(%.loc13_36) [template = constants.%.10]
-// CHECK:STDOUT: %.loc13_23.1: f64 = value_of_initializer %float.negate.loc13 [template = constants.%.10]
-// CHECK:STDOUT: %.loc13_23.2: f64 = converted %float.negate.loc13, %.loc13_23.1 [template = constants.%.10]
-// CHECK:STDOUT: %float.greater.loc13: init bool = call %Greater.ref.loc13(%.loc13_24, %.loc13_23.2) [template = constants.%.9]
-// CHECK:STDOUT: %.loc13_13.1: bool = value_of_initializer %float.greater.loc13 [template = constants.%.9]
-// CHECK:STDOUT: %.loc13_13.2: bool = converted %float.greater.loc13, %.loc13_13.1 [template = constants.%.9]
+// CHECK:STDOUT: %.loc13_36: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %float.negate.loc13: init f64 = call %Negate.ref.loc13(%.loc13_36) [template = constants.%.11]
+// CHECK:STDOUT: %.loc13_23.1: f64 = value_of_initializer %float.negate.loc13 [template = constants.%.11]
+// CHECK:STDOUT: %.loc13_23.2: f64 = converted %float.negate.loc13, %.loc13_23.1 [template = constants.%.11]
+// CHECK:STDOUT: %float.greater.loc13: init bool = call %Greater.ref.loc13(%.loc13_24, %.loc13_23.2) [template = constants.%.10]
+// CHECK:STDOUT: %.loc13_13.1: bool = value_of_initializer %float.greater.loc13 [template = constants.%.10]
+// CHECK:STDOUT: %.loc13_13.2: bool = converted %float.greater.loc13, %.loc13_13.1 [template = constants.%.10]
// CHECK:STDOUT: if %.loc13_13.2 br !if.expr.then.loc13 else br !if.expr.else.loc13
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc13:
diff --git a/toolchain/check/testdata/builtins/float/greater_eq.carbon b/toolchain/check/testdata/builtins/float/greater_eq.carbon
index 9f4e8537bb092..0c8ffc9f6211b 100644
--- a/toolchain/check/testdata/builtins/float/greater_eq.carbon
+++ b/toolchain/check/testdata/builtins/float/greater_eq.carbon
@@ -43,16 +43,17 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: %Negate: %Negate.type = struct_value () [template]
// CHECK:STDOUT: %True: type = class_type @True [template]
// CHECK:STDOUT: %.3: type = struct_type {} [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
// CHECK:STDOUT: %False: type = class_type @False [template]
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
-// CHECK:STDOUT: %.5: f64 = float_literal 1 [template]
-// CHECK:STDOUT: %.6: f64 = float_literal 2 [template]
-// CHECK:STDOUT: %.7: bool = bool_literal false [template]
-// CHECK:STDOUT: %.8: bool = bool_literal true [template]
-// CHECK:STDOUT: %.9: f64 = float_literal 0 [template]
-// CHECK:STDOUT: %.10: f64 = float_literal -1 [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.6: f64 = float_literal 1 [template]
+// CHECK:STDOUT: %.7: f64 = float_literal 2 [template]
+// CHECK:STDOUT: %.8: bool = bool_literal false [template]
+// CHECK:STDOUT: %.9: bool = bool_literal true [template]
+// CHECK:STDOUT: %.10: f64 = float_literal 0 [template]
+// CHECK:STDOUT: %.11: f64 = float_literal -1 [template]
// CHECK:STDOUT: %RuntimeCall.type: type = fn_type @RuntimeCall [template]
// CHECK:STDOUT: %RuntimeCall: %RuntimeCall.type = struct_value () [template]
// CHECK:STDOUT: }
@@ -147,11 +148,15 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @True {
+// CHECK:STDOUT: %.loc5: = complete_type_witness %.3 [template = constants.%.4]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%True
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @False {
+// CHECK:STDOUT: %.loc6: = complete_type_witness %.3 [template = constants.%.4]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%False
// CHECK:STDOUT: }
@@ -168,11 +173,11 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %false_.ref.loc9: %False = name_ref false_, %false_
// CHECK:STDOUT: %GreaterEq.ref.loc9: %GreaterEq.type = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%GreaterEq]
-// CHECK:STDOUT: %.loc9_27: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %.loc9_32: f64 = float_literal 2 [template = constants.%.6]
-// CHECK:STDOUT: %float.greater_eq.loc9: init bool = call %GreaterEq.ref.loc9(%.loc9_27, %.loc9_32) [template = constants.%.7]
-// CHECK:STDOUT: %.loc9_14.1: bool = value_of_initializer %float.greater_eq.loc9 [template = constants.%.7]
-// CHECK:STDOUT: %.loc9_14.2: bool = converted %float.greater_eq.loc9, %.loc9_14.1 [template = constants.%.7]
+// CHECK:STDOUT: %.loc9_27: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc9_32: f64 = float_literal 2 [template = constants.%.7]
+// CHECK:STDOUT: %float.greater_eq.loc9: init bool = call %GreaterEq.ref.loc9(%.loc9_27, %.loc9_32) [template = constants.%.8]
+// CHECK:STDOUT: %.loc9_14.1: bool = value_of_initializer %float.greater_eq.loc9 [template = constants.%.8]
+// CHECK:STDOUT: %.loc9_14.2: bool = converted %float.greater_eq.loc9, %.loc9_14.1 [template = constants.%.8]
// CHECK:STDOUT: if %.loc9_14.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc9:
@@ -187,11 +192,11 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: %.loc9_14.3: type = block_arg !if.expr.result.loc9 [template = constants.%False]
// CHECK:STDOUT: %true_.ref.loc10: %True = name_ref true_, %true_
// CHECK:STDOUT: %GreaterEq.ref.loc10: %GreaterEq.type = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%GreaterEq]
-// CHECK:STDOUT: %.loc10_26: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %.loc10_31: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %float.greater_eq.loc10: init bool = call %GreaterEq.ref.loc10(%.loc10_26, %.loc10_31) [template = constants.%.8]
-// CHECK:STDOUT: %.loc10_13.1: bool = value_of_initializer %float.greater_eq.loc10 [template = constants.%.8]
-// CHECK:STDOUT: %.loc10_13.2: bool = converted %float.greater_eq.loc10, %.loc10_13.1 [template = constants.%.8]
+// CHECK:STDOUT: %.loc10_26: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc10_31: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %float.greater_eq.loc10: init bool = call %GreaterEq.ref.loc10(%.loc10_26, %.loc10_31) [template = constants.%.9]
+// CHECK:STDOUT: %.loc10_13.1: bool = value_of_initializer %float.greater_eq.loc10 [template = constants.%.9]
+// CHECK:STDOUT: %.loc10_13.2: bool = converted %float.greater_eq.loc10, %.loc10_13.1 [template = constants.%.9]
// CHECK:STDOUT: if %.loc10_13.2 br !if.expr.then.loc10 else br !if.expr.else.loc10
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc10:
@@ -206,11 +211,11 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: %.loc10_13.3: type = block_arg !if.expr.result.loc10 [template = constants.%True]
// CHECK:STDOUT: %true_.ref.loc11: %True = name_ref true_, %true_
// CHECK:STDOUT: %GreaterEq.ref.loc11: %GreaterEq.type = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%GreaterEq]
-// CHECK:STDOUT: %.loc11_26: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %.loc11_31: f64 = float_literal 0 [template = constants.%.9]
-// CHECK:STDOUT: %float.greater_eq.loc11: init bool = call %GreaterEq.ref.loc11(%.loc11_26, %.loc11_31) [template = constants.%.8]
-// CHECK:STDOUT: %.loc11_13.1: bool = value_of_initializer %float.greater_eq.loc11 [template = constants.%.8]
-// CHECK:STDOUT: %.loc11_13.2: bool = converted %float.greater_eq.loc11, %.loc11_13.1 [template = constants.%.8]
+// CHECK:STDOUT: %.loc11_26: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc11_31: f64 = float_literal 0 [template = constants.%.10]
+// CHECK:STDOUT: %float.greater_eq.loc11: init bool = call %GreaterEq.ref.loc11(%.loc11_26, %.loc11_31) [template = constants.%.9]
+// CHECK:STDOUT: %.loc11_13.1: bool = value_of_initializer %float.greater_eq.loc11 [template = constants.%.9]
+// CHECK:STDOUT: %.loc11_13.2: bool = converted %float.greater_eq.loc11, %.loc11_13.1 [template = constants.%.9]
// CHECK:STDOUT: if %.loc11_13.2 br !if.expr.then.loc11 else br !if.expr.else.loc11
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc11:
@@ -226,14 +231,14 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: %false_.ref.loc12: %False = name_ref false_, %false_
// CHECK:STDOUT: %GreaterEq.ref.loc12: %GreaterEq.type = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%GreaterEq]
// CHECK:STDOUT: %Negate.ref.loc12: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT: %.loc12_34: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %float.negate.loc12: init f64 = call %Negate.ref.loc12(%.loc12_34) [template = constants.%.10]
-// CHECK:STDOUT: %.loc12_40: f64 = float_literal 0 [template = constants.%.9]
-// CHECK:STDOUT: %.loc12_26.1: f64 = value_of_initializer %float.negate.loc12 [template = constants.%.10]
-// CHECK:STDOUT: %.loc12_26.2: f64 = converted %float.negate.loc12, %.loc12_26.1 [template = constants.%.10]
-// CHECK:STDOUT: %float.greater_eq.loc12: init bool = call %GreaterEq.ref.loc12(%.loc12_26.2, %.loc12_40) [template = constants.%.7]
-// CHECK:STDOUT: %.loc12_14.1: bool = value_of_initializer %float.greater_eq.loc12 [template = constants.%.7]
-// CHECK:STDOUT: %.loc12_14.2: bool = converted %float.greater_eq.loc12, %.loc12_14.1 [template = constants.%.7]
+// CHECK:STDOUT: %.loc12_34: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %float.negate.loc12: init f64 = call %Negate.ref.loc12(%.loc12_34) [template = constants.%.11]
+// CHECK:STDOUT: %.loc12_40: f64 = float_literal 0 [template = constants.%.10]
+// CHECK:STDOUT: %.loc12_26.1: f64 = value_of_initializer %float.negate.loc12 [template = constants.%.11]
+// CHECK:STDOUT: %.loc12_26.2: f64 = converted %float.negate.loc12, %.loc12_26.1 [template = constants.%.11]
+// CHECK:STDOUT: %float.greater_eq.loc12: init bool = call %GreaterEq.ref.loc12(%.loc12_26.2, %.loc12_40) [template = constants.%.8]
+// CHECK:STDOUT: %.loc12_14.1: bool = value_of_initializer %float.greater_eq.loc12 [template = constants.%.8]
+// CHECK:STDOUT: %.loc12_14.2: bool = converted %float.greater_eq.loc12, %.loc12_14.1 [template = constants.%.8]
// CHECK:STDOUT: if %.loc12_14.2 br !if.expr.then.loc12 else br !if.expr.else.loc12
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc12:
@@ -248,15 +253,15 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: %.loc12_14.3: type = block_arg !if.expr.result.loc12 [template = constants.%False]
// CHECK:STDOUT: %true_.ref.loc13: %True = name_ref true_, %true_
// CHECK:STDOUT: %GreaterEq.ref.loc13: %GreaterEq.type = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%GreaterEq]
-// CHECK:STDOUT: %.loc13_26: f64 = float_literal 0 [template = constants.%.9]
+// CHECK:STDOUT: %.loc13_26: f64 = float_literal 0 [template = constants.%.10]
// CHECK:STDOUT: %Negate.ref.loc13: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT: %.loc13_38: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %float.negate.loc13: init f64 = call %Negate.ref.loc13(%.loc13_38) [template = constants.%.10]
-// CHECK:STDOUT: %.loc13_25.1: f64 = value_of_initializer %float.negate.loc13 [template = constants.%.10]
-// CHECK:STDOUT: %.loc13_25.2: f64 = converted %float.negate.loc13, %.loc13_25.1 [template = constants.%.10]
-// CHECK:STDOUT: %float.greater_eq.loc13: init bool = call %GreaterEq.ref.loc13(%.loc13_26, %.loc13_25.2) [template = constants.%.8]
-// CHECK:STDOUT: %.loc13_13.1: bool = value_of_initializer %float.greater_eq.loc13 [template = constants.%.8]
-// CHECK:STDOUT: %.loc13_13.2: bool = converted %float.greater_eq.loc13, %.loc13_13.1 [template = constants.%.8]
+// CHECK:STDOUT: %.loc13_38: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %float.negate.loc13: init f64 = call %Negate.ref.loc13(%.loc13_38) [template = constants.%.11]
+// CHECK:STDOUT: %.loc13_25.1: f64 = value_of_initializer %float.negate.loc13 [template = constants.%.11]
+// CHECK:STDOUT: %.loc13_25.2: f64 = converted %float.negate.loc13, %.loc13_25.1 [template = constants.%.11]
+// CHECK:STDOUT: %float.greater_eq.loc13: init bool = call %GreaterEq.ref.loc13(%.loc13_26, %.loc13_25.2) [template = constants.%.9]
+// CHECK:STDOUT: %.loc13_13.1: bool = value_of_initializer %float.greater_eq.loc13 [template = constants.%.9]
+// CHECK:STDOUT: %.loc13_13.2: bool = converted %float.greater_eq.loc13, %.loc13_13.1 [template = constants.%.9]
// CHECK:STDOUT: if %.loc13_13.2 br !if.expr.then.loc13 else br !if.expr.else.loc13
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc13:
diff --git a/toolchain/check/testdata/builtins/float/less.carbon b/toolchain/check/testdata/builtins/float/less.carbon
index 8ec60ba29b3d9..ce67aaa0e314f 100644
--- a/toolchain/check/testdata/builtins/float/less.carbon
+++ b/toolchain/check/testdata/builtins/float/less.carbon
@@ -43,16 +43,17 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: %Negate: %Negate.type = struct_value () [template]
// CHECK:STDOUT: %True: type = class_type @True [template]
// CHECK:STDOUT: %.3: type = struct_type {} [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
// CHECK:STDOUT: %False: type = class_type @False [template]
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
-// CHECK:STDOUT: %.5: f64 = float_literal 1 [template]
-// CHECK:STDOUT: %.6: f64 = float_literal 2 [template]
-// CHECK:STDOUT: %.7: bool = bool_literal true [template]
-// CHECK:STDOUT: %.8: bool = bool_literal false [template]
-// CHECK:STDOUT: %.9: f64 = float_literal 0 [template]
-// CHECK:STDOUT: %.10: f64 = float_literal -1 [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.6: f64 = float_literal 1 [template]
+// CHECK:STDOUT: %.7: f64 = float_literal 2 [template]
+// CHECK:STDOUT: %.8: bool = bool_literal true [template]
+// CHECK:STDOUT: %.9: bool = bool_literal false [template]
+// CHECK:STDOUT: %.10: f64 = float_literal 0 [template]
+// CHECK:STDOUT: %.11: f64 = float_literal -1 [template]
// CHECK:STDOUT: %RuntimeCall.type: type = fn_type @RuntimeCall [template]
// CHECK:STDOUT: %RuntimeCall: %RuntimeCall.type = struct_value () [template]
// CHECK:STDOUT: }
@@ -147,11 +148,15 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @True {
+// CHECK:STDOUT: %.loc5: = complete_type_witness %.3 [template = constants.%.4]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%True
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @False {
+// CHECK:STDOUT: %.loc6: = complete_type_witness %.3 [template = constants.%.4]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%False
// CHECK:STDOUT: }
@@ -168,11 +173,11 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %true_.ref.loc9: %True = name_ref true_, %true_
// CHECK:STDOUT: %Less.ref.loc9: %Less.type = name_ref Less, file.%Less.decl [template = constants.%Less]
-// CHECK:STDOUT: %.loc9_21: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %.loc9_26: f64 = float_literal 2 [template = constants.%.6]
-// CHECK:STDOUT: %float.less.loc9: init bool = call %Less.ref.loc9(%.loc9_21, %.loc9_26) [template = constants.%.7]
-// CHECK:STDOUT: %.loc9_13.1: bool = value_of_initializer %float.less.loc9 [template = constants.%.7]
-// CHECK:STDOUT: %.loc9_13.2: bool = converted %float.less.loc9, %.loc9_13.1 [template = constants.%.7]
+// CHECK:STDOUT: %.loc9_21: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc9_26: f64 = float_literal 2 [template = constants.%.7]
+// CHECK:STDOUT: %float.less.loc9: init bool = call %Less.ref.loc9(%.loc9_21, %.loc9_26) [template = constants.%.8]
+// CHECK:STDOUT: %.loc9_13.1: bool = value_of_initializer %float.less.loc9 [template = constants.%.8]
+// CHECK:STDOUT: %.loc9_13.2: bool = converted %float.less.loc9, %.loc9_13.1 [template = constants.%.8]
// CHECK:STDOUT: if %.loc9_13.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc9:
@@ -187,11 +192,11 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: %.loc9_13.3: type = block_arg !if.expr.result.loc9 [template = constants.%True]
// CHECK:STDOUT: %false_.ref.loc10: %False = name_ref false_, %false_
// CHECK:STDOUT: %Less.ref.loc10: %Less.type = name_ref Less, file.%Less.decl [template = constants.%Less]
-// CHECK:STDOUT: %.loc10_22: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %.loc10_27: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %float.less.loc10: init bool = call %Less.ref.loc10(%.loc10_22, %.loc10_27) [template = constants.%.8]
-// CHECK:STDOUT: %.loc10_14.1: bool = value_of_initializer %float.less.loc10 [template = constants.%.8]
-// CHECK:STDOUT: %.loc10_14.2: bool = converted %float.less.loc10, %.loc10_14.1 [template = constants.%.8]
+// CHECK:STDOUT: %.loc10_22: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc10_27: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %float.less.loc10: init bool = call %Less.ref.loc10(%.loc10_22, %.loc10_27) [template = constants.%.9]
+// CHECK:STDOUT: %.loc10_14.1: bool = value_of_initializer %float.less.loc10 [template = constants.%.9]
+// CHECK:STDOUT: %.loc10_14.2: bool = converted %float.less.loc10, %.loc10_14.1 [template = constants.%.9]
// CHECK:STDOUT: if %.loc10_14.2 br !if.expr.then.loc10 else br !if.expr.else.loc10
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc10:
@@ -206,11 +211,11 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: %.loc10_14.3: type = block_arg !if.expr.result.loc10 [template = constants.%False]
// CHECK:STDOUT: %false_.ref.loc11: %False = name_ref false_, %false_
// CHECK:STDOUT: %Less.ref.loc11: %Less.type = name_ref Less, file.%Less.decl [template = constants.%Less]
-// CHECK:STDOUT: %.loc11_22: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %.loc11_27: f64 = float_literal 0 [template = constants.%.9]
-// CHECK:STDOUT: %float.less.loc11: init bool = call %Less.ref.loc11(%.loc11_22, %.loc11_27) [template = constants.%.8]
-// CHECK:STDOUT: %.loc11_14.1: bool = value_of_initializer %float.less.loc11 [template = constants.%.8]
-// CHECK:STDOUT: %.loc11_14.2: bool = converted %float.less.loc11, %.loc11_14.1 [template = constants.%.8]
+// CHECK:STDOUT: %.loc11_22: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc11_27: f64 = float_literal 0 [template = constants.%.10]
+// CHECK:STDOUT: %float.less.loc11: init bool = call %Less.ref.loc11(%.loc11_22, %.loc11_27) [template = constants.%.9]
+// CHECK:STDOUT: %.loc11_14.1: bool = value_of_initializer %float.less.loc11 [template = constants.%.9]
+// CHECK:STDOUT: %.loc11_14.2: bool = converted %float.less.loc11, %.loc11_14.1 [template = constants.%.9]
// CHECK:STDOUT: if %.loc11_14.2 br !if.expr.then.loc11 else br !if.expr.else.loc11
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc11:
@@ -226,14 +231,14 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: %true_.ref.loc12: %True = name_ref true_, %true_
// CHECK:STDOUT: %Less.ref.loc12: %Less.type = name_ref Less, file.%Less.decl [template = constants.%Less]
// CHECK:STDOUT: %Negate.ref.loc12: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT: %.loc12_28: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %float.negate.loc12: init f64 = call %Negate.ref.loc12(%.loc12_28) [template = constants.%.10]
-// CHECK:STDOUT: %.loc12_34: f64 = float_literal 0 [template = constants.%.9]
-// CHECK:STDOUT: %.loc12_20.1: f64 = value_of_initializer %float.negate.loc12 [template = constants.%.10]
-// CHECK:STDOUT: %.loc12_20.2: f64 = converted %float.negate.loc12, %.loc12_20.1 [template = constants.%.10]
-// CHECK:STDOUT: %float.less.loc12: init bool = call %Less.ref.loc12(%.loc12_20.2, %.loc12_34) [template = constants.%.7]
-// CHECK:STDOUT: %.loc12_13.1: bool = value_of_initializer %float.less.loc12 [template = constants.%.7]
-// CHECK:STDOUT: %.loc12_13.2: bool = converted %float.less.loc12, %.loc12_13.1 [template = constants.%.7]
+// CHECK:STDOUT: %.loc12_28: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %float.negate.loc12: init f64 = call %Negate.ref.loc12(%.loc12_28) [template = constants.%.11]
+// CHECK:STDOUT: %.loc12_34: f64 = float_literal 0 [template = constants.%.10]
+// CHECK:STDOUT: %.loc12_20.1: f64 = value_of_initializer %float.negate.loc12 [template = constants.%.11]
+// CHECK:STDOUT: %.loc12_20.2: f64 = converted %float.negate.loc12, %.loc12_20.1 [template = constants.%.11]
+// CHECK:STDOUT: %float.less.loc12: init bool = call %Less.ref.loc12(%.loc12_20.2, %.loc12_34) [template = constants.%.8]
+// CHECK:STDOUT: %.loc12_13.1: bool = value_of_initializer %float.less.loc12 [template = constants.%.8]
+// CHECK:STDOUT: %.loc12_13.2: bool = converted %float.less.loc12, %.loc12_13.1 [template = constants.%.8]
// CHECK:STDOUT: if %.loc12_13.2 br !if.expr.then.loc12 else br !if.expr.else.loc12
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc12:
@@ -248,15 +253,15 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: %.loc12_13.3: type = block_arg !if.expr.result.loc12 [template = constants.%True]
// CHECK:STDOUT: %false_.ref.loc13: %False = name_ref false_, %false_
// CHECK:STDOUT: %Less.ref.loc13: %Less.type = name_ref Less, file.%Less.decl [template = constants.%Less]
-// CHECK:STDOUT: %.loc13_22: f64 = float_literal 0 [template = constants.%.9]
+// CHECK:STDOUT: %.loc13_22: f64 = float_literal 0 [template = constants.%.10]
// CHECK:STDOUT: %Negate.ref.loc13: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT: %.loc13_34: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %float.negate.loc13: init f64 = call %Negate.ref.loc13(%.loc13_34) [template = constants.%.10]
-// CHECK:STDOUT: %.loc13_21.1: f64 = value_of_initializer %float.negate.loc13 [template = constants.%.10]
-// CHECK:STDOUT: %.loc13_21.2: f64 = converted %float.negate.loc13, %.loc13_21.1 [template = constants.%.10]
-// CHECK:STDOUT: %float.less.loc13: init bool = call %Less.ref.loc13(%.loc13_22, %.loc13_21.2) [template = constants.%.8]
-// CHECK:STDOUT: %.loc13_14.1: bool = value_of_initializer %float.less.loc13 [template = constants.%.8]
-// CHECK:STDOUT: %.loc13_14.2: bool = converted %float.less.loc13, %.loc13_14.1 [template = constants.%.8]
+// CHECK:STDOUT: %.loc13_34: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %float.negate.loc13: init f64 = call %Negate.ref.loc13(%.loc13_34) [template = constants.%.11]
+// CHECK:STDOUT: %.loc13_21.1: f64 = value_of_initializer %float.negate.loc13 [template = constants.%.11]
+// CHECK:STDOUT: %.loc13_21.2: f64 = converted %float.negate.loc13, %.loc13_21.1 [template = constants.%.11]
+// CHECK:STDOUT: %float.less.loc13: init bool = call %Less.ref.loc13(%.loc13_22, %.loc13_21.2) [template = constants.%.9]
+// CHECK:STDOUT: %.loc13_14.1: bool = value_of_initializer %float.less.loc13 [template = constants.%.9]
+// CHECK:STDOUT: %.loc13_14.2: bool = converted %float.less.loc13, %.loc13_14.1 [template = constants.%.9]
// CHECK:STDOUT: if %.loc13_14.2 br !if.expr.then.loc13 else br !if.expr.else.loc13
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc13:
diff --git a/toolchain/check/testdata/builtins/float/less_eq.carbon b/toolchain/check/testdata/builtins/float/less_eq.carbon
index e5359dc5bc5da..82effca5c6638 100644
--- a/toolchain/check/testdata/builtins/float/less_eq.carbon
+++ b/toolchain/check/testdata/builtins/float/less_eq.carbon
@@ -43,16 +43,17 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: %Negate: %Negate.type = struct_value () [template]
// CHECK:STDOUT: %True: type = class_type @True [template]
// CHECK:STDOUT: %.3: type = struct_type {} [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
// CHECK:STDOUT: %False: type = class_type @False [template]
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
-// CHECK:STDOUT: %.5: f64 = float_literal 1 [template]
-// CHECK:STDOUT: %.6: f64 = float_literal 2 [template]
-// CHECK:STDOUT: %.7: bool = bool_literal true [template]
-// CHECK:STDOUT: %.8: f64 = float_literal 0 [template]
-// CHECK:STDOUT: %.9: bool = bool_literal false [template]
-// CHECK:STDOUT: %.10: f64 = float_literal -1 [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.6: f64 = float_literal 1 [template]
+// CHECK:STDOUT: %.7: f64 = float_literal 2 [template]
+// CHECK:STDOUT: %.8: bool = bool_literal true [template]
+// CHECK:STDOUT: %.9: f64 = float_literal 0 [template]
+// CHECK:STDOUT: %.10: bool = bool_literal false [template]
+// CHECK:STDOUT: %.11: f64 = float_literal -1 [template]
// CHECK:STDOUT: %RuntimeCall.type: type = fn_type @RuntimeCall [template]
// CHECK:STDOUT: %RuntimeCall: %RuntimeCall.type = struct_value () [template]
// CHECK:STDOUT: }
@@ -147,11 +148,15 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @True {
+// CHECK:STDOUT: %.loc5: = complete_type_witness %.3 [template = constants.%.4]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%True
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @False {
+// CHECK:STDOUT: %.loc6: = complete_type_witness %.3 [template = constants.%.4]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%False
// CHECK:STDOUT: }
@@ -168,11 +173,11 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %true_.ref.loc9: %True = name_ref true_, %true_
// CHECK:STDOUT: %LessEq.ref.loc9: %LessEq.type = name_ref LessEq, file.%LessEq.decl [template = constants.%LessEq]
-// CHECK:STDOUT: %.loc9_23: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %.loc9_28: f64 = float_literal 2 [template = constants.%.6]
-// CHECK:STDOUT: %float.less_eq.loc9: init bool = call %LessEq.ref.loc9(%.loc9_23, %.loc9_28) [template = constants.%.7]
-// CHECK:STDOUT: %.loc9_13.1: bool = value_of_initializer %float.less_eq.loc9 [template = constants.%.7]
-// CHECK:STDOUT: %.loc9_13.2: bool = converted %float.less_eq.loc9, %.loc9_13.1 [template = constants.%.7]
+// CHECK:STDOUT: %.loc9_23: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc9_28: f64 = float_literal 2 [template = constants.%.7]
+// CHECK:STDOUT: %float.less_eq.loc9: init bool = call %LessEq.ref.loc9(%.loc9_23, %.loc9_28) [template = constants.%.8]
+// CHECK:STDOUT: %.loc9_13.1: bool = value_of_initializer %float.less_eq.loc9 [template = constants.%.8]
+// CHECK:STDOUT: %.loc9_13.2: bool = converted %float.less_eq.loc9, %.loc9_13.1 [template = constants.%.8]
// CHECK:STDOUT: if %.loc9_13.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc9:
@@ -187,11 +192,11 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: %.loc9_13.3: type = block_arg !if.expr.result.loc9 [template = constants.%True]
// CHECK:STDOUT: %true_.ref.loc10: %True = name_ref true_, %true_
// CHECK:STDOUT: %LessEq.ref.loc10: %LessEq.type = name_ref LessEq, file.%LessEq.decl [template = constants.%LessEq]
-// CHECK:STDOUT: %.loc10_23: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %.loc10_28: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %float.less_eq.loc10: init bool = call %LessEq.ref.loc10(%.loc10_23, %.loc10_28) [template = constants.%.7]
-// CHECK:STDOUT: %.loc10_13.1: bool = value_of_initializer %float.less_eq.loc10 [template = constants.%.7]
-// CHECK:STDOUT: %.loc10_13.2: bool = converted %float.less_eq.loc10, %.loc10_13.1 [template = constants.%.7]
+// CHECK:STDOUT: %.loc10_23: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc10_28: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %float.less_eq.loc10: init bool = call %LessEq.ref.loc10(%.loc10_23, %.loc10_28) [template = constants.%.8]
+// CHECK:STDOUT: %.loc10_13.1: bool = value_of_initializer %float.less_eq.loc10 [template = constants.%.8]
+// CHECK:STDOUT: %.loc10_13.2: bool = converted %float.less_eq.loc10, %.loc10_13.1 [template = constants.%.8]
// CHECK:STDOUT: if %.loc10_13.2 br !if.expr.then.loc10 else br !if.expr.else.loc10
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc10:
@@ -206,11 +211,11 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: %.loc10_13.3: type = block_arg !if.expr.result.loc10 [template = constants.%True]
// CHECK:STDOUT: %false_.ref.loc11: %False = name_ref false_, %false_
// CHECK:STDOUT: %LessEq.ref.loc11: %LessEq.type = name_ref LessEq, file.%LessEq.decl [template = constants.%LessEq]
-// CHECK:STDOUT: %.loc11_24: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %.loc11_29: f64 = float_literal 0 [template = constants.%.8]
-// CHECK:STDOUT: %float.less_eq.loc11: init bool = call %LessEq.ref.loc11(%.loc11_24, %.loc11_29) [template = constants.%.9]
-// CHECK:STDOUT: %.loc11_14.1: bool = value_of_initializer %float.less_eq.loc11 [template = constants.%.9]
-// CHECK:STDOUT: %.loc11_14.2: bool = converted %float.less_eq.loc11, %.loc11_14.1 [template = constants.%.9]
+// CHECK:STDOUT: %.loc11_24: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc11_29: f64 = float_literal 0 [template = constants.%.9]
+// CHECK:STDOUT: %float.less_eq.loc11: init bool = call %LessEq.ref.loc11(%.loc11_24, %.loc11_29) [template = constants.%.10]
+// CHECK:STDOUT: %.loc11_14.1: bool = value_of_initializer %float.less_eq.loc11 [template = constants.%.10]
+// CHECK:STDOUT: %.loc11_14.2: bool = converted %float.less_eq.loc11, %.loc11_14.1 [template = constants.%.10]
// CHECK:STDOUT: if %.loc11_14.2 br !if.expr.then.loc11 else br !if.expr.else.loc11
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc11:
@@ -226,14 +231,14 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: %true_.ref.loc12: %True = name_ref true_, %true_
// CHECK:STDOUT: %LessEq.ref.loc12: %LessEq.type = name_ref LessEq, file.%LessEq.decl [template = constants.%LessEq]
// CHECK:STDOUT: %Negate.ref.loc12: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT: %.loc12_30: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %float.negate.loc12: init f64 = call %Negate.ref.loc12(%.loc12_30) [template = constants.%.10]
-// CHECK:STDOUT: %.loc12_36: f64 = float_literal 0 [template = constants.%.8]
-// CHECK:STDOUT: %.loc12_22.1: f64 = value_of_initializer %float.negate.loc12 [template = constants.%.10]
-// CHECK:STDOUT: %.loc12_22.2: f64 = converted %float.negate.loc12, %.loc12_22.1 [template = constants.%.10]
-// CHECK:STDOUT: %float.less_eq.loc12: init bool = call %LessEq.ref.loc12(%.loc12_22.2, %.loc12_36) [template = constants.%.7]
-// CHECK:STDOUT: %.loc12_13.1: bool = value_of_initializer %float.less_eq.loc12 [template = constants.%.7]
-// CHECK:STDOUT: %.loc12_13.2: bool = converted %float.less_eq.loc12, %.loc12_13.1 [template = constants.%.7]
+// CHECK:STDOUT: %.loc12_30: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %float.negate.loc12: init f64 = call %Negate.ref.loc12(%.loc12_30) [template = constants.%.11]
+// CHECK:STDOUT: %.loc12_36: f64 = float_literal 0 [template = constants.%.9]
+// CHECK:STDOUT: %.loc12_22.1: f64 = value_of_initializer %float.negate.loc12 [template = constants.%.11]
+// CHECK:STDOUT: %.loc12_22.2: f64 = converted %float.negate.loc12, %.loc12_22.1 [template = constants.%.11]
+// CHECK:STDOUT: %float.less_eq.loc12: init bool = call %LessEq.ref.loc12(%.loc12_22.2, %.loc12_36) [template = constants.%.8]
+// CHECK:STDOUT: %.loc12_13.1: bool = value_of_initializer %float.less_eq.loc12 [template = constants.%.8]
+// CHECK:STDOUT: %.loc12_13.2: bool = converted %float.less_eq.loc12, %.loc12_13.1 [template = constants.%.8]
// CHECK:STDOUT: if %.loc12_13.2 br !if.expr.then.loc12 else br !if.expr.else.loc12
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc12:
@@ -248,15 +253,15 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
// CHECK:STDOUT: %.loc12_13.3: type = block_arg !if.expr.result.loc12 [template = constants.%True]
// CHECK:STDOUT: %false_.ref.loc13: %False = name_ref false_, %false_
// CHECK:STDOUT: %LessEq.ref.loc13: %LessEq.type = name_ref LessEq, file.%LessEq.decl [template = constants.%LessEq]
-// CHECK:STDOUT: %.loc13_24: f64 = float_literal 0 [template = constants.%.8]
+// CHECK:STDOUT: %.loc13_24: f64 = float_literal 0 [template = constants.%.9]
// CHECK:STDOUT: %Negate.ref.loc13: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT: %.loc13_36: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %float.negate.loc13: init f64 = call %Negate.ref.loc13(%.loc13_36) [template = constants.%.10]
-// CHECK:STDOUT: %.loc13_23.1: f64 = value_of_initializer %float.negate.loc13 [template = constants.%.10]
-// CHECK:STDOUT: %.loc13_23.2: f64 = converted %float.negate.loc13, %.loc13_23.1 [template = constants.%.10]
-// CHECK:STDOUT: %float.less_eq.loc13: init bool = call %LessEq.ref.loc13(%.loc13_24, %.loc13_23.2) [template = constants.%.9]
-// CHECK:STDOUT: %.loc13_14.1: bool = value_of_initializer %float.less_eq.loc13 [template = constants.%.9]
-// CHECK:STDOUT: %.loc13_14.2: bool = converted %float.less_eq.loc13, %.loc13_14.1 [template = constants.%.9]
+// CHECK:STDOUT: %.loc13_36: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %float.negate.loc13: init f64 = call %Negate.ref.loc13(%.loc13_36) [template = constants.%.11]
+// CHECK:STDOUT: %.loc13_23.1: f64 = value_of_initializer %float.negate.loc13 [template = constants.%.11]
+// CHECK:STDOUT: %.loc13_23.2: f64 = converted %float.negate.loc13, %.loc13_23.1 [template = constants.%.11]
+// CHECK:STDOUT: %float.less_eq.loc13: init bool = call %LessEq.ref.loc13(%.loc13_24, %.loc13_23.2) [template = constants.%.10]
+// CHECK:STDOUT: %.loc13_14.1: bool = value_of_initializer %float.less_eq.loc13 [template = constants.%.10]
+// CHECK:STDOUT: %.loc13_14.2: bool = converted %float.less_eq.loc13, %.loc13_14.1 [template = constants.%.10]
// CHECK:STDOUT: if %.loc13_14.2 br !if.expr.then.loc13 else br !if.expr.else.loc13
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc13:
diff --git a/toolchain/check/testdata/builtins/float/neq.carbon b/toolchain/check/testdata/builtins/float/neq.carbon
index dc787b039f1fa..c242b7f458cab 100644
--- a/toolchain/check/testdata/builtins/float/neq.carbon
+++ b/toolchain/check/testdata/builtins/float/neq.carbon
@@ -46,14 +46,15 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.neq";
// CHECK:STDOUT: %Neq: %Neq.type = struct_value () [template]
// CHECK:STDOUT: %True: type = class_type @True [template]
// CHECK:STDOUT: %.3: type = struct_type {} [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
// CHECK:STDOUT: %False: type = class_type @False [template]
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
-// CHECK:STDOUT: %.5: f64 = float_literal 1 [template]
-// CHECK:STDOUT: %.6: f64 = float_literal 2 [template]
-// CHECK:STDOUT: %.7: bool = bool_literal true [template]
-// CHECK:STDOUT: %.8: bool = bool_literal false [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.6: f64 = float_literal 1 [template]
+// CHECK:STDOUT: %.7: f64 = float_literal 2 [template]
+// CHECK:STDOUT: %.8: bool = bool_literal true [template]
+// CHECK:STDOUT: %.9: bool = bool_literal false [template]
// CHECK:STDOUT: %RuntimeCall.type: type = fn_type @RuntimeCall [template]
// CHECK:STDOUT: %RuntimeCall: %RuntimeCall.type = struct_value () [template]
// CHECK:STDOUT: }
@@ -134,11 +135,15 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.neq";
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @True {
+// CHECK:STDOUT: %.loc4: = complete_type_witness %.3 [template = constants.%.4]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%True
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @False {
+// CHECK:STDOUT: %.loc5: = complete_type_witness %.3 [template = constants.%.4]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%False
// CHECK:STDOUT: }
@@ -153,11 +158,11 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.neq";
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %true_.ref: %True = name_ref true_, %true_
// CHECK:STDOUT: %Neq.ref.loc8: %Neq.type = name_ref Neq, file.%Neq.decl [template = constants.%Neq]
-// CHECK:STDOUT: %.loc8_20: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %.loc8_25: f64 = float_literal 2 [template = constants.%.6]
-// CHECK:STDOUT: %float.neq.loc8: init bool = call %Neq.ref.loc8(%.loc8_20, %.loc8_25) [template = constants.%.7]
-// CHECK:STDOUT: %.loc8_13.1: bool = value_of_initializer %float.neq.loc8 [template = constants.%.7]
-// CHECK:STDOUT: %.loc8_13.2: bool = converted %float.neq.loc8, %.loc8_13.1 [template = constants.%.7]
+// CHECK:STDOUT: %.loc8_20: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc8_25: f64 = float_literal 2 [template = constants.%.7]
+// CHECK:STDOUT: %float.neq.loc8: init bool = call %Neq.ref.loc8(%.loc8_20, %.loc8_25) [template = constants.%.8]
+// CHECK:STDOUT: %.loc8_13.1: bool = value_of_initializer %float.neq.loc8 [template = constants.%.8]
+// CHECK:STDOUT: %.loc8_13.2: bool = converted %float.neq.loc8, %.loc8_13.1 [template = constants.%.8]
// CHECK:STDOUT: if %.loc8_13.2 br !if.expr.then.loc8 else br !if.expr.else.loc8
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc8:
@@ -172,11 +177,11 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.neq";
// CHECK:STDOUT: %.loc8_13.3: type = block_arg !if.expr.result.loc8 [template = constants.%True]
// CHECK:STDOUT: %false_.ref: %False = name_ref false_, %false_
// CHECK:STDOUT: %Neq.ref.loc9: %Neq.type = name_ref Neq, file.%Neq.decl [template = constants.%Neq]
-// CHECK:STDOUT: %.loc9_21: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %.loc9_26: f64 = float_literal 1 [template = constants.%.5]
-// CHECK:STDOUT: %float.neq.loc9: init bool = call %Neq.ref.loc9(%.loc9_21, %.loc9_26) [template = constants.%.8]
-// CHECK:STDOUT: %.loc9_14.1: bool = value_of_initializer %float.neq.loc9 [template = constants.%.8]
-// CHECK:STDOUT: %.loc9_14.2: bool = converted %float.neq.loc9, %.loc9_14.1 [template = constants.%.8]
+// CHECK:STDOUT: %.loc9_21: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc9_26: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %float.neq.loc9: init bool = call %Neq.ref.loc9(%.loc9_21, %.loc9_26) [template = constants.%.9]
+// CHECK:STDOUT: %.loc9_14.1: bool = value_of_initializer %float.neq.loc9 [template = constants.%.9]
+// CHECK:STDOUT: %.loc9_14.2: bool = converted %float.neq.loc9, %.loc9_14.1 [template = constants.%.9]
// CHECK:STDOUT: if %.loc9_14.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc9:
diff --git a/toolchain/check/testdata/builtins/int/eq.carbon b/toolchain/check/testdata/builtins/int/eq.carbon
index 617100b3b910a..fa72169032c12 100644
--- a/toolchain/check/testdata/builtins/int/eq.carbon
+++ b/toolchain/check/testdata/builtins/int/eq.carbon
@@ -45,14 +45,15 @@ fn WrongResult(a: i32, b: i32) -> i32 = "int.eq";
// CHECK:STDOUT: %Eq: %Eq.type = struct_value () [template]
// CHECK:STDOUT: %True: type = class_type @True [template]
// CHECK:STDOUT: %.2: type = struct_type {} [template]
+// CHECK:STDOUT: %.3: = complete_type_witness %.2 [template]
// CHECK:STDOUT: %False: type = class_type @False [template]
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
-// CHECK:STDOUT: %.3: type = ptr_type %.2 [template]
-// CHECK:STDOUT: %.4: i32 = int_literal 1 [template]
-// CHECK:STDOUT: %.5: bool = bool_literal true [template]
-// CHECK:STDOUT: %.6: i32 = int_literal 2 [template]
-// CHECK:STDOUT: %.7: bool = bool_literal false [template]
+// CHECK:STDOUT: %.4: type = ptr_type %.2 [template]
+// CHECK:STDOUT: %.5: i32 = int_literal 1 [template]
+// CHECK:STDOUT: %.6: bool = bool_literal true [template]
+// CHECK:STDOUT: %.7: i32 = int_literal 2 [template]
+// CHECK:STDOUT: %.8: bool = bool_literal false [template]
// CHECK:STDOUT: %RuntimeCall.type: type = fn_type @RuntimeCall [template]
// CHECK:STDOUT: %RuntimeCall: %RuntimeCall.type = struct_value () [template]
// CHECK:STDOUT: }
@@ -129,11 +130,15 @@ fn WrongResult(a: i32, b: i32) -> i32 = "int.eq";
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @True {
+// CHECK:STDOUT: %.loc4: = complete_type_witness %.2 [template = constants.%.3]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%True
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @False {
+// CHECK:STDOUT: %.loc5: = complete_type_witness %.2 [template = constants.%.3]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%False
// CHECK:STDOUT: }
@@ -148,11 +153,11 @@ fn WrongResult(a: i32, b: i32) -> i32 = "int.eq";
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %true_.ref: %True = name_ref true_, %true_
// CHECK:STDOUT: %Eq.ref.loc8: %Eq.type = name_ref Eq, file.%Eq.decl [template = constants.%Eq]
-// CHECK:STDOUT: %.loc8_19: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %.loc8_22: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %int.eq.loc8: init bool = call %Eq.ref.loc8(%.loc8_19, %.loc8_22) [template = constants.%.5]
-// CHECK:STDOUT: %.loc8_13.1: bool = value_of_initializer %int.eq.loc8 [template = constants.%.5]
-// CHECK:STDOUT: %.loc8_13.2: bool = converted %int.eq.loc8, %.loc8_13.1 [template = constants.%.5]
+// CHECK:STDOUT: %.loc8_19: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %.loc8_22: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %int.eq.loc8: init bool = call %Eq.ref.loc8(%.loc8_19, %.loc8_22) [template = constants.%.6]
+// CHECK:STDOUT: %.loc8_13.1: bool = value_of_initializer %int.eq.loc8 [template = constants.%.6]
+// CHECK:STDOUT: %.loc8_13.2: bool = converted %int.eq.loc8, %.loc8_13.1 [template = constants.%.6]
// CHECK:STDOUT: if %.loc8_13.2 br !if.expr.then.loc8 else br !if.expr.else.loc8
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc8:
@@ -167,11 +172,11 @@ fn WrongResult(a: i32, b: i32) -> i32 = "int.eq";
// CHECK:STDOUT: %.loc8_13.3: type = block_arg !if.expr.result.loc8 [template = constants.%True]
// CHECK:STDOUT: %false_.ref: %False = name_ref false_, %false_
// CHECK:STDOUT: %Eq.ref.loc9: %Eq.type = name_ref Eq, file.%Eq.decl [template = constants.%Eq]
-// CHECK:STDOUT: %.loc9_20: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %.loc9_23: i32 = int_literal 2 [template = constants.%.6]
-// CHECK:STDOUT: %int.eq.loc9: init bool = call %Eq.ref.loc9(%.loc9_20, %.loc9_23) [template = constants.%.7]
-// CHECK:STDOUT: %.loc9_14.1: bool = value_of_initializer %int.eq.loc9 [template = constants.%.7]
-// CHECK:STDOUT: %.loc9_14.2: bool = converted %int.eq.loc9, %.loc9_14.1 [template = constants.%.7]
+// CHECK:STDOUT: %.loc9_20: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %.loc9_23: i32 = int_literal 2 [template = constants.%.7]
+// CHECK:STDOUT: %int.eq.loc9: init bool = call %Eq.ref.loc9(%.loc9_20, %.loc9_23) [template = constants.%.8]
+// CHECK:STDOUT: %.loc9_14.1: bool = value_of_initializer %int.eq.loc9 [template = constants.%.8]
+// CHECK:STDOUT: %.loc9_14.2: bool = converted %int.eq.loc9, %.loc9_14.1 [template = constants.%.8]
// CHECK:STDOUT: if %.loc9_14.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc9:
diff --git a/toolchain/check/testdata/builtins/int/greater.carbon b/toolchain/check/testdata/builtins/int/greater.carbon
index f5cf1c6df2995..b1554ad82b9be 100644
--- a/toolchain/check/testdata/builtins/int/greater.carbon
+++ b/toolchain/check/testdata/builtins/int/greater.carbon
@@ -42,16 +42,17 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: %Negate: %Negate.type = struct_value () [template]
// CHECK:STDOUT: %True: type = class_type @True [template]
// CHECK:STDOUT: %.2: type = struct_type {} [template]
+// CHECK:STDOUT: %.3: = complete_type_witness %.2 [template]
// CHECK:STDOUT: %False: type = class_type @False [template]
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
-// CHECK:STDOUT: %.3: type = ptr_type %.2 [template]
-// CHECK:STDOUT: %.4: i32 = int_literal 1 [template]
-// CHECK:STDOUT: %.5: i32 = int_literal 2 [template]
-// CHECK:STDOUT: %.6: bool = bool_literal false [template]
-// CHECK:STDOUT: %.7: i32 = int_literal 0 [template]
-// CHECK:STDOUT: %.8: bool = bool_literal true [template]
-// CHECK:STDOUT: %.9: i32 = int_literal -1 [template]
+// CHECK:STDOUT: %.4: type = ptr_type %.2 [template]
+// CHECK:STDOUT: %.5: i32 = int_literal 1 [template]
+// CHECK:STDOUT: %.6: i32 = int_literal 2 [template]
+// CHECK:STDOUT: %.7: bool = bool_literal false [template]
+// CHECK:STDOUT: %.8: i32 = int_literal 0 [template]
+// CHECK:STDOUT: %.9: bool = bool_literal true [template]
+// CHECK:STDOUT: %.10: i32 = int_literal -1 [template]
// CHECK:STDOUT: %RuntimeCall.type: type = fn_type @RuntimeCall [template]
// CHECK:STDOUT: %RuntimeCall: %RuntimeCall.type = struct_value () [template]
// CHECK:STDOUT: }
@@ -140,11 +141,15 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @True {
+// CHECK:STDOUT: %.loc5: = complete_type_witness %.2 [template = constants.%.3]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%True
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @False {
+// CHECK:STDOUT: %.loc6: = complete_type_witness %.2 [template = constants.%.3]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%False
// CHECK:STDOUT: }
@@ -161,11 +166,11 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %false_.ref.loc9: %False = name_ref false_, %false_
// CHECK:STDOUT: %Greater.ref.loc9: %Greater.type = name_ref Greater, file.%Greater.decl [template = constants.%Greater]
-// CHECK:STDOUT: %.loc9_25: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %.loc9_28: i32 = int_literal 2 [template = constants.%.5]
-// CHECK:STDOUT: %int.greater.loc9: init bool = call %Greater.ref.loc9(%.loc9_25, %.loc9_28) [template = constants.%.6]
-// CHECK:STDOUT: %.loc9_14.1: bool = value_of_initializer %int.greater.loc9 [template = constants.%.6]
-// CHECK:STDOUT: %.loc9_14.2: bool = converted %int.greater.loc9, %.loc9_14.1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc9_25: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %.loc9_28: i32 = int_literal 2 [template = constants.%.6]
+// CHECK:STDOUT: %int.greater.loc9: init bool = call %Greater.ref.loc9(%.loc9_25, %.loc9_28) [template = constants.%.7]
+// CHECK:STDOUT: %.loc9_14.1: bool = value_of_initializer %int.greater.loc9 [template = constants.%.7]
+// CHECK:STDOUT: %.loc9_14.2: bool = converted %int.greater.loc9, %.loc9_14.1 [template = constants.%.7]
// CHECK:STDOUT: if %.loc9_14.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc9:
@@ -180,11 +185,11 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: %.loc9_14.3: type = block_arg !if.expr.result.loc9 [template = constants.%False]
// CHECK:STDOUT: %false_.ref.loc10: %False = name_ref false_, %false_
// CHECK:STDOUT: %Greater.ref.loc10: %Greater.type = name_ref Greater, file.%Greater.decl [template = constants.%Greater]
-// CHECK:STDOUT: %.loc10_25: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %.loc10_28: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %int.greater.loc10: init bool = call %Greater.ref.loc10(%.loc10_25, %.loc10_28) [template = constants.%.6]
-// CHECK:STDOUT: %.loc10_14.1: bool = value_of_initializer %int.greater.loc10 [template = constants.%.6]
-// CHECK:STDOUT: %.loc10_14.2: bool = converted %int.greater.loc10, %.loc10_14.1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc10_25: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %.loc10_28: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %int.greater.loc10: init bool = call %Greater.ref.loc10(%.loc10_25, %.loc10_28) [template = constants.%.7]
+// CHECK:STDOUT: %.loc10_14.1: bool = value_of_initializer %int.greater.loc10 [template = constants.%.7]
+// CHECK:STDOUT: %.loc10_14.2: bool = converted %int.greater.loc10, %.loc10_14.1 [template = constants.%.7]
// CHECK:STDOUT: if %.loc10_14.2 br !if.expr.then.loc10 else br !if.expr.else.loc10
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc10:
@@ -199,11 +204,11 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: %.loc10_14.3: type = block_arg !if.expr.result.loc10 [template = constants.%False]
// CHECK:STDOUT: %true_.ref.loc11: %True = name_ref true_, %true_
// CHECK:STDOUT: %Greater.ref.loc11: %Greater.type = name_ref Greater, file.%Greater.decl [template = constants.%Greater]
-// CHECK:STDOUT: %.loc11_24: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %.loc11_27: i32 = int_literal 0 [template = constants.%.7]
-// CHECK:STDOUT: %int.greater.loc11: init bool = call %Greater.ref.loc11(%.loc11_24, %.loc11_27) [template = constants.%.8]
-// CHECK:STDOUT: %.loc11_13.1: bool = value_of_initializer %int.greater.loc11 [template = constants.%.8]
-// CHECK:STDOUT: %.loc11_13.2: bool = converted %int.greater.loc11, %.loc11_13.1 [template = constants.%.8]
+// CHECK:STDOUT: %.loc11_24: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %.loc11_27: i32 = int_literal 0 [template = constants.%.8]
+// CHECK:STDOUT: %int.greater.loc11: init bool = call %Greater.ref.loc11(%.loc11_24, %.loc11_27) [template = constants.%.9]
+// CHECK:STDOUT: %.loc11_13.1: bool = value_of_initializer %int.greater.loc11 [template = constants.%.9]
+// CHECK:STDOUT: %.loc11_13.2: bool = converted %int.greater.loc11, %.loc11_13.1 [template = constants.%.9]
// CHECK:STDOUT: if %.loc11_13.2 br !if.expr.then.loc11 else br !if.expr.else.loc11
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc11:
@@ -219,14 +224,14 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: %false_.ref.loc12: %False = name_ref false_, %false_
// CHECK:STDOUT: %Greater.ref.loc12: %Greater.type = name_ref Greater, file.%Greater.decl [template = constants.%Greater]
// CHECK:STDOUT: %Negate.ref.loc12: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT: %.loc12_32: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_32) [template = constants.%.9]
-// CHECK:STDOUT: %.loc12_36: i32 = int_literal 0 [template = constants.%.7]
-// CHECK:STDOUT: %.loc12_24.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.9]
-// CHECK:STDOUT: %.loc12_24.2: i32 = converted %int.snegate.loc12, %.loc12_24.1 [template = constants.%.9]
-// CHECK:STDOUT: %int.greater.loc12: init bool = call %Greater.ref.loc12(%.loc12_24.2, %.loc12_36) [template = constants.%.6]
-// CHECK:STDOUT: %.loc12_14.1: bool = value_of_initializer %int.greater.loc12 [template = constants.%.6]
-// CHECK:STDOUT: %.loc12_14.2: bool = converted %int.greater.loc12, %.loc12_14.1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc12_32: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_32) [template = constants.%.10]
+// CHECK:STDOUT: %.loc12_36: i32 = int_literal 0 [template = constants.%.8]
+// CHECK:STDOUT: %.loc12_24.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.10]
+// CHECK:STDOUT: %.loc12_24.2: i32 = converted %int.snegate.loc12, %.loc12_24.1 [template = constants.%.10]
+// CHECK:STDOUT: %int.greater.loc12: init bool = call %Greater.ref.loc12(%.loc12_24.2, %.loc12_36) [template = constants.%.7]
+// CHECK:STDOUT: %.loc12_14.1: bool = value_of_initializer %int.greater.loc12 [template = constants.%.7]
+// CHECK:STDOUT: %.loc12_14.2: bool = converted %int.greater.loc12, %.loc12_14.1 [template = constants.%.7]
// CHECK:STDOUT: if %.loc12_14.2 br !if.expr.then.loc12 else br !if.expr.else.loc12
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc12:
@@ -241,15 +246,15 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: %.loc12_14.3: type = block_arg !if.expr.result.loc12 [template = constants.%False]
// CHECK:STDOUT: %true_.ref.loc13: %True = name_ref true_, %true_
// CHECK:STDOUT: %Greater.ref.loc13: %Greater.type = name_ref Greater, file.%Greater.decl [template = constants.%Greater]
-// CHECK:STDOUT: %.loc13_24: i32 = int_literal 0 [template = constants.%.7]
+// CHECK:STDOUT: %.loc13_24: i32 = int_literal 0 [template = constants.%.8]
// CHECK:STDOUT: %Negate.ref.loc13: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT: %.loc13_34: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %int.snegate.loc13: init i32 = call %Negate.ref.loc13(%.loc13_34) [template = constants.%.9]
-// CHECK:STDOUT: %.loc13_23.1: i32 = value_of_initializer %int.snegate.loc13 [template = constants.%.9]
-// CHECK:STDOUT: %.loc13_23.2: i32 = converted %int.snegate.loc13, %.loc13_23.1 [template = constants.%.9]
-// CHECK:STDOUT: %int.greater.loc13: init bool = call %Greater.ref.loc13(%.loc13_24, %.loc13_23.2) [template = constants.%.8]
-// CHECK:STDOUT: %.loc13_13.1: bool = value_of_initializer %int.greater.loc13 [template = constants.%.8]
-// CHECK:STDOUT: %.loc13_13.2: bool = converted %int.greater.loc13, %.loc13_13.1 [template = constants.%.8]
+// CHECK:STDOUT: %.loc13_34: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %int.snegate.loc13: init i32 = call %Negate.ref.loc13(%.loc13_34) [template = constants.%.10]
+// CHECK:STDOUT: %.loc13_23.1: i32 = value_of_initializer %int.snegate.loc13 [template = constants.%.10]
+// CHECK:STDOUT: %.loc13_23.2: i32 = converted %int.snegate.loc13, %.loc13_23.1 [template = constants.%.10]
+// CHECK:STDOUT: %int.greater.loc13: init bool = call %Greater.ref.loc13(%.loc13_24, %.loc13_23.2) [template = constants.%.9]
+// CHECK:STDOUT: %.loc13_13.1: bool = value_of_initializer %int.greater.loc13 [template = constants.%.9]
+// CHECK:STDOUT: %.loc13_13.2: bool = converted %int.greater.loc13, %.loc13_13.1 [template = constants.%.9]
// CHECK:STDOUT: if %.loc13_13.2 br !if.expr.then.loc13 else br !if.expr.else.loc13
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc13:
diff --git a/toolchain/check/testdata/builtins/int/greater_eq.carbon b/toolchain/check/testdata/builtins/int/greater_eq.carbon
index b266c0a3a074f..fff5948a45862 100644
--- a/toolchain/check/testdata/builtins/int/greater_eq.carbon
+++ b/toolchain/check/testdata/builtins/int/greater_eq.carbon
@@ -42,16 +42,17 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: %Negate: %Negate.type = struct_value () [template]
// CHECK:STDOUT: %True: type = class_type @True [template]
// CHECK:STDOUT: %.2: type = struct_type {} [template]
+// CHECK:STDOUT: %.3: = complete_type_witness %.2 [template]
// CHECK:STDOUT: %False: type = class_type @False [template]
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
-// CHECK:STDOUT: %.3: type = ptr_type %.2 [template]
-// CHECK:STDOUT: %.4: i32 = int_literal 1 [template]
-// CHECK:STDOUT: %.5: i32 = int_literal 2 [template]
-// CHECK:STDOUT: %.6: bool = bool_literal false [template]
-// CHECK:STDOUT: %.7: bool = bool_literal true [template]
-// CHECK:STDOUT: %.8: i32 = int_literal 0 [template]
-// CHECK:STDOUT: %.9: i32 = int_literal -1 [template]
+// CHECK:STDOUT: %.4: type = ptr_type %.2 [template]
+// CHECK:STDOUT: %.5: i32 = int_literal 1 [template]
+// CHECK:STDOUT: %.6: i32 = int_literal 2 [template]
+// CHECK:STDOUT: %.7: bool = bool_literal false [template]
+// CHECK:STDOUT: %.8: bool = bool_literal true [template]
+// CHECK:STDOUT: %.9: i32 = int_literal 0 [template]
+// CHECK:STDOUT: %.10: i32 = int_literal -1 [template]
// CHECK:STDOUT: %RuntimeCall.type: type = fn_type @RuntimeCall [template]
// CHECK:STDOUT: %RuntimeCall: %RuntimeCall.type = struct_value () [template]
// CHECK:STDOUT: }
@@ -140,11 +141,15 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @True {
+// CHECK:STDOUT: %.loc5: = complete_type_witness %.2 [template = constants.%.3]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%True
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @False {
+// CHECK:STDOUT: %.loc6: = complete_type_witness %.2 [template = constants.%.3]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%False
// CHECK:STDOUT: }
@@ -161,11 +166,11 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %false_.ref.loc9: %False = name_ref false_, %false_
// CHECK:STDOUT: %GreaterEq.ref.loc9: %GreaterEq.type = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%GreaterEq]
-// CHECK:STDOUT: %.loc9_27: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %.loc9_30: i32 = int_literal 2 [template = constants.%.5]
-// CHECK:STDOUT: %int.greater_eq.loc9: init bool = call %GreaterEq.ref.loc9(%.loc9_27, %.loc9_30) [template = constants.%.6]
-// CHECK:STDOUT: %.loc9_14.1: bool = value_of_initializer %int.greater_eq.loc9 [template = constants.%.6]
-// CHECK:STDOUT: %.loc9_14.2: bool = converted %int.greater_eq.loc9, %.loc9_14.1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc9_27: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %.loc9_30: i32 = int_literal 2 [template = constants.%.6]
+// CHECK:STDOUT: %int.greater_eq.loc9: init bool = call %GreaterEq.ref.loc9(%.loc9_27, %.loc9_30) [template = constants.%.7]
+// CHECK:STDOUT: %.loc9_14.1: bool = value_of_initializer %int.greater_eq.loc9 [template = constants.%.7]
+// CHECK:STDOUT: %.loc9_14.2: bool = converted %int.greater_eq.loc9, %.loc9_14.1 [template = constants.%.7]
// CHECK:STDOUT: if %.loc9_14.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc9:
@@ -180,11 +185,11 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: %.loc9_14.3: type = block_arg !if.expr.result.loc9 [template = constants.%False]
// CHECK:STDOUT: %true_.ref.loc10: %True = name_ref true_, %true_
// CHECK:STDOUT: %GreaterEq.ref.loc10: %GreaterEq.type = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%GreaterEq]
-// CHECK:STDOUT: %.loc10_26: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %.loc10_29: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %int.greater_eq.loc10: init bool = call %GreaterEq.ref.loc10(%.loc10_26, %.loc10_29) [template = constants.%.7]
-// CHECK:STDOUT: %.loc10_13.1: bool = value_of_initializer %int.greater_eq.loc10 [template = constants.%.7]
-// CHECK:STDOUT: %.loc10_13.2: bool = converted %int.greater_eq.loc10, %.loc10_13.1 [template = constants.%.7]
+// CHECK:STDOUT: %.loc10_26: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %.loc10_29: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %int.greater_eq.loc10: init bool = call %GreaterEq.ref.loc10(%.loc10_26, %.loc10_29) [template = constants.%.8]
+// CHECK:STDOUT: %.loc10_13.1: bool = value_of_initializer %int.greater_eq.loc10 [template = constants.%.8]
+// CHECK:STDOUT: %.loc10_13.2: bool = converted %int.greater_eq.loc10, %.loc10_13.1 [template = constants.%.8]
// CHECK:STDOUT: if %.loc10_13.2 br !if.expr.then.loc10 else br !if.expr.else.loc10
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc10:
@@ -199,11 +204,11 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: %.loc10_13.3: type = block_arg !if.expr.result.loc10 [template = constants.%True]
// CHECK:STDOUT: %true_.ref.loc11: %True = name_ref true_, %true_
// CHECK:STDOUT: %GreaterEq.ref.loc11: %GreaterEq.type = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%GreaterEq]
-// CHECK:STDOUT: %.loc11_26: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %.loc11_29: i32 = int_literal 0 [template = constants.%.8]
-// CHECK:STDOUT: %int.greater_eq.loc11: init bool = call %GreaterEq.ref.loc11(%.loc11_26, %.loc11_29) [template = constants.%.7]
-// CHECK:STDOUT: %.loc11_13.1: bool = value_of_initializer %int.greater_eq.loc11 [template = constants.%.7]
-// CHECK:STDOUT: %.loc11_13.2: bool = converted %int.greater_eq.loc11, %.loc11_13.1 [template = constants.%.7]
+// CHECK:STDOUT: %.loc11_26: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %.loc11_29: i32 = int_literal 0 [template = constants.%.9]
+// CHECK:STDOUT: %int.greater_eq.loc11: init bool = call %GreaterEq.ref.loc11(%.loc11_26, %.loc11_29) [template = constants.%.8]
+// CHECK:STDOUT: %.loc11_13.1: bool = value_of_initializer %int.greater_eq.loc11 [template = constants.%.8]
+// CHECK:STDOUT: %.loc11_13.2: bool = converted %int.greater_eq.loc11, %.loc11_13.1 [template = constants.%.8]
// CHECK:STDOUT: if %.loc11_13.2 br !if.expr.then.loc11 else br !if.expr.else.loc11
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc11:
@@ -219,14 +224,14 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: %false_.ref.loc12: %False = name_ref false_, %false_
// CHECK:STDOUT: %GreaterEq.ref.loc12: %GreaterEq.type = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%GreaterEq]
// CHECK:STDOUT: %Negate.ref.loc12: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT: %.loc12_34: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_34) [template = constants.%.9]
-// CHECK:STDOUT: %.loc12_38: i32 = int_literal 0 [template = constants.%.8]
-// CHECK:STDOUT: %.loc12_26.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.9]
-// CHECK:STDOUT: %.loc12_26.2: i32 = converted %int.snegate.loc12, %.loc12_26.1 [template = constants.%.9]
-// CHECK:STDOUT: %int.greater_eq.loc12: init bool = call %GreaterEq.ref.loc12(%.loc12_26.2, %.loc12_38) [template = constants.%.6]
-// CHECK:STDOUT: %.loc12_14.1: bool = value_of_initializer %int.greater_eq.loc12 [template = constants.%.6]
-// CHECK:STDOUT: %.loc12_14.2: bool = converted %int.greater_eq.loc12, %.loc12_14.1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc12_34: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_34) [template = constants.%.10]
+// CHECK:STDOUT: %.loc12_38: i32 = int_literal 0 [template = constants.%.9]
+// CHECK:STDOUT: %.loc12_26.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.10]
+// CHECK:STDOUT: %.loc12_26.2: i32 = converted %int.snegate.loc12, %.loc12_26.1 [template = constants.%.10]
+// CHECK:STDOUT: %int.greater_eq.loc12: init bool = call %GreaterEq.ref.loc12(%.loc12_26.2, %.loc12_38) [template = constants.%.7]
+// CHECK:STDOUT: %.loc12_14.1: bool = value_of_initializer %int.greater_eq.loc12 [template = constants.%.7]
+// CHECK:STDOUT: %.loc12_14.2: bool = converted %int.greater_eq.loc12, %.loc12_14.1 [template = constants.%.7]
// CHECK:STDOUT: if %.loc12_14.2 br !if.expr.then.loc12 else br !if.expr.else.loc12
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc12:
@@ -241,15 +246,15 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: %.loc12_14.3: type = block_arg !if.expr.result.loc12 [template = constants.%False]
// CHECK:STDOUT: %true_.ref.loc13: %True = name_ref true_, %true_
// CHECK:STDOUT: %GreaterEq.ref.loc13: %GreaterEq.type = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%GreaterEq]
-// CHECK:STDOUT: %.loc13_26: i32 = int_literal 0 [template = constants.%.8]
+// CHECK:STDOUT: %.loc13_26: i32 = int_literal 0 [template = constants.%.9]
// CHECK:STDOUT: %Negate.ref.loc13: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT: %.loc13_36: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %int.snegate.loc13: init i32 = call %Negate.ref.loc13(%.loc13_36) [template = constants.%.9]
-// CHECK:STDOUT: %.loc13_25.1: i32 = value_of_initializer %int.snegate.loc13 [template = constants.%.9]
-// CHECK:STDOUT: %.loc13_25.2: i32 = converted %int.snegate.loc13, %.loc13_25.1 [template = constants.%.9]
-// CHECK:STDOUT: %int.greater_eq.loc13: init bool = call %GreaterEq.ref.loc13(%.loc13_26, %.loc13_25.2) [template = constants.%.7]
-// CHECK:STDOUT: %.loc13_13.1: bool = value_of_initializer %int.greater_eq.loc13 [template = constants.%.7]
-// CHECK:STDOUT: %.loc13_13.2: bool = converted %int.greater_eq.loc13, %.loc13_13.1 [template = constants.%.7]
+// CHECK:STDOUT: %.loc13_36: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %int.snegate.loc13: init i32 = call %Negate.ref.loc13(%.loc13_36) [template = constants.%.10]
+// CHECK:STDOUT: %.loc13_25.1: i32 = value_of_initializer %int.snegate.loc13 [template = constants.%.10]
+// CHECK:STDOUT: %.loc13_25.2: i32 = converted %int.snegate.loc13, %.loc13_25.1 [template = constants.%.10]
+// CHECK:STDOUT: %int.greater_eq.loc13: init bool = call %GreaterEq.ref.loc13(%.loc13_26, %.loc13_25.2) [template = constants.%.8]
+// CHECK:STDOUT: %.loc13_13.1: bool = value_of_initializer %int.greater_eq.loc13 [template = constants.%.8]
+// CHECK:STDOUT: %.loc13_13.2: bool = converted %int.greater_eq.loc13, %.loc13_13.1 [template = constants.%.8]
// CHECK:STDOUT: if %.loc13_13.2 br !if.expr.then.loc13 else br !if.expr.else.loc13
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc13:
diff --git a/toolchain/check/testdata/builtins/int/less.carbon b/toolchain/check/testdata/builtins/int/less.carbon
index 729c6402c7ff9..24e50e9d9c1f6 100644
--- a/toolchain/check/testdata/builtins/int/less.carbon
+++ b/toolchain/check/testdata/builtins/int/less.carbon
@@ -42,16 +42,17 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: %Negate: %Negate.type = struct_value () [template]
// CHECK:STDOUT: %True: type = class_type @True [template]
// CHECK:STDOUT: %.2: type = struct_type {} [template]
+// CHECK:STDOUT: %.3: = complete_type_witness %.2 [template]
// CHECK:STDOUT: %False: type = class_type @False [template]
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
-// CHECK:STDOUT: %.3: type = ptr_type %.2 [template]
-// CHECK:STDOUT: %.4: i32 = int_literal 1 [template]
-// CHECK:STDOUT: %.5: i32 = int_literal 2 [template]
-// CHECK:STDOUT: %.6: bool = bool_literal true [template]
-// CHECK:STDOUT: %.7: bool = bool_literal false [template]
-// CHECK:STDOUT: %.8: i32 = int_literal 0 [template]
-// CHECK:STDOUT: %.9: i32 = int_literal -1 [template]
+// CHECK:STDOUT: %.4: type = ptr_type %.2 [template]
+// CHECK:STDOUT: %.5: i32 = int_literal 1 [template]
+// CHECK:STDOUT: %.6: i32 = int_literal 2 [template]
+// CHECK:STDOUT: %.7: bool = bool_literal true [template]
+// CHECK:STDOUT: %.8: bool = bool_literal false [template]
+// CHECK:STDOUT: %.9: i32 = int_literal 0 [template]
+// CHECK:STDOUT: %.10: i32 = int_literal -1 [template]
// CHECK:STDOUT: %RuntimeCall.type: type = fn_type @RuntimeCall [template]
// CHECK:STDOUT: %RuntimeCall: %RuntimeCall.type = struct_value () [template]
// CHECK:STDOUT: }
@@ -140,11 +141,15 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @True {
+// CHECK:STDOUT: %.loc5: = complete_type_witness %.2 [template = constants.%.3]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%True
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @False {
+// CHECK:STDOUT: %.loc6: = complete_type_witness %.2 [template = constants.%.3]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%False
// CHECK:STDOUT: }
@@ -161,11 +166,11 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %true_.ref.loc9: %True = name_ref true_, %true_
// CHECK:STDOUT: %Less.ref.loc9: %Less.type = name_ref Less, file.%Less.decl [template = constants.%Less]
-// CHECK:STDOUT: %.loc9_21: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %.loc9_24: i32 = int_literal 2 [template = constants.%.5]
-// CHECK:STDOUT: %int.less.loc9: init bool = call %Less.ref.loc9(%.loc9_21, %.loc9_24) [template = constants.%.6]
-// CHECK:STDOUT: %.loc9_13.1: bool = value_of_initializer %int.less.loc9 [template = constants.%.6]
-// CHECK:STDOUT: %.loc9_13.2: bool = converted %int.less.loc9, %.loc9_13.1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc9_21: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %.loc9_24: i32 = int_literal 2 [template = constants.%.6]
+// CHECK:STDOUT: %int.less.loc9: init bool = call %Less.ref.loc9(%.loc9_21, %.loc9_24) [template = constants.%.7]
+// CHECK:STDOUT: %.loc9_13.1: bool = value_of_initializer %int.less.loc9 [template = constants.%.7]
+// CHECK:STDOUT: %.loc9_13.2: bool = converted %int.less.loc9, %.loc9_13.1 [template = constants.%.7]
// CHECK:STDOUT: if %.loc9_13.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc9:
@@ -180,11 +185,11 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: %.loc9_13.3: type = block_arg !if.expr.result.loc9 [template = constants.%True]
// CHECK:STDOUT: %false_.ref.loc10: %False = name_ref false_, %false_
// CHECK:STDOUT: %Less.ref.loc10: %Less.type = name_ref Less, file.%Less.decl [template = constants.%Less]
-// CHECK:STDOUT: %.loc10_22: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %.loc10_25: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %int.less.loc10: init bool = call %Less.ref.loc10(%.loc10_22, %.loc10_25) [template = constants.%.7]
-// CHECK:STDOUT: %.loc10_14.1: bool = value_of_initializer %int.less.loc10 [template = constants.%.7]
-// CHECK:STDOUT: %.loc10_14.2: bool = converted %int.less.loc10, %.loc10_14.1 [template = constants.%.7]
+// CHECK:STDOUT: %.loc10_22: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %.loc10_25: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %int.less.loc10: init bool = call %Less.ref.loc10(%.loc10_22, %.loc10_25) [template = constants.%.8]
+// CHECK:STDOUT: %.loc10_14.1: bool = value_of_initializer %int.less.loc10 [template = constants.%.8]
+// CHECK:STDOUT: %.loc10_14.2: bool = converted %int.less.loc10, %.loc10_14.1 [template = constants.%.8]
// CHECK:STDOUT: if %.loc10_14.2 br !if.expr.then.loc10 else br !if.expr.else.loc10
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc10:
@@ -199,11 +204,11 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: %.loc10_14.3: type = block_arg !if.expr.result.loc10 [template = constants.%False]
// CHECK:STDOUT: %false_.ref.loc11: %False = name_ref false_, %false_
// CHECK:STDOUT: %Less.ref.loc11: %Less.type = name_ref Less, file.%Less.decl [template = constants.%Less]
-// CHECK:STDOUT: %.loc11_22: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %.loc11_25: i32 = int_literal 0 [template = constants.%.8]
-// CHECK:STDOUT: %int.less.loc11: init bool = call %Less.ref.loc11(%.loc11_22, %.loc11_25) [template = constants.%.7]
-// CHECK:STDOUT: %.loc11_14.1: bool = value_of_initializer %int.less.loc11 [template = constants.%.7]
-// CHECK:STDOUT: %.loc11_14.2: bool = converted %int.less.loc11, %.loc11_14.1 [template = constants.%.7]
+// CHECK:STDOUT: %.loc11_22: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %.loc11_25: i32 = int_literal 0 [template = constants.%.9]
+// CHECK:STDOUT: %int.less.loc11: init bool = call %Less.ref.loc11(%.loc11_22, %.loc11_25) [template = constants.%.8]
+// CHECK:STDOUT: %.loc11_14.1: bool = value_of_initializer %int.less.loc11 [template = constants.%.8]
+// CHECK:STDOUT: %.loc11_14.2: bool = converted %int.less.loc11, %.loc11_14.1 [template = constants.%.8]
// CHECK:STDOUT: if %.loc11_14.2 br !if.expr.then.loc11 else br !if.expr.else.loc11
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc11:
@@ -219,14 +224,14 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: %true_.ref.loc12: %True = name_ref true_, %true_
// CHECK:STDOUT: %Less.ref.loc12: %Less.type = name_ref Less, file.%Less.decl [template = constants.%Less]
// CHECK:STDOUT: %Negate.ref.loc12: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT: %.loc12_28: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_28) [template = constants.%.9]
-// CHECK:STDOUT: %.loc12_32: i32 = int_literal 0 [template = constants.%.8]
-// CHECK:STDOUT: %.loc12_20.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.9]
-// CHECK:STDOUT: %.loc12_20.2: i32 = converted %int.snegate.loc12, %.loc12_20.1 [template = constants.%.9]
-// CHECK:STDOUT: %int.less.loc12: init bool = call %Less.ref.loc12(%.loc12_20.2, %.loc12_32) [template = constants.%.6]
-// CHECK:STDOUT: %.loc12_13.1: bool = value_of_initializer %int.less.loc12 [template = constants.%.6]
-// CHECK:STDOUT: %.loc12_13.2: bool = converted %int.less.loc12, %.loc12_13.1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc12_28: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_28) [template = constants.%.10]
+// CHECK:STDOUT: %.loc12_32: i32 = int_literal 0 [template = constants.%.9]
+// CHECK:STDOUT: %.loc12_20.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.10]
+// CHECK:STDOUT: %.loc12_20.2: i32 = converted %int.snegate.loc12, %.loc12_20.1 [template = constants.%.10]
+// CHECK:STDOUT: %int.less.loc12: init bool = call %Less.ref.loc12(%.loc12_20.2, %.loc12_32) [template = constants.%.7]
+// CHECK:STDOUT: %.loc12_13.1: bool = value_of_initializer %int.less.loc12 [template = constants.%.7]
+// CHECK:STDOUT: %.loc12_13.2: bool = converted %int.less.loc12, %.loc12_13.1 [template = constants.%.7]
// CHECK:STDOUT: if %.loc12_13.2 br !if.expr.then.loc12 else br !if.expr.else.loc12
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc12:
@@ -241,15 +246,15 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: %.loc12_13.3: type = block_arg !if.expr.result.loc12 [template = constants.%True]
// CHECK:STDOUT: %false_.ref.loc13: %False = name_ref false_, %false_
// CHECK:STDOUT: %Less.ref.loc13: %Less.type = name_ref Less, file.%Less.decl [template = constants.%Less]
-// CHECK:STDOUT: %.loc13_22: i32 = int_literal 0 [template = constants.%.8]
+// CHECK:STDOUT: %.loc13_22: i32 = int_literal 0 [template = constants.%.9]
// CHECK:STDOUT: %Negate.ref.loc13: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT: %.loc13_32: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %int.snegate.loc13: init i32 = call %Negate.ref.loc13(%.loc13_32) [template = constants.%.9]
-// CHECK:STDOUT: %.loc13_21.1: i32 = value_of_initializer %int.snegate.loc13 [template = constants.%.9]
-// CHECK:STDOUT: %.loc13_21.2: i32 = converted %int.snegate.loc13, %.loc13_21.1 [template = constants.%.9]
-// CHECK:STDOUT: %int.less.loc13: init bool = call %Less.ref.loc13(%.loc13_22, %.loc13_21.2) [template = constants.%.7]
-// CHECK:STDOUT: %.loc13_14.1: bool = value_of_initializer %int.less.loc13 [template = constants.%.7]
-// CHECK:STDOUT: %.loc13_14.2: bool = converted %int.less.loc13, %.loc13_14.1 [template = constants.%.7]
+// CHECK:STDOUT: %.loc13_32: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %int.snegate.loc13: init i32 = call %Negate.ref.loc13(%.loc13_32) [template = constants.%.10]
+// CHECK:STDOUT: %.loc13_21.1: i32 = value_of_initializer %int.snegate.loc13 [template = constants.%.10]
+// CHECK:STDOUT: %.loc13_21.2: i32 = converted %int.snegate.loc13, %.loc13_21.1 [template = constants.%.10]
+// CHECK:STDOUT: %int.less.loc13: init bool = call %Less.ref.loc13(%.loc13_22, %.loc13_21.2) [template = constants.%.8]
+// CHECK:STDOUT: %.loc13_14.1: bool = value_of_initializer %int.less.loc13 [template = constants.%.8]
+// CHECK:STDOUT: %.loc13_14.2: bool = converted %int.less.loc13, %.loc13_14.1 [template = constants.%.8]
// CHECK:STDOUT: if %.loc13_14.2 br !if.expr.then.loc13 else br !if.expr.else.loc13
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc13:
diff --git a/toolchain/check/testdata/builtins/int/less_eq.carbon b/toolchain/check/testdata/builtins/int/less_eq.carbon
index 0f543b38db8d7..ffd516ca3b78c 100644
--- a/toolchain/check/testdata/builtins/int/less_eq.carbon
+++ b/toolchain/check/testdata/builtins/int/less_eq.carbon
@@ -42,16 +42,17 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: %Negate: %Negate.type = struct_value () [template]
// CHECK:STDOUT: %True: type = class_type @True [template]
// CHECK:STDOUT: %.2: type = struct_type {} [template]
+// CHECK:STDOUT: %.3: = complete_type_witness %.2 [template]
// CHECK:STDOUT: %False: type = class_type @False [template]
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
-// CHECK:STDOUT: %.3: type = ptr_type %.2 [template]
-// CHECK:STDOUT: %.4: i32 = int_literal 1 [template]
-// CHECK:STDOUT: %.5: i32 = int_literal 2 [template]
-// CHECK:STDOUT: %.6: bool = bool_literal true [template]
-// CHECK:STDOUT: %.7: i32 = int_literal 0 [template]
-// CHECK:STDOUT: %.8: bool = bool_literal false [template]
-// CHECK:STDOUT: %.9: i32 = int_literal -1 [template]
+// CHECK:STDOUT: %.4: type = ptr_type %.2 [template]
+// CHECK:STDOUT: %.5: i32 = int_literal 1 [template]
+// CHECK:STDOUT: %.6: i32 = int_literal 2 [template]
+// CHECK:STDOUT: %.7: bool = bool_literal true [template]
+// CHECK:STDOUT: %.8: i32 = int_literal 0 [template]
+// CHECK:STDOUT: %.9: bool = bool_literal false [template]
+// CHECK:STDOUT: %.10: i32 = int_literal -1 [template]
// CHECK:STDOUT: %RuntimeCall.type: type = fn_type @RuntimeCall [template]
// CHECK:STDOUT: %RuntimeCall: %RuntimeCall.type = struct_value () [template]
// CHECK:STDOUT: }
@@ -140,11 +141,15 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @True {
+// CHECK:STDOUT: %.loc5: = complete_type_witness %.2 [template = constants.%.3]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%True
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @False {
+// CHECK:STDOUT: %.loc6: = complete_type_witness %.2 [template = constants.%.3]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%False
// CHECK:STDOUT: }
@@ -161,11 +166,11 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %true_.ref.loc9: %True = name_ref true_, %true_
// CHECK:STDOUT: %LessEq.ref.loc9: %LessEq.type = name_ref LessEq, file.%LessEq.decl [template = constants.%LessEq]
-// CHECK:STDOUT: %.loc9_23: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %.loc9_26: i32 = int_literal 2 [template = constants.%.5]
-// CHECK:STDOUT: %int.less_eq.loc9: init bool = call %LessEq.ref.loc9(%.loc9_23, %.loc9_26) [template = constants.%.6]
-// CHECK:STDOUT: %.loc9_13.1: bool = value_of_initializer %int.less_eq.loc9 [template = constants.%.6]
-// CHECK:STDOUT: %.loc9_13.2: bool = converted %int.less_eq.loc9, %.loc9_13.1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc9_23: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %.loc9_26: i32 = int_literal 2 [template = constants.%.6]
+// CHECK:STDOUT: %int.less_eq.loc9: init bool = call %LessEq.ref.loc9(%.loc9_23, %.loc9_26) [template = constants.%.7]
+// CHECK:STDOUT: %.loc9_13.1: bool = value_of_initializer %int.less_eq.loc9 [template = constants.%.7]
+// CHECK:STDOUT: %.loc9_13.2: bool = converted %int.less_eq.loc9, %.loc9_13.1 [template = constants.%.7]
// CHECK:STDOUT: if %.loc9_13.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc9:
@@ -180,11 +185,11 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: %.loc9_13.3: type = block_arg !if.expr.result.loc9 [template = constants.%True]
// CHECK:STDOUT: %true_.ref.loc10: %True = name_ref true_, %true_
// CHECK:STDOUT: %LessEq.ref.loc10: %LessEq.type = name_ref LessEq, file.%LessEq.decl [template = constants.%LessEq]
-// CHECK:STDOUT: %.loc10_23: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %.loc10_26: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %int.less_eq.loc10: init bool = call %LessEq.ref.loc10(%.loc10_23, %.loc10_26) [template = constants.%.6]
-// CHECK:STDOUT: %.loc10_13.1: bool = value_of_initializer %int.less_eq.loc10 [template = constants.%.6]
-// CHECK:STDOUT: %.loc10_13.2: bool = converted %int.less_eq.loc10, %.loc10_13.1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc10_23: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %.loc10_26: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %int.less_eq.loc10: init bool = call %LessEq.ref.loc10(%.loc10_23, %.loc10_26) [template = constants.%.7]
+// CHECK:STDOUT: %.loc10_13.1: bool = value_of_initializer %int.less_eq.loc10 [template = constants.%.7]
+// CHECK:STDOUT: %.loc10_13.2: bool = converted %int.less_eq.loc10, %.loc10_13.1 [template = constants.%.7]
// CHECK:STDOUT: if %.loc10_13.2 br !if.expr.then.loc10 else br !if.expr.else.loc10
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc10:
@@ -199,11 +204,11 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: %.loc10_13.3: type = block_arg !if.expr.result.loc10 [template = constants.%True]
// CHECK:STDOUT: %false_.ref.loc11: %False = name_ref false_, %false_
// CHECK:STDOUT: %LessEq.ref.loc11: %LessEq.type = name_ref LessEq, file.%LessEq.decl [template = constants.%LessEq]
-// CHECK:STDOUT: %.loc11_24: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %.loc11_27: i32 = int_literal 0 [template = constants.%.7]
-// CHECK:STDOUT: %int.less_eq.loc11: init bool = call %LessEq.ref.loc11(%.loc11_24, %.loc11_27) [template = constants.%.8]
-// CHECK:STDOUT: %.loc11_14.1: bool = value_of_initializer %int.less_eq.loc11 [template = constants.%.8]
-// CHECK:STDOUT: %.loc11_14.2: bool = converted %int.less_eq.loc11, %.loc11_14.1 [template = constants.%.8]
+// CHECK:STDOUT: %.loc11_24: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %.loc11_27: i32 = int_literal 0 [template = constants.%.8]
+// CHECK:STDOUT: %int.less_eq.loc11: init bool = call %LessEq.ref.loc11(%.loc11_24, %.loc11_27) [template = constants.%.9]
+// CHECK:STDOUT: %.loc11_14.1: bool = value_of_initializer %int.less_eq.loc11 [template = constants.%.9]
+// CHECK:STDOUT: %.loc11_14.2: bool = converted %int.less_eq.loc11, %.loc11_14.1 [template = constants.%.9]
// CHECK:STDOUT: if %.loc11_14.2 br !if.expr.then.loc11 else br !if.expr.else.loc11
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc11:
@@ -219,14 +224,14 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: %true_.ref.loc12: %True = name_ref true_, %true_
// CHECK:STDOUT: %LessEq.ref.loc12: %LessEq.type = name_ref LessEq, file.%LessEq.decl [template = constants.%LessEq]
// CHECK:STDOUT: %Negate.ref.loc12: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT: %.loc12_30: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_30) [template = constants.%.9]
-// CHECK:STDOUT: %.loc12_34: i32 = int_literal 0 [template = constants.%.7]
-// CHECK:STDOUT: %.loc12_22.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.9]
-// CHECK:STDOUT: %.loc12_22.2: i32 = converted %int.snegate.loc12, %.loc12_22.1 [template = constants.%.9]
-// CHECK:STDOUT: %int.less_eq.loc12: init bool = call %LessEq.ref.loc12(%.loc12_22.2, %.loc12_34) [template = constants.%.6]
-// CHECK:STDOUT: %.loc12_13.1: bool = value_of_initializer %int.less_eq.loc12 [template = constants.%.6]
-// CHECK:STDOUT: %.loc12_13.2: bool = converted %int.less_eq.loc12, %.loc12_13.1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc12_30: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_30) [template = constants.%.10]
+// CHECK:STDOUT: %.loc12_34: i32 = int_literal 0 [template = constants.%.8]
+// CHECK:STDOUT: %.loc12_22.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.10]
+// CHECK:STDOUT: %.loc12_22.2: i32 = converted %int.snegate.loc12, %.loc12_22.1 [template = constants.%.10]
+// CHECK:STDOUT: %int.less_eq.loc12: init bool = call %LessEq.ref.loc12(%.loc12_22.2, %.loc12_34) [template = constants.%.7]
+// CHECK:STDOUT: %.loc12_13.1: bool = value_of_initializer %int.less_eq.loc12 [template = constants.%.7]
+// CHECK:STDOUT: %.loc12_13.2: bool = converted %int.less_eq.loc12, %.loc12_13.1 [template = constants.%.7]
// CHECK:STDOUT: if %.loc12_13.2 br !if.expr.then.loc12 else br !if.expr.else.loc12
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc12:
@@ -241,15 +246,15 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: %.loc12_13.3: type = block_arg !if.expr.result.loc12 [template = constants.%True]
// CHECK:STDOUT: %false_.ref.loc13: %False = name_ref false_, %false_
// CHECK:STDOUT: %LessEq.ref.loc13: %LessEq.type = name_ref LessEq, file.%LessEq.decl [template = constants.%LessEq]
-// CHECK:STDOUT: %.loc13_24: i32 = int_literal 0 [template = constants.%.7]
+// CHECK:STDOUT: %.loc13_24: i32 = int_literal 0 [template = constants.%.8]
// CHECK:STDOUT: %Negate.ref.loc13: %Negate.type = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT: %.loc13_34: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %int.snegate.loc13: init i32 = call %Negate.ref.loc13(%.loc13_34) [template = constants.%.9]
-// CHECK:STDOUT: %.loc13_23.1: i32 = value_of_initializer %int.snegate.loc13 [template = constants.%.9]
-// CHECK:STDOUT: %.loc13_23.2: i32 = converted %int.snegate.loc13, %.loc13_23.1 [template = constants.%.9]
-// CHECK:STDOUT: %int.less_eq.loc13: init bool = call %LessEq.ref.loc13(%.loc13_24, %.loc13_23.2) [template = constants.%.8]
-// CHECK:STDOUT: %.loc13_14.1: bool = value_of_initializer %int.less_eq.loc13 [template = constants.%.8]
-// CHECK:STDOUT: %.loc13_14.2: bool = converted %int.less_eq.loc13, %.loc13_14.1 [template = constants.%.8]
+// CHECK:STDOUT: %.loc13_34: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %int.snegate.loc13: init i32 = call %Negate.ref.loc13(%.loc13_34) [template = constants.%.10]
+// CHECK:STDOUT: %.loc13_23.1: i32 = value_of_initializer %int.snegate.loc13 [template = constants.%.10]
+// CHECK:STDOUT: %.loc13_23.2: i32 = converted %int.snegate.loc13, %.loc13_23.1 [template = constants.%.10]
+// CHECK:STDOUT: %int.less_eq.loc13: init bool = call %LessEq.ref.loc13(%.loc13_24, %.loc13_23.2) [template = constants.%.9]
+// CHECK:STDOUT: %.loc13_14.1: bool = value_of_initializer %int.less_eq.loc13 [template = constants.%.9]
+// CHECK:STDOUT: %.loc13_14.2: bool = converted %int.less_eq.loc13, %.loc13_14.1 [template = constants.%.9]
// CHECK:STDOUT: if %.loc13_14.2 br !if.expr.then.loc13 else br !if.expr.else.loc13
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc13:
diff --git a/toolchain/check/testdata/builtins/int/neq.carbon b/toolchain/check/testdata/builtins/int/neq.carbon
index 7f476dd221d14..73762b33b68d2 100644
--- a/toolchain/check/testdata/builtins/int/neq.carbon
+++ b/toolchain/check/testdata/builtins/int/neq.carbon
@@ -36,14 +36,15 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: %Neq: %Neq.type = struct_value () [template]
// CHECK:STDOUT: %True: type = class_type @True [template]
// CHECK:STDOUT: %.2: type = struct_type {} [template]
+// CHECK:STDOUT: %.3: = complete_type_witness %.2 [template]
// CHECK:STDOUT: %False: type = class_type @False [template]
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
-// CHECK:STDOUT: %.3: type = ptr_type %.2 [template]
-// CHECK:STDOUT: %.4: i32 = int_literal 1 [template]
-// CHECK:STDOUT: %.5: bool = bool_literal false [template]
-// CHECK:STDOUT: %.6: i32 = int_literal 2 [template]
-// CHECK:STDOUT: %.7: bool = bool_literal true [template]
+// CHECK:STDOUT: %.4: type = ptr_type %.2 [template]
+// CHECK:STDOUT: %.5: i32 = int_literal 1 [template]
+// CHECK:STDOUT: %.6: bool = bool_literal false [template]
+// CHECK:STDOUT: %.7: i32 = int_literal 2 [template]
+// CHECK:STDOUT: %.8: bool = bool_literal true [template]
// CHECK:STDOUT: %RuntimeCall.type: type = fn_type @RuntimeCall [template]
// CHECK:STDOUT: %RuntimeCall: %RuntimeCall.type = struct_value () [template]
// CHECK:STDOUT: }
@@ -120,11 +121,15 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @True {
+// CHECK:STDOUT: %.loc4: = complete_type_witness %.2 [template = constants.%.3]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%True
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @False {
+// CHECK:STDOUT: %.loc5: = complete_type_witness %.2 [template = constants.%.3]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%False
// CHECK:STDOUT: }
@@ -139,11 +144,11 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %false_.ref: %False = name_ref false_, %false_
// CHECK:STDOUT: %Neq.ref.loc8: %Neq.type = name_ref Neq, file.%Neq.decl [template = constants.%Neq]
-// CHECK:STDOUT: %.loc8_21: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %.loc8_24: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %int.neq.loc8: init bool = call %Neq.ref.loc8(%.loc8_21, %.loc8_24) [template = constants.%.5]
-// CHECK:STDOUT: %.loc8_14.1: bool = value_of_initializer %int.neq.loc8 [template = constants.%.5]
-// CHECK:STDOUT: %.loc8_14.2: bool = converted %int.neq.loc8, %.loc8_14.1 [template = constants.%.5]
+// CHECK:STDOUT: %.loc8_21: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %.loc8_24: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %int.neq.loc8: init bool = call %Neq.ref.loc8(%.loc8_21, %.loc8_24) [template = constants.%.6]
+// CHECK:STDOUT: %.loc8_14.1: bool = value_of_initializer %int.neq.loc8 [template = constants.%.6]
+// CHECK:STDOUT: %.loc8_14.2: bool = converted %int.neq.loc8, %.loc8_14.1 [template = constants.%.6]
// CHECK:STDOUT: if %.loc8_14.2 br !if.expr.then.loc8 else br !if.expr.else.loc8
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc8:
@@ -158,11 +163,11 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
// CHECK:STDOUT: %.loc8_14.3: type = block_arg !if.expr.result.loc8 [template = constants.%False]
// CHECK:STDOUT: %true_.ref: %True = name_ref true_, %true_
// CHECK:STDOUT: %Neq.ref.loc9: %Neq.type = name_ref Neq, file.%Neq.decl [template = constants.%Neq]
-// CHECK:STDOUT: %.loc9_20: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT: %.loc9_23: i32 = int_literal 2 [template = constants.%.6]
-// CHECK:STDOUT: %int.neq.loc9: init bool = call %Neq.ref.loc9(%.loc9_20, %.loc9_23) [template = constants.%.7]
-// CHECK:STDOUT: %.loc9_13.1: bool = value_of_initializer %int.neq.loc9 [template = constants.%.7]
-// CHECK:STDOUT: %.loc9_13.2: bool = converted %int.neq.loc9, %.loc9_13.1 [template = constants.%.7]
+// CHECK:STDOUT: %.loc9_20: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT: %.loc9_23: i32 = int_literal 2 [template = constants.%.7]
+// CHECK:STDOUT: %int.neq.loc9: init bool = call %Neq.ref.loc9(%.loc9_20, %.loc9_23) [template = constants.%.8]
+// CHECK:STDOUT: %.loc9_13.1: bool = value_of_initializer %int.neq.loc9 [template = constants.%.8]
+// CHECK:STDOUT: %.loc9_13.2: bool = converted %int.neq.loc9, %.loc9_13.1 [template = constants.%.8]
// CHECK:STDOUT: if %.loc9_13.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then.loc9:
diff --git a/toolchain/check/testdata/class/access_modifers.carbon b/toolchain/check/testdata/class/access_modifers.carbon
index ab035420c1932..76895b6e424a8 100644
--- a/toolchain/check/testdata/class/access_modifers.carbon
+++ b/toolchain/check/testdata/class/access_modifers.carbon
@@ -159,8 +159,9 @@ class A {
// CHECK:STDOUT: %Make.type: type = fn_type @Make [template]
// CHECK:STDOUT: %Make: %Make.type = struct_value () [template]
// CHECK:STDOUT: %.4: type = struct_type {.radius: i32} [template]
-// CHECK:STDOUT: %.5: i32 = int_literal 0 [template]
-// CHECK:STDOUT: %.6: type = ptr_type %.4 [template]
+// CHECK:STDOUT: %.5: = complete_type_witness %.4 [template]
+// CHECK:STDOUT: %.6: i32 = int_literal 0 [template]
+// CHECK:STDOUT: %.7: type = ptr_type %.4 [template]
// CHECK:STDOUT: %struct: %Circle = struct_value (%.3) [template]
// CHECK:STDOUT: %Run.type: type = fn_type @Run [template]
// CHECK:STDOUT: %Run: %Run.type = struct_value () [template]
@@ -212,6 +213,7 @@ class A {
// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Circle [template = constants.%Circle]
// CHECK:STDOUT: %return.var.loc12: ref %Circle = var
// CHECK:STDOUT: }
+// CHECK:STDOUT: %.loc15: = complete_type_witness %.4 [template = constants.%.5]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%Circle
@@ -225,7 +227,7 @@ class A {
// CHECK:STDOUT:
// CHECK:STDOUT: fn @SomeInternalFunction() -> i32 {
// CHECK:STDOUT: !entry:
-// CHECK:STDOUT: %.loc9: i32 = int_literal 0 [template = constants.%.5]
+// CHECK:STDOUT: %.loc9: i32 = int_literal 0 [template = constants.%.6]
// CHECK:STDOUT: return %.loc9
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -276,9 +278,10 @@ class A {
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
// CHECK:STDOUT: %.2: type = unbound_element_type %A, i32 [template]
// CHECK:STDOUT: %.3: type = struct_type {.x: i32} [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
// CHECK:STDOUT: %Run.type: type = fn_type @Run [template]
// CHECK:STDOUT: %Run: %Run.type = struct_value () [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -312,6 +315,7 @@ class A {
// CHECK:STDOUT: %.loc5_20.1: type = value_of_initializer %int.make_type_32 [template = i32]
// CHECK:STDOUT: %.loc5_20.2: type = converted %int.make_type_32, %.loc5_20.1 [template = i32]
// CHECK:STDOUT: %.loc5_18: %.2 = field_decl x, element0 [template]
+// CHECK:STDOUT: %.loc6: = complete_type_witness %.3 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%A
@@ -346,8 +350,9 @@ class A {
// CHECK:STDOUT: %Compute.type: type = fn_type @Compute [template]
// CHECK:STDOUT: %Compute: %Compute.type = struct_value () [template]
// CHECK:STDOUT: %.3: type = struct_type {.radius: i32} [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
-// CHECK:STDOUT: %.5: i32 = int_literal 0 [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.6: i32 = int_literal 0 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -403,6 +408,7 @@ class A {
// CHECK:STDOUT: %.loc15_31.2: type = converted %int.make_type_32.loc15, %.loc15_31.1 [template = i32]
// CHECK:STDOUT: %return.var.loc15: ref i32 = var
// CHECK:STDOUT: }
+// CHECK:STDOUT: %.loc18: = complete_type_witness %.3 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%Circle
@@ -425,7 +431,7 @@ class A {
// CHECK:STDOUT:
// CHECK:STDOUT: fn @SomeInternalFunction() -> i32 {
// CHECK:STDOUT: !entry:
-// CHECK:STDOUT: %.loc12: i32 = int_literal 0 [template = constants.%.5]
+// CHECK:STDOUT: %.loc12: i32 = int_literal 0 [template = constants.%.6]
// CHECK:STDOUT: return %.loc12
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -448,7 +454,8 @@ class A {
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
// CHECK:STDOUT: %.2: i32 = int_literal 5 [template]
// CHECK:STDOUT: %.3: type = struct_type {} [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -485,6 +492,7 @@ class A {
// CHECK:STDOUT: %.loc5_10.2: type = converted %int.make_type_32, %.loc5_10.1 [template = i32]
// CHECK:STDOUT: %.loc5_16: i32 = int_literal 5 [template = constants.%.2]
// CHECK:STDOUT: %x: i32 = bind_name x, %.loc5_16
+// CHECK:STDOUT: %.loc6: = complete_type_witness %.3 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%A
@@ -510,7 +518,8 @@ class A {
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
// CHECK:STDOUT: %.2: i32 = int_literal 5 [template]
// CHECK:STDOUT: %.3: type = struct_type {} [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -556,6 +565,7 @@ class A {
// CHECK:STDOUT: %.loc6_18.2: type = converted %int.make_type_32.loc6, %.loc6_18.1 [template = i32]
// CHECK:STDOUT: %.loc6_24: i32 = int_literal 5 [template = constants.%.2]
// CHECK:STDOUT: %y: i32 = bind_name y, %.loc6_24
+// CHECK:STDOUT: %.loc7: = complete_type_witness %.3 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%A
@@ -586,7 +596,8 @@ class A {
// CHECK:STDOUT: %G.type: type = fn_type @G [template]
// CHECK:STDOUT: %G: %G.type = struct_value () [template]
// CHECK:STDOUT: %.2: type = struct_type {} [template]
-// CHECK:STDOUT: %.3: type = ptr_type %.2 [template]
+// CHECK:STDOUT: %.3: = complete_type_witness %.2 [template]
+// CHECK:STDOUT: %.4: type = ptr_type %.2 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -614,6 +625,7 @@ class A {
// CHECK:STDOUT: class @A {
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {}
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [template = constants.%G] {}
+// CHECK:STDOUT: %.loc7: = complete_type_witness %.2 [template = constants.%.3]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%A
diff --git a/toolchain/check/testdata/class/adapt.carbon b/toolchain/check/testdata/class/adapt.carbon
index 78c30f8a5c13f..e1947841ebbc6 100644
--- a/toolchain/check/testdata/class/adapt.carbon
+++ b/toolchain/check/testdata/class/adapt.carbon
@@ -54,8 +54,10 @@ fn F(a: AdaptNotExtend) {
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
// CHECK:STDOUT: %.2: type = unbound_element_type %SomeClass, i32 [template]
// CHECK:STDOUT: %.3: type = struct_type {.a: i32, .b: i32} [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
// CHECK:STDOUT: %SomeClassAdapter: type = class_type @SomeClassAdapter [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.6: = complete_type_witness %SomeClass [template]
// CHECK:STDOUT: %StructAdapter: type = class_type @StructAdapter [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -96,6 +98,7 @@ fn F(a: AdaptNotExtend) {
// CHECK:STDOUT: %.loc6_10.1: type = value_of_initializer %int.make_type_32.loc6 [template = i32]
// CHECK:STDOUT: %.loc6_10.2: type = converted %int.make_type_32.loc6, %.loc6_10.1 [template = i32]
// CHECK:STDOUT: %.loc6_8: %.2 = field_decl b, element1 [template]
+// CHECK:STDOUT: %.loc7: = complete_type_witness %.3 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%SomeClass
@@ -106,6 +109,7 @@ fn F(a: AdaptNotExtend) {
// CHECK:STDOUT: class @SomeClassAdapter {
// CHECK:STDOUT: %SomeClass.ref: type = name_ref SomeClass, file.%SomeClass.decl [template = constants.%SomeClass]
// CHECK:STDOUT: adapt_decl %SomeClass
+// CHECK:STDOUT: %.loc11: = complete_type_witness %SomeClass [template = constants.%.6]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%SomeClassAdapter
@@ -120,6 +124,7 @@ fn F(a: AdaptNotExtend) {
// CHECK:STDOUT: %.loc14_23.2: type = converted %int.make_type_32.loc14_23, %.loc14_23.1 [template = i32]
// CHECK:STDOUT: %.loc14_26: type = struct_type {.a: i32, .b: i32} [template = constants.%.3]
// CHECK:STDOUT: adapt_decl %.3
+// CHECK:STDOUT: %.loc15: = complete_type_witness %.3 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%StructAdapter
@@ -135,8 +140,10 @@ fn F(a: AdaptNotExtend) {
// CHECK:STDOUT: %.1: type = tuple_type () [template]
// CHECK:STDOUT: %F.1: %F.type.1 = struct_value () [template]
// CHECK:STDOUT: %.2: type = struct_type {} [template]
+// CHECK:STDOUT: %.3: = complete_type_witness %.2 [template]
// CHECK:STDOUT: %AdaptNotExtend: type = class_type @AdaptNotExtend [template]
-// CHECK:STDOUT: %.3: type = ptr_type %.2 [template]
+// CHECK:STDOUT: %.4: type = ptr_type %.2 [template]
+// CHECK:STDOUT: %.5: = complete_type_witness %Adapted [template]
// CHECK:STDOUT: %F.type.2: type = fn_type @F.2 [template]
// CHECK:STDOUT: %F.2: %F.type.2 = struct_value () [template]
// CHECK:STDOUT: }
@@ -173,6 +180,7 @@ fn F(a: AdaptNotExtend) {
// CHECK:STDOUT:
// CHECK:STDOUT: class @Adapted {
// CHECK:STDOUT: %F.decl: %F.type.1 = fn_decl @F.1 [template = constants.%F.1] {}
+// CHECK:STDOUT: %.loc6: = complete_type_witness %.2 [template = constants.%.3]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%Adapted
@@ -182,6 +190,7 @@ fn F(a: AdaptNotExtend) {
// CHECK:STDOUT: class @AdaptNotExtend {
// CHECK:STDOUT: %Adapted.ref: type = name_ref Adapted, file.%Adapted.decl [template = constants.%Adapted]
// CHECK:STDOUT: adapt_decl %Adapted
+// CHECK:STDOUT: %.loc10: = complete_type_witness %Adapted [template = constants.%.5]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%AdaptNotExtend
diff --git a/toolchain/check/testdata/class/base.carbon b/toolchain/check/testdata/class/base.carbon
index 5f2f33856b412..369f8670c5ef6 100644
--- a/toolchain/check/testdata/class/base.carbon
+++ b/toolchain/check/testdata/class/base.carbon
@@ -35,26 +35,28 @@ fn Access(d: Derived) -> (i32, i32) {
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
// CHECK:STDOUT: %.2: type = unbound_element_type %Base, i32 [template]
// CHECK:STDOUT: %.3: type = struct_type {.b: i32} [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
// CHECK:STDOUT: %Derived: type = class_type @Derived [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
-// CHECK:STDOUT: %.5: type = unbound_element_type %Derived, %Base [template]
-// CHECK:STDOUT: %.6: type = unbound_element_type %Derived, i32 [template]
-// CHECK:STDOUT: %.7: type = struct_type {.base: %Base, .d: i32} [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.6: type = unbound_element_type %Derived, %Base [template]
+// CHECK:STDOUT: %.7: type = unbound_element_type %Derived, i32 [template]
+// CHECK:STDOUT: %.8: type = struct_type {.base: %Base, .d: i32} [template]
+// CHECK:STDOUT: %.9: = complete_type_witness %.8 [template]
// CHECK:STDOUT: %Make.type: type = fn_type @Make [template]
// CHECK:STDOUT: %Make: %Make.type = struct_value () [template]
-// CHECK:STDOUT: %.8: type = struct_type {.base: %.4, .d: i32} [template]
-// CHECK:STDOUT: %.9: type = ptr_type %.8 [template]
-// CHECK:STDOUT: %.10: type = ptr_type %.7 [template]
-// CHECK:STDOUT: %.11: i32 = int_literal 4 [template]
-// CHECK:STDOUT: %.12: i32 = int_literal 7 [template]
-// CHECK:STDOUT: %.13: type = struct_type {.base: %.3, .d: i32} [template]
-// CHECK:STDOUT: %struct.1: %Base = struct_value (%.11) [template]
-// CHECK:STDOUT: %struct.2: %Derived = struct_value (%struct.1, %.12) [template]
-// CHECK:STDOUT: %.14: type = tuple_type (type, type) [template]
-// CHECK:STDOUT: %.15: type = tuple_type (i32, i32) [template]
+// CHECK:STDOUT: %.10: type = struct_type {.base: %.5, .d: i32} [template]
+// CHECK:STDOUT: %.11: type = ptr_type %.10 [template]
+// CHECK:STDOUT: %.12: type = ptr_type %.8 [template]
+// CHECK:STDOUT: %.13: i32 = int_literal 4 [template]
+// CHECK:STDOUT: %.14: i32 = int_literal 7 [template]
+// CHECK:STDOUT: %.15: type = struct_type {.base: %.3, .d: i32} [template]
+// CHECK:STDOUT: %struct.1: %Base = struct_value (%.13) [template]
+// CHECK:STDOUT: %struct.2: %Derived = struct_value (%struct.1, %.14) [template]
+// CHECK:STDOUT: %.16: type = tuple_type (type, type) [template]
+// CHECK:STDOUT: %.17: type = tuple_type (i32, i32) [template]
// CHECK:STDOUT: %Access.type: type = fn_type @Access [template]
// CHECK:STDOUT: %Access: %Access.type = struct_value () [template]
-// CHECK:STDOUT: %.16: type = ptr_type %.15 [template]
+// CHECK:STDOUT: %.18: type = ptr_type %.17 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -93,13 +95,13 @@ fn Access(d: Derived) -> (i32, i32) {
// CHECK:STDOUT: @Access.%d: %Derived = bind_name d, %d.loc25_11.1
// CHECK:STDOUT: %int.make_type_32.loc25_27: init type = call constants.%Int32() [template = i32]
// CHECK:STDOUT: %int.make_type_32.loc25_32: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT: %.loc25_35.1: %.14 = tuple_literal (%int.make_type_32.loc25_27, %int.make_type_32.loc25_32)
+// CHECK:STDOUT: %.loc25_35.1: %.16 = tuple_literal (%int.make_type_32.loc25_27, %int.make_type_32.loc25_32)
// CHECK:STDOUT: %.loc25_35.2: type = value_of_initializer %int.make_type_32.loc25_27 [template = i32]
// CHECK:STDOUT: %.loc25_35.3: type = converted %int.make_type_32.loc25_27, %.loc25_35.2 [template = i32]
// CHECK:STDOUT: %.loc25_35.4: type = value_of_initializer %int.make_type_32.loc25_32 [template = i32]
// CHECK:STDOUT: %.loc25_35.5: type = converted %int.make_type_32.loc25_32, %.loc25_35.4 [template = i32]
-// CHECK:STDOUT: %.loc25_35.6: type = converted %.loc25_35.1, constants.%.15 [template = constants.%.15]
-// CHECK:STDOUT: @Access.%return: ref %.15 = var
+// CHECK:STDOUT: %.loc25_35.6: type = converted %.loc25_35.1, constants.%.17 [template = constants.%.17]
+// CHECK:STDOUT: @Access.%return: ref %.17 = var
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -108,6 +110,7 @@ fn Access(d: Derived) -> (i32, i32) {
// CHECK:STDOUT: %.loc12_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
// CHECK:STDOUT: %.loc12_10.2: type = converted %int.make_type_32, %.loc12_10.1 [template = i32]
// CHECK:STDOUT: %.loc12_8: %.2 = field_decl b, element0 [template]
+// CHECK:STDOUT: %.loc13: = complete_type_witness %.3 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%Base
@@ -116,11 +119,12 @@ fn Access(d: Derived) -> (i32, i32) {
// CHECK:STDOUT:
// CHECK:STDOUT: class @Derived {
// CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base]
-// CHECK:STDOUT: %.loc16: %.5 = base_decl %Base, element0 [template]
+// CHECK:STDOUT: %.loc16: %.6 = base_decl %Base, element0 [template]
// CHECK:STDOUT: %int.make_type_32: init type = call constants.%Int32() [template = i32]
// CHECK:STDOUT: %.loc18_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
// CHECK:STDOUT: %.loc18_10.2: type = converted %int.make_type_32, %.loc18_10.1 [template = i32]
-// CHECK:STDOUT: %.loc18_8: %.6 = field_decl d, element1 [template]
+// CHECK:STDOUT: %.loc18_8: %.7 = field_decl d, element1 [template]
+// CHECK:STDOUT: %.loc19: = complete_type_witness %.8 [template = constants.%.9]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%Derived
@@ -133,42 +137,42 @@ fn Access(d: Derived) -> (i32, i32) {
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Make() -> %return: %Derived {
// CHECK:STDOUT: !entry:
-// CHECK:STDOUT: %.loc22_25: i32 = int_literal 4 [template = constants.%.11]
+// CHECK:STDOUT: %.loc22_25: i32 = int_literal 4 [template = constants.%.13]
// CHECK:STDOUT: %.loc22_26.1: %.3 = struct_literal (%.loc22_25)
-// CHECK:STDOUT: %.loc22_34: i32 = int_literal 7 [template = constants.%.12]
-// CHECK:STDOUT: %.loc22_35.1: %.13 = struct_literal (%.loc22_26.1, %.loc22_34)
+// CHECK:STDOUT: %.loc22_34: i32 = int_literal 7 [template = constants.%.14]
+// CHECK:STDOUT: %.loc22_35.1: %.15 = struct_literal (%.loc22_26.1, %.loc22_34)
// CHECK:STDOUT: %.loc22_35.2: ref %Base = class_element_access %return, element0
// CHECK:STDOUT: %.loc22_26.2: ref i32 = class_element_access %.loc22_35.2, element0
-// CHECK:STDOUT: %.loc22_26.3: init i32 = initialize_from %.loc22_25 to %.loc22_26.2 [template = constants.%.11]
+// CHECK:STDOUT: %.loc22_26.3: init i32 = initialize_from %.loc22_25 to %.loc22_26.2 [template = constants.%.13]
// CHECK:STDOUT: %.loc22_26.4: init %Base = class_init (%.loc22_26.3), %.loc22_35.2 [template = constants.%struct.1]
// CHECK:STDOUT: %.loc22_35.3: init %Base = converted %.loc22_26.1, %.loc22_26.4 [template = constants.%struct.1]
// CHECK:STDOUT: %.loc22_35.4: ref i32 = class_element_access %return, element1
-// CHECK:STDOUT: %.loc22_35.5: init i32 = initialize_from %.loc22_34 to %.loc22_35.4 [template = constants.%.12]
+// CHECK:STDOUT: %.loc22_35.5: init i32 = initialize_from %.loc22_34 to %.loc22_35.4 [template = constants.%.14]
// CHECK:STDOUT: %.loc22_35.6: init %Derived = class_init (%.loc22_35.3, %.loc22_35.5), %return [template = constants.%struct.2]
// CHECK:STDOUT: %.loc22_36: init %Derived = converted %.loc22_35.1, %.loc22_35.6 [template = constants.%struct.2]
// CHECK:STDOUT: return %.loc22_36 to %return
// CHECK:STDOUT: }
// CHECK:STDOUT:
-// CHECK:STDOUT: fn @Access(%d: %Derived) -> %return: %.15 {
+// CHECK:STDOUT: fn @Access(%d: %Derived) -> %return: %.17 {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %d.ref.loc26_11: %Derived = name_ref d, %d
-// CHECK:STDOUT: %d.ref.loc26_12: %.6 = name_ref d, @Derived.%.loc18_8 [template = @Derived.%.loc18_8]
+// CHECK:STDOUT: %d.ref.loc26_12: %.7 = name_ref d, @Derived.%.loc18_8 [template = @Derived.%.loc18_8]
// CHECK:STDOUT: %.loc26_12.1: ref i32 = class_element_access %d.ref.loc26_11, element1
// CHECK:STDOUT: %.loc26_12.2: i32 = bind_value %.loc26_12.1
// CHECK:STDOUT: %d.ref.loc26_16: %Derived = name_ref d, %d
-// CHECK:STDOUT: %base.ref: %.5 = name_ref base, @Derived.%.loc16 [template = @Derived.%.loc16]
+// CHECK:STDOUT: %base.ref: %.6 = name_ref base, @Derived.%.loc16 [template = @Derived.%.loc16]
// CHECK:STDOUT: %.loc26_17.1: ref %Base = class_element_access %d.ref.loc26_16, element0
// CHECK:STDOUT: %.loc26_17.2: %Base = bind_value %.loc26_17.1
// CHECK:STDOUT: %b.ref: %.2 = name_ref b, @Base.%.loc12_8 [template = @Base.%.loc12_8]
// CHECK:STDOUT: %.loc26_22.1: ref i32 = class_element_access %.loc26_17.2, element0
// CHECK:STDOUT: %.loc26_22.2: i32 = bind_value %.loc26_22.1
-// CHECK:STDOUT: %.loc26_24.1: %.15 = tuple_literal (%.loc26_12.2, %.loc26_22.2)
+// CHECK:STDOUT: %.loc26_24.1: %.17 = tuple_literal (%.loc26_12.2, %.loc26_22.2)
// CHECK:STDOUT: %.loc26_24.2: ref i32 = tuple_access %return, element0
// CHECK:STDOUT: %.loc26_24.3: init i32 = initialize_from %.loc26_12.2 to %.loc26_24.2
// CHECK:STDOUT: %.loc26_24.4: ref i32 = tuple_access %return, element1
// CHECK:STDOUT: %.loc26_24.5: init i32 = initialize_from %.loc26_22.2 to %.loc26_24.4
-// CHECK:STDOUT: %.loc26_24.6: init %.15 = tuple_init (%.loc26_24.3, %.loc26_24.5) to %return
-// CHECK:STDOUT: %.loc26_25: init %.15 = converted %.loc26_24.1, %.loc26_24.6
+// CHECK:STDOUT: %.loc26_24.6: init %.17 = tuple_init (%.loc26_24.3, %.loc26_24.5) to %return
+// CHECK:STDOUT: %.loc26_25: init %.17 = converted %.loc26_24.1, %.loc26_24.6
// CHECK:STDOUT: return %.loc26_25 to %return
// CHECK:STDOUT: }
// CHECK:STDOUT:
diff --git a/toolchain/check/testdata/class/base_field.carbon b/toolchain/check/testdata/class/base_field.carbon
index 61399eca8acb5..94a2bee3d5ef3 100644
--- a/toolchain/check/testdata/class/base_field.carbon
+++ b/toolchain/check/testdata/class/base_field.carbon
@@ -34,18 +34,20 @@ fn Access(p: Derived*) -> i32* {
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
// CHECK:STDOUT: %.2: type = unbound_element_type %Base, i32 [template]
// CHECK:STDOUT: %.3: type = struct_type {.a: i32, .b: i32, .c: i32} [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
// CHECK:STDOUT: %Derived: type = class_type @Derived [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
-// CHECK:STDOUT: %.5: type = unbound_element_type %Derived, %Base [template]
-// CHECK:STDOUT: %.6: type = unbound_element_type %Derived, i32 [template]
-// CHECK:STDOUT: %.7: type = struct_type {.base: %Base, .d: i32, .e: i32} [template]
-// CHECK:STDOUT: %.8: type = ptr_type %Derived [template]
-// CHECK:STDOUT: %.9: type = ptr_type i32 [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.6: type = unbound_element_type %Derived, %Base [template]
+// CHECK:STDOUT: %.7: type = unbound_element_type %Derived, i32 [template]
+// CHECK:STDOUT: %.8: type = struct_type {.base: %Base, .d: i32, .e: i32} [template]
+// CHECK:STDOUT: %.9: = complete_type_witness %.8 [template]
+// CHECK:STDOUT: %.10: type = ptr_type %Derived [template]
+// CHECK:STDOUT: %.11: type = ptr_type i32 [template]
// CHECK:STDOUT: %Access.type: type = fn_type @Access [template]
// CHECK:STDOUT: %Access: %Access.type = struct_value () [template]
-// CHECK:STDOUT: %.10: type = struct_type {.base: %.4, .d: i32, .e: i32} [template]
-// CHECK:STDOUT: %.11: type = ptr_type %.10 [template]
-// CHECK:STDOUT: %.12: type = ptr_type %.7 [template]
+// CHECK:STDOUT: %.12: type = struct_type {.base: %.5, .d: i32, .e: i32} [template]
+// CHECK:STDOUT: %.13: type = ptr_type %.12 [template]
+// CHECK:STDOUT: %.14: type = ptr_type %.8 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -75,14 +77,14 @@ fn Access(p: Derived*) -> i32* {
// CHECK:STDOUT: %Derived.decl: type = class_decl @Derived [template = constants.%Derived] {}
// CHECK:STDOUT: %Access.decl: %Access.type = fn_decl @Access [template = constants.%Access] {
// CHECK:STDOUT: %Derived.ref: type = name_ref Derived, %Derived.decl [template = constants.%Derived]
-// CHECK:STDOUT: %.loc24_21: type = ptr_type %Derived [template = constants.%.8]
-// CHECK:STDOUT: %p.loc24_11.1: %.8 = param p, runtime_param0
-// CHECK:STDOUT: @Access.%p: %.8 = bind_name p, %p.loc24_11.1
+// CHECK:STDOUT: %.loc24_21: type = ptr_type %Derived [template = constants.%.10]
+// CHECK:STDOUT: %p.loc24_11.1: %.10 = param p, runtime_param0
+// CHECK:STDOUT: @Access.%p: %.10 = bind_name p, %p.loc24_11.1
// CHECK:STDOUT: %int.make_type_32: init type = call constants.%Int32() [template = i32]
// CHECK:STDOUT: %.loc24_30.1: type = value_of_initializer %int.make_type_32 [template = i32]
// CHECK:STDOUT: %.loc24_30.2: type = converted %int.make_type_32, %.loc24_30.1 [template = i32]
-// CHECK:STDOUT: %.loc24_30.3: type = ptr_type i32 [template = constants.%.9]
-// CHECK:STDOUT: @Access.%return: ref %.9 = var
+// CHECK:STDOUT: %.loc24_30.3: type = ptr_type i32 [template = constants.%.11]
+// CHECK:STDOUT: @Access.%return: ref %.11 = var
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -99,6 +101,7 @@ fn Access(p: Derived*) -> i32* {
// CHECK:STDOUT: %.loc14_10.1: type = value_of_initializer %int.make_type_32.loc14 [template = i32]
// CHECK:STDOUT: %.loc14_10.2: type = converted %int.make_type_32.loc14, %.loc14_10.1 [template = i32]
// CHECK:STDOUT: %.loc14_8: %.2 = field_decl c, element2 [template]
+// CHECK:STDOUT: %.loc15: = complete_type_witness %.3 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%Base
@@ -109,15 +112,16 @@ fn Access(p: Derived*) -> i32* {
// CHECK:STDOUT:
// CHECK:STDOUT: class @Derived {
// CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base]
-// CHECK:STDOUT: %.loc18: %.5 = base_decl %Base, element0 [template]
+// CHECK:STDOUT: %.loc18: %.6 = base_decl %Base, element0 [template]
// CHECK:STDOUT: %int.make_type_32.loc20: init type = call constants.%Int32() [template = i32]
// CHECK:STDOUT: %.loc20_10.1: type = value_of_initializer %int.make_type_32.loc20 [template = i32]
// CHECK:STDOUT: %.loc20_10.2: type = converted %int.make_type_32.loc20, %.loc20_10.1 [template = i32]
-// CHECK:STDOUT: %.loc20_8: %.6 = field_decl d, element1 [template]
+// CHECK:STDOUT: %.loc20_8: %.7 = field_decl d, element1 [template]
// CHECK:STDOUT: %int.make_type_32.loc21: init type = call constants.%Int32() [template = i32]
// CHECK:STDOUT: %.loc21_10.1: type = value_of_initializer %int.make_type_32.loc21 [template = i32]
// CHECK:STDOUT: %.loc21_10.2: type = converted %int.make_type_32.loc21, %.loc21_10.1 [template = i32]
-// CHECK:STDOUT: %.loc21_8: %.6 = field_decl e, element2 [template]
+// CHECK:STDOUT: %.loc21_8: %.7 = field_decl e, element2 [template]
+// CHECK:STDOUT: %.loc22: = complete_type_witness %.8 [template = constants.%.9]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%Derived
@@ -129,15 +133,15 @@ fn Access(p: Derived*) -> i32* {
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
// CHECK:STDOUT:
-// CHECK:STDOUT: fn @Access(%p: %.8) -> %.9 {
+// CHECK:STDOUT: fn @Access(%p: %.10) -> %.11 {
// CHECK:STDOUT: !entry:
-// CHECK:STDOUT: %p.ref: %.8 = name_ref p, %p
+// CHECK:STDOUT: %p.ref: %.10 = name_ref p, %p
// CHECK:STDOUT: %.loc25_12: ref %Derived = deref %p.ref
// CHECK:STDOUT: %c.ref: %.2 = name_ref c, @Base.%.loc14_8 [template = @Base.%.loc14_8]
// CHECK:STDOUT: %.loc25_15.1: ref %Base = class_element_access %.loc25_12, element0
// CHECK:STDOUT: %.loc25_15.2: ref %Base = converted %.loc25_12, %.loc25_15.1
// CHECK:STDOUT: %.loc25_15.3: ref i32 = class_element_access %.loc25_15.2, element2
-// CHECK:STDOUT: %.loc25_10: %.9 = addr_of %.loc25_15.3
+// CHECK:STDOUT: %.loc25_10: %.11 = addr_of %.loc25_15.3
// CHECK:STDOUT: return %.loc25_10
// CHECK:STDOUT: }
// CHECK:STDOUT:
diff --git a/toolchain/check/testdata/class/base_function_unqualified.carbon b/toolchain/check/testdata/class/base_function_unqualified.carbon
index 36be675257066..b0f5a3680a1e4 100644
--- a/toolchain/check/testdata/class/base_function_unqualified.carbon
+++ b/toolchain/check/testdata/class/base_function_unqualified.carbon
@@ -31,14 +31,16 @@ fn Derived.H() {
// CHECK:STDOUT: %.1: type = tuple_type () [template]
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
// CHECK:STDOUT: %.2: type = struct_type {} [template]
+// CHECK:STDOUT: %.3: = complete_type_witness %.2 [template]
// CHECK:STDOUT: %Derived: type = class_type @Derived [template]
-// CHECK:STDOUT: %.3: type = ptr_type %.2 [template]
-// CHECK:STDOUT: %.4: type = unbound_element_type %Derived, %Base [template]
+// CHECK:STDOUT: %.4: type = ptr_type %.2 [template]
+// CHECK:STDOUT: %.5: type = unbound_element_type %Derived, %Base [template]
// CHECK:STDOUT: %G.type: type = fn_type @G [template]
// CHECK:STDOUT: %G: %G.type = struct_value () [template]
// CHECK:STDOUT: %H.type: type = fn_type @H [template]
// CHECK:STDOUT: %H: %H.type = struct_value () [template]
-// CHECK:STDOUT: %.5: type = struct_type {.base: %Base} [template]
+// CHECK:STDOUT: %.6: type = struct_type {.base: %Base} [template]
+// CHECK:STDOUT: %.7: = complete_type_witness %.6 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -68,6 +70,7 @@ fn Derived.H() {
// CHECK:STDOUT:
// CHECK:STDOUT: class @Base {
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {}
+// CHECK:STDOUT: %.loc13: = complete_type_witness %.2 [template = constants.%.3]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%Base
@@ -76,9 +79,10 @@ fn Derived.H() {
// CHECK:STDOUT:
// CHECK:STDOUT: class @Derived {
// CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base]
-// CHECK:STDOUT: %.loc16: %.4 = base_decl %Base, element0 [template]
+// CHECK:STDOUT: %.loc16: %.5 = base_decl %Base, element0 [template]
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [template = constants.%G] {}
// CHECK:STDOUT: %H.decl: %H.type = fn_decl @H [template = constants.%H] {}
+// CHECK:STDOUT: %.loc20: = complete_type_witness %.6 [template = constants.%.7]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%Derived
diff --git a/toolchain/check/testdata/class/base_method.carbon b/toolchain/check/testdata/class/base_method.carbon
index 527854420b142..a00ca01a59d2c 100644
--- a/toolchain/check/testdata/class/base_method.carbon
+++ b/toolchain/check/testdata/class/base_method.carbon
@@ -38,16 +38,18 @@ fn Call(p: Derived*) {
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
// CHECK:STDOUT: %.4: type = struct_type {.a: i32} [template]
-// CHECK:STDOUT: %.5: type = ptr_type %.4 [template]
-// CHECK:STDOUT: %.6: i32 = int_literal 1 [template]
+// CHECK:STDOUT: %.5: = complete_type_witness %.4 [template]
+// CHECK:STDOUT: %.6: type = ptr_type %.4 [template]
+// CHECK:STDOUT: %.7: i32 = int_literal 1 [template]
// CHECK:STDOUT: %Derived: type = class_type @Derived [template]
-// CHECK:STDOUT: %.7: type = unbound_element_type %Derived, %Base [template]
-// CHECK:STDOUT: %.8: type = struct_type {.base: %Base} [template]
-// CHECK:STDOUT: %.9: type = ptr_type %Derived [template]
+// CHECK:STDOUT: %.8: type = unbound_element_type %Derived, %Base [template]
+// CHECK:STDOUT: %.9: type = struct_type {.base: %Base} [template]
+// CHECK:STDOUT: %.10: = complete_type_witness %.9 [template]
+// CHECK:STDOUT: %.11: type = ptr_type %Derived [template]
// CHECK:STDOUT: %Call.type: type = fn_type @Call [template]
// CHECK:STDOUT: %Call: %Call.type = struct_value () [template]
-// CHECK:STDOUT: %.10: type = struct_type {.base: %.5} [template]
-// CHECK:STDOUT: %.11: type = ptr_type %.8 [template]
+// CHECK:STDOUT: %.12: type = struct_type {.base: %.6} [template]
+// CHECK:STDOUT: %.13: type = ptr_type %.9 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -84,9 +86,9 @@ fn Call(p: Derived*) {
// CHECK:STDOUT: %Derived.decl: type = class_decl @Derived [template = constants.%Derived] {}
// CHECK:STDOUT: %Call.decl: %Call.type = fn_decl @Call [template = constants.%Call] {
// CHECK:STDOUT: %Derived.ref: type = name_ref Derived, %Derived.decl [template = constants.%Derived]
-// CHECK:STDOUT: %.loc25: type = ptr_type %Derived [template = constants.%.9]
-// CHECK:STDOUT: %p.loc25_9.1: %.9 = param p, runtime_param0
-// CHECK:STDOUT: @Call.%p: %.9 = bind_name p, %p.loc25_9.1
+// CHECK:STDOUT: %.loc25: type = ptr_type %Derived [template = constants.%.11]
+// CHECK:STDOUT: %p.loc25_9.1: %.11 = param p, runtime_param0
+// CHECK:STDOUT: @Call.%p: %.11 = bind_name p, %p.loc25_9.1
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -102,6 +104,7 @@ fn Call(p: Derived*) {
// CHECK:STDOUT: %self.loc14_13.3: %.3 = bind_name self, %self.loc14_13.1
// CHECK:STDOUT: %.loc14_8: %.3 = addr_pattern %self.loc14_13.3
// CHECK:STDOUT: }
+// CHECK:STDOUT: %.loc15: = complete_type_witness %.4 [template = constants.%.5]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%Base
@@ -111,7 +114,8 @@ fn Call(p: Derived*) {
// CHECK:STDOUT:
// CHECK:STDOUT: class @Derived {
// CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base]
-// CHECK:STDOUT: %.loc22: %.7 = base_decl %Base, element0 [template]
+// CHECK:STDOUT: %.loc22: %.8 = base_decl %Base, element0 [template]
+// CHECK:STDOUT: %.loc23: = complete_type_witness %.9 [template = constants.%.10]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%Derived
@@ -127,18 +131,18 @@ fn Call(p: Derived*) {
// CHECK:STDOUT: %.loc18_4: ref %Base = deref %self.ref
// CHECK:STDOUT: %a.ref: %.2 = name_ref a, @Base.%.loc12_8 [template = @Base.%.loc12_8]
// CHECK:STDOUT: %.loc18_10: ref i32 = class_element_access %.loc18_4, element0
-// CHECK:STDOUT: %.loc18_15: i32 = int_literal 1 [template = constants.%.6]
+// CHECK:STDOUT: %.loc18_15: i32 = int_literal 1 [template = constants.%.7]
// CHECK:STDOUT: assign %.loc18_10, %.loc18_15
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
-// CHECK:STDOUT: fn @Call(%p: %.9) {
+// CHECK:STDOUT: fn @Call(%p: %.11) {
// CHECK:STDOUT: !entry:
-// CHECK:STDOUT: %p.ref: %.9 = name_ref p, %p
+// CHECK:STDOUT: %p.ref: %.11 = name_ref p, %p
// CHECK:STDOUT: %.loc26_4.1: ref %Derived = deref %p.ref
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, @Base.%F.decl [template = constants.%F]
// CHECK:STDOUT: %.loc26_7: = bound_method %.loc26_4.1, %F.ref
-// CHECK:STDOUT: %.loc26_4.2: %.9 = addr_of %.loc26_4.1
+// CHECK:STDOUT: %.loc26_4.2: %.11 = addr_of %.loc26_4.1
// CHECK:STDOUT: %.loc26_9.1: ref %Derived = deref %.loc26_4.2
// CHECK:STDOUT: %.loc26_9.2: ref %Base = class_element_access %.loc26_9.1, element0
// CHECK:STDOUT: %.loc26_9.3: %.3 = addr_of %.loc26_9.2
diff --git a/toolchain/check/testdata/class/base_method_qualified.carbon b/toolchain/check/testdata/class/base_method_qualified.carbon
index 0e28dc09fb1be..8f99beb95e6f6 100644
--- a/toolchain/check/testdata/class/base_method_qualified.carbon
+++ b/toolchain/check/testdata/class/base_method_qualified.carbon
@@ -51,18 +51,20 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 {
// CHECK:STDOUT: %G.type.1: type = fn_type @G.1 [template]
// CHECK:STDOUT: %G.1: %G.type.1 = struct_value () [template]
// CHECK:STDOUT: %.2: type = struct_type {} [template]
-// CHECK:STDOUT: %.3: type = ptr_type %.2 [template]
-// CHECK:STDOUT: %.4: type = unbound_element_type %Derived, %Base [template]
+// CHECK:STDOUT: %.3: = complete_type_witness %.2 [template]
+// CHECK:STDOUT: %.4: type = ptr_type %.2 [template]
+// CHECK:STDOUT: %.5: type = unbound_element_type %Derived, %Base [template]
// CHECK:STDOUT: %F.type.2: type = fn_type @F.2 [template]
// CHECK:STDOUT: %F.2: %F.type.2 = struct_value () [template]
// CHECK:STDOUT: %G.type.2: type = fn_type @G.2 [template]
// CHECK:STDOUT: %G.2: %G.type.2 = struct_value () [template]
-// CHECK:STDOUT: %.5: type = struct_type {.base: %Base} [template]
+// CHECK:STDOUT: %.6: type = struct_type {.base: %Base} [template]
+// CHECK:STDOUT: %.7: = complete_type_witness %.6 [template]
// CHECK:STDOUT: %Call.type: type = fn_type @Call [template]
// CHECK:STDOUT: %Call: %Call.type = struct_value () [template]
-// CHECK:STDOUT: %.6: type = struct_type {.base: %.3} [template]
-// CHECK:STDOUT: %.7: type = ptr_type %.5 [template]
-// CHECK:STDOUT: %.8: type = ptr_type %Derived [template]
+// CHECK:STDOUT: %.8: type = struct_type {.base: %.4} [template]
+// CHECK:STDOUT: %.9: type = ptr_type %.6 [template]
+// CHECK:STDOUT: %.10: type = ptr_type %Derived [template]
// CHECK:STDOUT: %CallIndirect.type: type = fn_type @CallIndirect [template]
// CHECK:STDOUT: %CallIndirect: %CallIndirect.type = struct_value () [template]
// CHECK:STDOUT: %PassDerivedToBase.type: type = fn_type @PassDerivedToBase [template]
@@ -111,9 +113,9 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 {
// CHECK:STDOUT: }
// CHECK:STDOUT: %CallIndirect.decl: %CallIndirect.type = fn_decl @CallIndirect [template = constants.%CallIndirect] {
// CHECK:STDOUT: %Derived.ref.loc29: type = name_ref Derived, %Derived.decl.loc11 [template = constants.%Derived]
-// CHECK:STDOUT: %.loc29_27: type = ptr_type %Derived [template = constants.%.8]
-// CHECK:STDOUT: %p.loc29_17.1: %.8 = param p, runtime_param0
-// CHECK:STDOUT: @CallIndirect.%p: %.8 = bind_name p, %p.loc29_17.1
+// CHECK:STDOUT: %.loc29_27: type = ptr_type %Derived [template = constants.%.10]
+// CHECK:STDOUT: %p.loc29_17.1: %.10 = param p, runtime_param0
+// CHECK:STDOUT: @CallIndirect.%p: %.10 = bind_name p, %p.loc29_17.1
// CHECK:STDOUT: %int.make_type_32.loc29: init type = call constants.%Int32() [template = i32]
// CHECK:STDOUT: %.loc29_33.1: type = value_of_initializer %int.make_type_32.loc29 [template = i32]
// CHECK:STDOUT: %.loc29_33.2: type = converted %int.make_type_32.loc29, %.loc29_33.1 [template = i32]
@@ -130,9 +132,9 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 {
// CHECK:STDOUT: }
// CHECK:STDOUT: %PassDerivedToBaseIndirect.decl: %PassDerivedToBaseIndirect.type = fn_decl @PassDerivedToBaseIndirect [template = constants.%PassDerivedToBaseIndirect] {
// CHECK:STDOUT: %Derived.ref.loc37: type = name_ref Derived, %Derived.decl.loc11 [template = constants.%Derived]
-// CHECK:STDOUT: %.loc37_40: type = ptr_type %Derived [template = constants.%.8]
-// CHECK:STDOUT: %p.loc37_30.1: %.8 = param p, runtime_param0
-// CHECK:STDOUT: @PassDerivedToBaseIndirect.%p: %.8 = bind_name p, %p.loc37_30.1
+// CHECK:STDOUT: %.loc37_40: type = ptr_type %Derived [template = constants.%.10]
+// CHECK:STDOUT: %p.loc37_30.1: %.10 = param p, runtime_param0
+// CHECK:STDOUT: @PassDerivedToBaseIndirect.%p: %.10 = bind_name p, %p.loc37_30.1
// CHECK:STDOUT: %int.make_type_32.loc37: init type = call constants.%Int32() [template = i32]
// CHECK:STDOUT: %.loc37_46.1: type = value_of_initializer %int.make_type_32.loc37 [template = i32]
// CHECK:STDOUT: %.loc37_46.2: type = converted %int.make_type_32.loc37, %.loc37_46.1 [template = i32]
@@ -142,7 +144,7 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 {
// CHECK:STDOUT:
// CHECK:STDOUT: class @Derived {
// CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base]
-// CHECK:STDOUT: %.loc19: %.4 = base_decl %Base, element0 [template]
+// CHECK:STDOUT: %.loc19: %.5 = base_decl %Base, element0 [template]
// CHECK:STDOUT: %F.decl: %F.type.2 = fn_decl @F.2 [template = constants.%F.2] {
// CHECK:STDOUT: %Self.ref.loc21: type = name_ref Self, constants.%Derived [template = constants.%Derived]
// CHECK:STDOUT: %self.loc21_8.1: %Derived = param self, runtime_param0
@@ -153,6 +155,7 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 {
// CHECK:STDOUT: %self.loc22_8.1: %Derived = param self, runtime_param0
// CHECK:STDOUT: %self.loc22_8.2: %Derived = bind_name self, %self.loc22_8.1
// CHECK:STDOUT: }
+// CHECK:STDOUT: %.loc23: = complete_type_witness %.6 [template = constants.%.7]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%Derived
@@ -181,6 +184,7 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 {
// CHECK:STDOUT: %.loc15_28.2: type = converted %int.make_type_32.loc15, %.loc15_28.1 [template = i32]
// CHECK:STDOUT: %return.var.loc15: ref i32 = var
// CHECK:STDOUT: }
+// CHECK:STDOUT: %.loc16: = complete_type_witness %.2 [template = constants.%.3]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%Base
@@ -213,9 +217,9 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 {
// CHECK:STDOUT: return %.loc26_22.2
// CHECK:STDOUT: }
// CHECK:STDOUT:
-// CHECK:STDOUT: fn @CallIndirect(%p: %.8) -> i32 {
+// CHECK:STDOUT: fn @CallIndirect(%p: %.10) -> i32 {
// CHECK:STDOUT: !entry:
-// CHECK:STDOUT: %p.ref: %.8 = name_ref p, %p
+// CHECK:STDOUT: %p.ref: %.10 = name_ref p, %p
// CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base]
// CHECK:STDOUT: %F.ref: %F.type.1 = name_ref F, @Base.%F.decl [template = constants.%F.1]
// CHECK:STDOUT: %.loc30_11.1: ref %Derived = deref %p.ref
@@ -241,9 +245,9 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 {
// CHECK:STDOUT: return %.loc34_22.2
// CHECK:STDOUT: }
// CHECK:STDOUT:
-// CHECK:STDOUT: fn @PassDerivedToBaseIndirect(%p: %.8) -> i32 {
+// CHECK:STDOUT: fn @PassDerivedToBaseIndirect(%p: %.10) -> i32 {
// CHECK:STDOUT: !entry:
-// CHECK:STDOUT: %p.ref: %.8 = name_ref p, %p
+// CHECK:STDOUT: %p.ref: %.10 = name_ref p, %p
// CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base]
// CHECK:STDOUT: %G.ref: %G.type.1 = name_ref G, @Base.%G.decl [template = constants.%G.1]
// CHECK:STDOUT: %.loc38_11.1: ref %Derived = deref %p.ref
diff --git a/toolchain/check/testdata/class/base_method_shadow.carbon b/toolchain/check/testdata/class/base_method_shadow.carbon
index 1797652342f1d..ac9636ac26e63 100644
--- a/toolchain/check/testdata/class/base_method_shadow.carbon
+++ b/toolchain/check/testdata/class/base_method_shadow.carbon
@@ -42,28 +42,31 @@ fn Call(a: A*, b: B*, c: C*, d: D*) {
// CHECK:STDOUT: %.2: type = tuple_type () [template]
// CHECK:STDOUT: %F.1: %F.type.1 = struct_value () [template]
// CHECK:STDOUT: %.3: type = struct_type {} [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
// CHECK:STDOUT: %B: type = class_type @B [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
-// CHECK:STDOUT: %.5: type = unbound_element_type %B, %A [template]
-// CHECK:STDOUT: %.6: type = ptr_type %B [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.6: type = unbound_element_type %B, %A [template]
+// CHECK:STDOUT: %.7: type = ptr_type %B [template]
// CHECK:STDOUT: %F.type.2: type = fn_type @F.2 [template]
// CHECK:STDOUT: %F.2: %F.type.2 = struct_value () [template]
-// CHECK:STDOUT: %.7: type = struct_type {.base: %A} [template]
+// CHECK:STDOUT: %.8: type = struct_type {.base: %A} [template]
+// CHECK:STDOUT: %.9: = complete_type_witness %.8 [template]
// CHECK:STDOUT: %C: type = class_type @C [template]
-// CHECK:STDOUT: %.8: type = struct_type {.base: %.4} [template]
-// CHECK:STDOUT: %.9: type = ptr_type %.7 [template]
-// CHECK:STDOUT: %.10: type = unbound_element_type %C, %B [template]
-// CHECK:STDOUT: %.11: type = ptr_type %C [template]
+// CHECK:STDOUT: %.10: type = struct_type {.base: %.5} [template]
+// CHECK:STDOUT: %.11: type = ptr_type %.8 [template]
+// CHECK:STDOUT: %.12: type = unbound_element_type %C, %B [template]
+// CHECK:STDOUT: %.13: type = ptr_type %C [template]
// CHECK:STDOUT: %F.type.3: type = fn_type @F.3 [template]
// CHECK:STDOUT: %F.3: %F.type.3 = struct_value () [template]
-// CHECK:STDOUT: %.12: type = struct_type {.base: %B} [template]
+// CHECK:STDOUT: %.14: type = struct_type {.base: %B} [template]
+// CHECK:STDOUT: %.15: = complete_type_witness %.14 [template]
// CHECK:STDOUT: %D: type = class_type @D [template]
-// CHECK:STDOUT: %.13: type = unbound_element_type %D, %B [template]
-// CHECK:STDOUT: %.14: type = ptr_type %D [template]
+// CHECK:STDOUT: %.16: type = unbound_element_type %D, %B [template]
+// CHECK:STDOUT: %.17: type = ptr_type %D [template]
// CHECK:STDOUT: %Call.type: type = fn_type @Call [template]
// CHECK:STDOUT: %Call: %Call.type = struct_value () [template]
-// CHECK:STDOUT: %.15: type = struct_type {.base: %.9} [template]
-// CHECK:STDOUT: %.16: type = ptr_type %.12 [template]
+// CHECK:STDOUT: %.18: type = struct_type {.base: %.11} [template]
+// CHECK:STDOUT: %.19: type = ptr_type %.14 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -99,17 +102,17 @@ fn Call(a: A*, b: B*, c: C*, d: D*) {
// CHECK:STDOUT: %a.loc29_9.1: %.1 = param a, runtime_param0
// CHECK:STDOUT: @Call.%a: %.1 = bind_name a, %a.loc29_9.1
// CHECK:STDOUT: %B.ref: type = name_ref B, %B.decl [template = constants.%B]
-// CHECK:STDOUT: %.loc29_20: type = ptr_type %B [template = constants.%.6]
-// CHECK:STDOUT: %b.loc29_16.1: %.6 = param b, runtime_param1
-// CHECK:STDOUT: @Call.%b: %.6 = bind_name b, %b.loc29_16.1
+// CHECK:STDOUT: %.loc29_20: type = ptr_type %B [template = constants.%.7]
+// CHECK:STDOUT: %b.loc29_16.1: %.7 = param b, runtime_param1
+// CHECK:STDOUT: @Call.%b: %.7 = bind_name b, %b.loc29_16.1
// CHECK:STDOUT: %C.ref: type = name_ref C, %C.decl [template = constants.%C]
-// CHECK:STDOUT: %.loc29_27: type = ptr_type %C [template = constants.%.11]
-// CHECK:STDOUT: %c.loc29_23.1: %.11 = param c, runtime_param2
-// CHECK:STDOUT: @Call.%c: %.11 = bind_name c, %c.loc29_23.1
+// CHECK:STDOUT: %.loc29_27: type = ptr_type %C [template = constants.%.13]
+// CHECK:STDOUT: %c.loc29_23.1: %.13 = param c, runtime_param2
+// CHECK:STDOUT: @Call.%c: %.13 = bind_name c, %c.loc29_23.1
// CHECK:STDOUT: %D.ref: type = name_ref D, %D.decl [template = constants.%D]
-// CHECK:STDOUT: %.loc29_34: type = ptr_type %D [template = constants.%.14]
-// CHECK:STDOUT: %d.loc29_30.1: %.14 = param d, runtime_param3
-// CHECK:STDOUT: @Call.%d: %.14 = bind_name d, %d.loc29_30.1
+// CHECK:STDOUT: %.loc29_34: type = ptr_type %D [template = constants.%.17]
+// CHECK:STDOUT: %d.loc29_30.1: %.17 = param d, runtime_param3
+// CHECK:STDOUT: @Call.%d: %.17 = bind_name d, %d.loc29_30.1
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -121,6 +124,7 @@ fn Call(a: A*, b: B*, c: C*, d: D*) {
// CHECK:STDOUT: %self.loc12_13.3: %.1 = bind_name self, %self.loc12_13.1
// CHECK:STDOUT: %.loc12_8: %.1 = addr_pattern %self.loc12_13.3
// CHECK:STDOUT: }
+// CHECK:STDOUT: %.loc13: = complete_type_witness %.3 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%A
@@ -129,14 +133,15 @@ fn Call(a: A*, b: B*, c: C*, d: D*) {
// CHECK:STDOUT:
// CHECK:STDOUT: class @B {
// CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A]
-// CHECK:STDOUT: %.loc16: %.5 = base_decl %A, element0 [template]
+// CHECK:STDOUT: %.loc16: %.6 = base_decl %A, element0 [template]
// CHECK:STDOUT: %F.decl: %F.type.2 = fn_decl @F.2 [template = constants.%F.2] {
// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [template = constants.%B]
-// CHECK:STDOUT: %.loc17_23: type = ptr_type %B [template = constants.%.6]
-// CHECK:STDOUT: %self.loc17_13.1: %.6 = param self, runtime_param0
-// CHECK:STDOUT: %self.loc17_13.3: %.6 = bind_name self, %self.loc17_13.1
-// CHECK:STDOUT: %.loc17_8: %.6 = addr_pattern %self.loc17_13.3
+// CHECK:STDOUT: %.loc17_23: type = ptr_type %B [template = constants.%.7]
+// CHECK:STDOUT: %self.loc17_13.1: %.7 = param self, runtime_param0
+// CHECK:STDOUT: %self.loc17_13.3: %.7 = bind_name self, %self.loc17_13.1
+// CHECK:STDOUT: %.loc17_8: %.7 = addr_pattern %self.loc17_13.3
// CHECK:STDOUT: }
+// CHECK:STDOUT: %.loc18: = complete_type_witness %.8 [template = constants.%.9]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%B
@@ -147,14 +152,15 @@ fn Call(a: A*, b: B*, c: C*, d: D*) {
// CHECK:STDOUT:
// CHECK:STDOUT: class @C {
// CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B]
-// CHECK:STDOUT: %.loc21: %.10 = base_decl %B, element0 [template]
+// CHECK:STDOUT: %.loc21: %.12 = base_decl %B, element0 [template]
// CHECK:STDOUT: %F.decl: %F.type.3 = fn_decl @F.3 [template = constants.%F.3] {
// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [template = constants.%C]
-// CHECK:STDOUT: %.loc22_23: type = ptr_type %C [template = constants.%.11]
-// CHECK:STDOUT: %self.loc22_13.1: %.11 = param self, runtime_param0
-// CHECK:STDOUT: %self.loc22_13.3: %.11 = bind_name self, %self.loc22_13.1
-// CHECK:STDOUT: %.loc22_8: %.11 = addr_pattern %self.loc22_13.3
+// CHECK:STDOUT: %.loc22_23: type = ptr_type %C [template = constants.%.13]
+// CHECK:STDOUT: %self.loc22_13.1: %.13 = param self, runtime_param0
+// CHECK:STDOUT: %self.loc22_13.3: %.13 = bind_name self, %self.loc22_13.1
+// CHECK:STDOUT: %.loc22_8: %.13 = addr_pattern %self.loc22_13.3
// CHECK:STDOUT: }
+// CHECK:STDOUT: %.loc23: = complete_type_witness %.14 [template = constants.%.15]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%C
@@ -165,7 +171,8 @@ fn Call(a: A*, b: B*, c: C*, d: D*) {
// CHECK:STDOUT:
// CHECK:STDOUT: class @D {
// CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B]
-// CHECK:STDOUT: %.loc26: %.13 = base_decl %B, element0 [template]
+// CHECK:STDOUT: %.loc26: %.16 = base_decl %B, element0 [template]
+// CHECK:STDOUT: %.loc27: = complete_type_witness %.14 [template = constants.%.15]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%D
@@ -175,11 +182,11 @@ fn Call(a: A*, b: B*, c: C*, d: D*) {
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F.1[addr @A.%self.loc12_13.3: %.1]();
// CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.2[addr @B.%self.loc17_13.3: %.6]();
+// CHECK:STDOUT: fn @F.2[addr @B.%self.loc17_13.3: %.7]();
// CHECK:STDOUT:
-// CHECK:STDOUT: fn @F.3[addr @C.%self.loc22_13.3: %.11]();
+// CHECK:STDOUT: fn @F.3[addr @C.%self.loc22_13.3: %.13]();
// CHECK:STDOUT:
-// CHECK:STDOUT: fn @Call(%a: %.1, %b: %.6, %c: %.11, %d: %.14) {
+// CHECK:STDOUT: fn @Call(%a: %.1, %b: %.7, %c: %.13, %d: %.17) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %a.ref: %.1 = name_ref a, %a
// CHECK:STDOUT: %.loc30_4.1: ref %A = deref %a.ref
@@ -187,27 +194,27 @@ fn Call(a: A*, b: B*, c: C*, d: D*) {
// CHECK:STDOUT: %.loc30_7: = bound_method %.loc30_4.1, %F.ref.loc30
// CHECK:STDOUT: %.loc30_4.2: %.1 = addr_of %.loc30_4.1
// CHECK:STDOUT: %F.call.loc30: init %.2 = call %.loc30_7(%.loc30_4.2)
-// CHECK:STDOUT: %b.ref: %.6 = name_ref b, %b
+// CHECK:STDOUT: %b.ref: %.7 = name_ref b, %b
// CHECK:STDOUT: %.loc31_4.1: ref %B = deref %b.ref
// CHECK:STDOUT: %F.ref.loc31: %F.type.2 = name_ref F, @B.%F.decl [template = constants.%F.2]
// CHECK:STDOUT: %.loc31_7: = bound_method %.loc31_4.1, %F.ref.loc31
-// CHECK:STDOUT: %.loc31_4.2: %.6 = addr_of %.loc31_4.1
+// CHECK:STDOUT: %.loc31_4.2: %.7 = addr_of %.loc31_4.1
// CHECK:STDOUT: %F.call.loc31: init %.2 = call %.loc31_7(%.loc31_4.2)
-// CHECK:STDOUT: %c.ref: %.11 = name_ref c, %c
+// CHECK:STDOUT: %c.ref: %.13 = name_ref c, %c
// CHECK:STDOUT: %.loc32_4.1: ref %C = deref %c.ref
// CHECK:STDOUT: %F.ref.loc32: %F.type.3 = name_ref F, @C.%F.decl [template = constants.%F.3]
// CHECK:STDOUT: %.loc32_7: = bound_method %.loc32_4.1, %F.ref.loc32
-// CHECK:STDOUT: %.loc32_4.2: %.11 = addr_of %.loc32_4.1
+// CHECK:STDOUT: %.loc32_4.2: %.13 = addr_of %.loc32_4.1
// CHECK:STDOUT: %F.call.loc32: init %.2 = call %.loc32_7(%.loc32_4.2)
-// CHECK:STDOUT: %d.ref: %.14 = name_ref d, %d
+// CHECK:STDOUT: %d.ref: %.17 = name_ref d, %d
// CHECK:STDOUT: %.loc33_4.1: ref %D = deref %d.ref
// CHECK:STDOUT: %F.ref.loc33: %F.type.2 = name_ref F, @B.%F.decl [template = constants.%F.2]
// CHECK:STDOUT: %.loc33_7: = bound_method %.loc33_4.1, %F.ref.loc33
-// CHECK:STDOUT: %.loc33_4.2: %.14 = addr_of %.loc33_4.1
+// CHECK:STDOUT: %.loc33_4.2: %.17 = addr_of %.loc33_4.1
// CHECK:STDOUT: %.loc33_9.1: ref %D = deref %.loc33_4.2
// CHECK:STDOUT: %.loc33_9.2: ref %B = class_element_access %.loc33_9.1, element0
-// CHECK:STDOUT: %.loc33_9.3: %.6 = addr_of %.loc33_9.2
-// CHECK:STDOUT: %.loc33_9.4: %.6 = converted %.loc33_4.2, %.loc33_9.3
+// CHECK:STDOUT: %.loc33_9.3: %.7 = addr_of %.loc33_9.2
+// CHECK:STDOUT: %.loc33_9.4: %.7 = converted %.loc33_4.2, %.loc33_9.3
// CHECK:STDOUT: %F.call.loc33: init %.2 = call %.loc33_7(%.loc33_9.4)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
diff --git a/toolchain/check/testdata/class/basic.carbon b/toolchain/check/testdata/class/basic.carbon
index f1e23316f8f1c..89abbbb1aee8a 100644
--- a/toolchain/check/testdata/class/basic.carbon
+++ b/toolchain/check/testdata/class/basic.carbon
@@ -39,10 +39,11 @@ fn Run() -> i32 {
// CHECK:STDOUT: %G: %G.type = struct_value () [template]
// CHECK:STDOUT: %.2: type = unbound_element_type %Class, i32 [template]
// CHECK:STDOUT: %.3: type = struct_type {.k: i32} [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
// CHECK:STDOUT: %Run.type: type = fn_type @Run [template]
// CHECK:STDOUT: %Run: %Run.type = struct_value () [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
-// CHECK:STDOUT: %.5: i32 = int_literal 4 [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.6: i32 = int_literal 4 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -114,6 +115,7 @@ fn Run() -> i32 {
// CHECK:STDOUT: %.loc18_10.1: type = value_of_initializer %int.make_type_32.loc18 [template = i32]
// CHECK:STDOUT: %.loc18_10.2: type = converted %int.make_type_32.loc18, %.loc18_10.1 [template = i32]
// CHECK:STDOUT: %.loc18_8: %.2 = field_decl k, element0 [template]
+// CHECK:STDOUT: %.loc19: = complete_type_witness %.3 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%Class
@@ -140,7 +142,7 @@ fn Run() -> i32 {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Class.ref: type = name_ref Class, file.%Class.decl [template = constants.%Class]
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, @Class.%F.decl [template = constants.%F]
-// CHECK:STDOUT: %.loc26_18: i32 = int_literal 4 [template = constants.%.5]
+// CHECK:STDOUT: %.loc26_18: i32 = int_literal 4 [template = constants.%.6]
// CHECK:STDOUT: %F.call: init i32 = call %F.ref(%.loc26_18)
// CHECK:STDOUT: %.loc26_20.1: i32 = value_of_initializer %F.call
// CHECK:STDOUT: %.loc26_20.2: i32 = converted %F.call, %.loc26_20.1
diff --git a/toolchain/check/testdata/class/complete_in_member_fn.carbon b/toolchain/check/testdata/class/complete_in_member_fn.carbon
index 44bfc58af4138..3cac1c2df1e67 100644
--- a/toolchain/check/testdata/class/complete_in_member_fn.carbon
+++ b/toolchain/check/testdata/class/complete_in_member_fn.carbon
@@ -25,7 +25,8 @@ class C {
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
// CHECK:STDOUT: %.2: type = unbound_element_type %C, i32 [template]
// CHECK:STDOUT: %.3: type = struct_type {.a: i32} [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -66,6 +67,7 @@ class C {
// CHECK:STDOUT: %.loc14_10.1: type = value_of_initializer %int.make_type_32.loc14 [template = i32]
// CHECK:STDOUT: %.loc14_10.2: type = converted %int.make_type_32.loc14, %.loc14_10.1 [template = i32]
// CHECK:STDOUT: %.loc14_8: %.2 = field_decl a, element0 [template]
+// CHECK:STDOUT: %.loc15: = complete_type_witness %.3 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%C
diff --git a/toolchain/check/testdata/class/compound_field.carbon b/toolchain/check/testdata/class/compound_field.carbon
index 9c42115e087bb..ed0073d086c96 100644
--- a/toolchain/check/testdata/class/compound_field.carbon
+++ b/toolchain/check/testdata/class/compound_field.carbon
@@ -46,20 +46,22 @@ fn AccessBaseIndirect(p: Derived*) -> i32* {
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
// CHECK:STDOUT: %.2: type = unbound_element_type %Base, i32 [template]
// CHECK:STDOUT: %.3: type = struct_type {.a: i32, .b: i32, .c: i32} [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
// CHECK:STDOUT: %Derived: type = class_type @Derived [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
-// CHECK:STDOUT: %.5: type = unbound_element_type %Derived, %Base [template]
-// CHECK:STDOUT: %.6: type = unbound_element_type %Derived, i32 [template]
-// CHECK:STDOUT: %.7: type = struct_type {.base: %Base, .d: i32, .e: i32} [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.6: type = unbound_element_type %Derived, %Base [template]
+// CHECK:STDOUT: %.7: type = unbound_element_type %Derived, i32 [template]
+// CHECK:STDOUT: %.8: type = struct_type {.base: %Base, .d: i32, .e: i32} [template]
+// CHECK:STDOUT: %.9: = complete_type_witness %.8 [template]
// CHECK:STDOUT: %AccessDerived.type: type = fn_type @AccessDerived [template]
// CHECK:STDOUT: %AccessDerived: %AccessDerived.type = struct_value () [template]
-// CHECK:STDOUT: %.8: type = struct_type {.base: %.4, .d: i32, .e: i32} [template]
-// CHECK:STDOUT: %.9: type = ptr_type %.8 [template]
-// CHECK:STDOUT: %.10: type = ptr_type %.7 [template]
+// CHECK:STDOUT: %.10: type = struct_type {.base: %.5, .d: i32, .e: i32} [template]
+// CHECK:STDOUT: %.11: type = ptr_type %.10 [template]
+// CHECK:STDOUT: %.12: type = ptr_type %.8 [template]
// CHECK:STDOUT: %AccessBase.type: type = fn_type @AccessBase [template]
// CHECK:STDOUT: %AccessBase: %AccessBase.type = struct_value () [template]
-// CHECK:STDOUT: %.11: type = ptr_type %Derived [template]
-// CHECK:STDOUT: %.12: type = ptr_type i32 [template]
+// CHECK:STDOUT: %.13: type = ptr_type %Derived [template]
+// CHECK:STDOUT: %.14: type = ptr_type i32 [template]
// CHECK:STDOUT: %AccessDerivedIndirect.type: type = fn_type @AccessDerivedIndirect [template]
// CHECK:STDOUT: %AccessDerivedIndirect: %AccessDerivedIndirect.type = struct_value () [template]
// CHECK:STDOUT: %AccessBaseIndirect.type: type = fn_type @AccessBaseIndirect [template]
@@ -114,25 +116,25 @@ fn AccessBaseIndirect(p: Derived*) -> i32* {
// CHECK:STDOUT: }
// CHECK:STDOUT: %AccessDerivedIndirect.decl: %AccessDerivedIndirect.type = fn_decl @AccessDerivedIndirect [template = constants.%AccessDerivedIndirect] {
// CHECK:STDOUT: %Derived.ref.loc32: type = name_ref Derived, %Derived.decl [template = constants.%Derived]
-// CHECK:STDOUT: %.loc32_36: type = ptr_type %Derived [template = constants.%.11]
-// CHECK:STDOUT: %p.loc32_26.1: %.11 = param p, runtime_param0
-// CHECK:STDOUT: @AccessDerivedIndirect.%p: %.11 = bind_name p, %p.loc32_26.1
+// CHECK:STDOUT: %.loc32_36: type = ptr_type %Derived [template = constants.%.13]
+// CHECK:STDOUT: %p.loc32_26.1: %.13 = param p, runtime_param0
+// CHECK:STDOUT: @AccessDerivedIndirect.%p: %.13 = bind_name p, %p.loc32_26.1
// CHECK:STDOUT: %int.make_type_32.loc32: init type = call constants.%Int32() [template = i32]
// CHECK:STDOUT: %.loc32_45.1: type = value_of_initializer %int.make_type_32.loc32 [template = i32]
// CHECK:STDOUT: %.loc32_45.2: type = converted %int.make_type_32.loc32, %.loc32_45.1 [template = i32]
-// CHECK:STDOUT: %.loc32_45.3: type = ptr_type i32 [template = constants.%.12]
-// CHECK:STDOUT: @AccessDerivedIndirect.%return: ref %.12 = var
+// CHECK:STDOUT: %.loc32_45.3: type = ptr_type i32 [template = constants.%.14]
+// CHECK:STDOUT: @AccessDerivedIndirect.%return: ref %.14 = var
// CHECK:STDOUT: }
// CHECK:STDOUT: %AccessBaseIndirect.decl: %AccessBaseIndirect.type = fn_decl @AccessBaseIndirect [template = constants.%AccessBaseIndirect] {
// CHECK:STDOUT: %Derived.ref.loc36: type = name_ref Derived, %Derived.decl [template = constants.%Derived]
-// CHECK:STDOUT: %.loc36_33: type = ptr_type %Derived [template = constants.%.11]
-// CHECK:STDOUT: %p.loc36_23.1: %.11 = param p, runtime_param0
-// CHECK:STDOUT: @AccessBaseIndirect.%p: %.11 = bind_name p, %p.loc36_23.1
+// CHECK:STDOUT: %.loc36_33: type = ptr_type %Derived [template = constants.%.13]
+// CHECK:STDOUT: %p.loc36_23.1: %.13 = param p, runtime_param0
+// CHECK:STDOUT: @AccessBaseIndirect.%p: %.13 = bind_name p, %p.loc36_23.1
// CHECK:STDOUT: %int.make_type_32.loc36: init type = call constants.%Int32() [template = i32]
// CHECK:STDOUT: %.loc36_42.1: type = value_of_initializer %int.make_type_32.loc36 [template = i32]
// CHECK:STDOUT: %.loc36_42.2: type = converted %int.make_type_32.loc36, %.loc36_42.1 [template = i32]
-// CHECK:STDOUT: %.loc36_42.3: type = ptr_type i32 [template = constants.%.12]
-// CHECK:STDOUT: @AccessBaseIndirect.%return: ref %.12 = var
+// CHECK:STDOUT: %.loc36_42.3: type = ptr_type i32 [template = constants.%.14]
+// CHECK:STDOUT: @AccessBaseIndirect.%return: ref %.14 = var
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -149,6 +151,7 @@ fn AccessBaseIndirect(p: Derived*) -> i32* {
// CHECK:STDOUT: %.loc14_10.1: type = value_of_initializer %int.make_type_32.loc14 [template = i32]
// CHECK:STDOUT: %.loc14_10.2: type = converted %int.make_type_32.loc14, %.loc14_10.1 [template = i32]
// CHECK:STDOUT: %.loc14_8: %.2 = field_decl c, element2 [template]
+// CHECK:STDOUT: %.loc15: = complete_type_witness %.3 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%Base
@@ -159,15 +162,16 @@ fn AccessBaseIndirect(p: Derived*) -> i32* {
// CHECK:STDOUT:
// CHECK:STDOUT: class @Derived {
// CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base]
-// CHECK:STDOUT: %.loc18: %.5 = base_decl %Base, element0 [template]
+// CHECK:STDOUT: %.loc18: %.6 = base_decl %Base, element0 [template]
// CHECK:STDOUT: %int.make_type_32.loc20: init type = call constants.%Int32() [template = i32]
// CHECK:STDOUT: %.loc20_10.1: type = value_of_initializer %int.make_type_32.loc20 [template = i32]
// CHECK:STDOUT: %.loc20_10.2: type = converted %int.make_type_32.loc20, %.loc20_10.1 [template = i32]
-// CHECK:STDOUT: %.loc20_8: %.6 = field_decl d, element1 [template]
+// CHECK:STDOUT: %.loc20_8: %.7 = field_decl d, element1 [template]
// CHECK:STDOUT: %int.make_type_32.loc21: init type = call constants.%Int32() [template = i32]
// CHECK:STDOUT: %.loc21_10.1: type = value_of_initializer %int.make_type_32.loc21 [template = i32]
// CHECK:STDOUT: %.loc21_10.2: type = converted %int.make_type_32.loc21, %.loc21_10.1 [template = i32]
-// CHECK:STDOUT: %.loc21_8: %.6 = field_decl e, element2 [template]
+// CHECK:STDOUT: %.loc21_8: %.7 = field_decl e, element2 [template]
+// CHECK:STDOUT: %.loc22: = complete_type_witness %.8 [template = constants.%.9]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%Derived
@@ -183,7 +187,7 @@ fn AccessBaseIndirect(p: Derived*) -> i32* {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %d.ref.loc25_10: %Derived = name_ref d, %d
// CHECK:STDOUT: %Derived.ref: type = name_ref Derived, file.%Derived.decl [template = constants.%Derived]
-// CHECK:STDOUT: %d.ref.loc25_20: %.6 = name_ref d, @Derived.%.loc20_8 [template = @Derived.%.loc20_8]
+// CHECK:STDOUT: %d.ref.loc25_20: %.7 = name_ref d, @Derived.%.loc20_8 [template = @Derived.%.loc20_8]
// CHECK:STDOUT: %.loc25_11.1: ref i32 = class_element_access %d.ref.loc25_10, element1
// CHECK:STDOUT: %.loc25_11.2: i32 = bind_value %.loc25_11.1
// CHECK:STDOUT: return %.loc25_11.2
@@ -201,27 +205,27 @@ fn AccessBaseIndirect(p: Derived*) -> i32* {
// CHECK:STDOUT: return %.loc29_11.4
// CHECK:STDOUT: }
// CHECK:STDOUT:
-// CHECK:STDOUT: fn @AccessDerivedIndirect(%p: %.11) -> %.12 {
+// CHECK:STDOUT: fn @AccessDerivedIndirect(%p: %.13) -> %.14 {
// CHECK:STDOUT: !entry:
-// CHECK:STDOUT: %p.ref: %.11 = name_ref p, %p
+// CHECK:STDOUT: %p.ref: %.13 = name_ref p, %p
// CHECK:STDOUT: %Derived.ref: type = name_ref Derived, file.%Derived.decl [template = constants.%Derived]
-// CHECK:STDOUT: %d.ref: %.6 = name_ref d, @Derived.%.loc20_8 [template = @Derived.%.loc20_8]
+// CHECK:STDOUT: %d.ref: %.7 = name_ref d, @Derived.%.loc20_8 [template = @Derived.%.loc20_8]
// CHECK:STDOUT: %.loc33_12.1: ref %Derived = deref %p.ref
// CHECK:STDOUT: %.loc33_12.2: ref i32 = class_element_access %.loc33_12.1, element1
-// CHECK:STDOUT: %.loc33_10: %.12 = addr_of %.loc33_12.2
+// CHECK:STDOUT: %.loc33_10: %.14 = addr_of %.loc33_12.2
// CHECK:STDOUT: return %.loc33_10
// CHECK:STDOUT: }
// CHECK:STDOUT:
-// CHECK:STDOUT: fn @AccessBaseIndirect(%p: %.11) -> %.12 {
+// CHECK:STDOUT: fn @AccessBaseIndirect(%p: %.13) -> %.14 {
// CHECK:STDOUT: !entry:
-// CHECK:STDOUT: %p.ref: %.11 = name_ref p, %p
+// CHECK:STDOUT: %p.ref: %.13 = name_ref p, %p
// CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base]
// CHECK:STDOUT: %b.ref: %.2 = name_ref b, @Base.%.loc13_8 [template = @Base.%.loc13_8]
// CHECK:STDOUT: %.loc37_12.1: ref %Derived = deref %p.ref
// CHECK:STDOUT: %.loc37_12.2: ref %Base = class_element_access %.loc37_12.1, element0
// CHECK:STDOUT: %.loc37_12.3: ref %Base = converted %.loc37_12.1, %.loc37_12.2
// CHECK:STDOUT: %.loc37_12.4: ref i32 = class_element_access %.loc37_12.3, element1
-// CHECK:STDOUT: %.loc37_10: %.12 = addr_of %.loc37_12.4
+// CHECK:STDOUT: %.loc37_10: %.14 = addr_of %.loc37_12.4
// CHECK:STDOUT: return %.loc37_10
// CHECK:STDOUT: }
// CHECK:STDOUT:
diff --git a/toolchain/check/testdata/class/cross_package_import.carbon b/toolchain/check/testdata/class/cross_package_import.carbon
index a191e9cd4d47e..a4079d9c7d32e 100644
--- a/toolchain/check/testdata/class/cross_package_import.carbon
+++ b/toolchain/check/testdata/class/cross_package_import.carbon
@@ -114,6 +114,7 @@ var c: Other.C = {};
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %C: type = class_type @C [template]
// CHECK:STDOUT: %.1: type = struct_type {} [template]
+// CHECK:STDOUT: %.2: = complete_type_witness %.1 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -139,6 +140,8 @@ var c: Other.C = {};
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @C {
+// CHECK:STDOUT: %.loc4: = complete_type_witness %.1 [template = constants.%.2]
+// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%C
// CHECK:STDOUT: }
@@ -213,8 +216,9 @@ var c: Other.C = {};
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %C: type = class_type @C [template]
// CHECK:STDOUT: %.1: type = struct_type {} [template]
-// CHECK:STDOUT: %.2: type = tuple_type () [template]
-// CHECK:STDOUT: %.3: type = ptr_type %.1 [template]
+// CHECK:STDOUT: %.2: = complete_type_witness %.1 [template]
+// CHECK:STDOUT: %.3: type = tuple_type () [template]
+// CHECK:STDOUT: %.4: type = ptr_type %.1 [template]
// CHECK:STDOUT: %struct: %C = struct_value () [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -318,8 +322,9 @@ var c: Other.C = {};
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %C: type = class_type @C [template]
// CHECK:STDOUT: %.1: type = struct_type {} [template]
-// CHECK:STDOUT: %.2: type = tuple_type () [template]
-// CHECK:STDOUT: %.3: type = ptr_type %.1 [template]
+// CHECK:STDOUT: %.2: = complete_type_witness %.1 [template]
+// CHECK:STDOUT: %.3: type = tuple_type () [template]
+// CHECK:STDOUT: %.4: type = ptr_type %.1 [template]
// CHECK:STDOUT: %struct: %C = struct_value () [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -377,8 +382,9 @@ var c: Other.C = {};
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %C: type = class_type @C [template]
// CHECK:STDOUT: %.1: type = struct_type {} [template]
-// CHECK:STDOUT: %.2: type = tuple_type () [template]
-// CHECK:STDOUT: %.3: type = ptr_type %.1 [template]
+// CHECK:STDOUT: %.2: = complete_type_witness %.1 [template]
+// CHECK:STDOUT: %.3: type = tuple_type () [template]
+// CHECK:STDOUT: %.4: type = ptr_type %.1 [template]
// CHECK:STDOUT: %struct: %C = struct_value () [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
diff --git a/toolchain/check/testdata/class/derived_to_base.carbon b/toolchain/check/testdata/class/derived_to_base.carbon
index f639a02da413e..703a9501b15af 100644
--- a/toolchain/check/testdata/class/derived_to_base.carbon
+++ b/toolchain/check/testdata/class/derived_to_base.carbon
@@ -47,26 +47,29 @@ fn ConvertInit() {
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
// CHECK:STDOUT: %.2: type = unbound_element_type %A, i32 [template]
// CHECK:STDOUT: %.3: type = struct_type {.a: i32} [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
// CHECK:STDOUT: %B: type = class_type @B [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
-// CHECK:STDOUT: %.5: type = unbound_element_type %B, %A [template]
-// CHECK:STDOUT: %.6: type = unbound_element_type %B, i32 [template]
-// CHECK:STDOUT: %.7: type = struct_type {.base: %A, .b: i32} [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.6: type = unbound_element_type %B, %A [template]
+// CHECK:STDOUT: %.7: type = unbound_element_type %B, i32 [template]
+// CHECK:STDOUT: %.8: type = struct_type {.base: %A, .b: i32} [template]
+// CHECK:STDOUT: %.9: = complete_type_witness %.8 [template]
// CHECK:STDOUT: %C: type = class_type @C [template]
-// CHECK:STDOUT: %.8: type = struct_type {.base: %.4, .b: i32} [template]
-// CHECK:STDOUT: %.9: type = ptr_type %.8 [template]
-// CHECK:STDOUT: %.10: type = ptr_type %.7 [template]
-// CHECK:STDOUT: %.11: type = unbound_element_type %C, %B [template]
-// CHECK:STDOUT: %.12: type = unbound_element_type %C, i32 [template]
-// CHECK:STDOUT: %.13: type = struct_type {.base: %B, .c: i32} [template]
-// CHECK:STDOUT: %.14: type = ptr_type %C [template]
-// CHECK:STDOUT: %.15: type = ptr_type %B [template]
+// CHECK:STDOUT: %.10: type = struct_type {.base: %.5, .b: i32} [template]
+// CHECK:STDOUT: %.11: type = ptr_type %.10 [template]
+// CHECK:STDOUT: %.12: type = ptr_type %.8 [template]
+// CHECK:STDOUT: %.13: type = unbound_element_type %C, %B [template]
+// CHECK:STDOUT: %.14: type = unbound_element_type %C, i32 [template]
+// CHECK:STDOUT: %.15: type = struct_type {.base: %B, .c: i32} [template]
+// CHECK:STDOUT: %.16: = complete_type_witness %.15 [template]
+// CHECK:STDOUT: %.17: type = ptr_type %C [template]
+// CHECK:STDOUT: %.18: type = ptr_type %B [template]
// CHECK:STDOUT: %ConvertCToB.type: type = fn_type @ConvertCToB [template]
// CHECK:STDOUT: %ConvertCToB: %ConvertCToB.type = struct_value () [template]
-// CHECK:STDOUT: %.16: type = struct_type {.base: %.10, .c: i32} [template]
-// CHECK:STDOUT: %.17: type = ptr_type %.16 [template]
-// CHECK:STDOUT: %.18: type = ptr_type %.13 [template]
-// CHECK:STDOUT: %.19: type = ptr_type %A [template]
+// CHECK:STDOUT: %.19: type = struct_type {.base: %.12, .c: i32} [template]
+// CHECK:STDOUT: %.20: type = ptr_type %.19 [template]
+// CHECK:STDOUT: %.21: type = ptr_type %.15 [template]
+// CHECK:STDOUT: %.22: type = ptr_type %A [template]
// CHECK:STDOUT: %ConvertBToA.type: type = fn_type @ConvertBToA [template]
// CHECK:STDOUT: %ConvertBToA: %ConvertBToA.type = struct_value () [template]
// CHECK:STDOUT: %ConvertCToA.type: type = fn_type @ConvertCToA [template]
@@ -77,14 +80,14 @@ fn ConvertInit() {
// CHECK:STDOUT: %ConvertRef: %ConvertRef.type = struct_value () [template]
// CHECK:STDOUT: %ConvertInit.type: type = fn_type @ConvertInit [template]
// CHECK:STDOUT: %ConvertInit: %ConvertInit.type = struct_value () [template]
-// CHECK:STDOUT: %.20: i32 = int_literal 1 [template]
-// CHECK:STDOUT: %.21: i32 = int_literal 2 [template]
-// CHECK:STDOUT: %.22: type = struct_type {.base: %.3, .b: i32} [template]
-// CHECK:STDOUT: %.23: i32 = int_literal 3 [template]
-// CHECK:STDOUT: %.24: type = struct_type {.base: %.22, .c: i32} [template]
-// CHECK:STDOUT: %struct.1: %A = struct_value (%.20) [template]
-// CHECK:STDOUT: %struct.2: %B = struct_value (%struct.1, %.21) [template]
-// CHECK:STDOUT: %struct.3: %C = struct_value (%struct.2, %.23) [template]
+// CHECK:STDOUT: %.23: i32 = int_literal 1 [template]
+// CHECK:STDOUT: %.24: i32 = int_literal 2 [template]
+// CHECK:STDOUT: %.25: type = struct_type {.base: %.3, .b: i32} [template]
+// CHECK:STDOUT: %.26: i32 = int_literal 3 [template]
+// CHECK:STDOUT: %.27: type = struct_type {.base: %.25, .c: i32} [template]
+// CHECK:STDOUT: %struct.1: %A = struct_value (%.23) [template]
+// CHECK:STDOUT: %struct.2: %B = struct_value (%struct.1, %.24) [template]
+// CHECK:STDOUT: %struct.3: %C = struct_value (%struct.2, %.26) [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -121,30 +124,30 @@ fn ConvertInit() {
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {}
// CHECK:STDOUT: %ConvertCToB.decl: %ConvertCToB.type = fn_decl @ConvertCToB [template = constants.%ConvertCToB] {
// CHECK:STDOUT: %C.ref.loc25: type = name_ref C, %C.decl [template = constants.%C]
-// CHECK:STDOUT: %.loc25_20: type = ptr_type %C [template = constants.%.14]
-// CHECK:STDOUT: %p.loc25_16.1: %.14 = param p, runtime_param0
-// CHECK:STDOUT: @ConvertCToB.%p: %.14 = bind_name p, %p.loc25_16.1
+// CHECK:STDOUT: %.loc25_20: type = ptr_type %C [template = constants.%.17]
+// CHECK:STDOUT: %p.loc25_16.1: %.17 = param p, runtime_param0
+// CHECK:STDOUT: @ConvertCToB.%p: %.17 = bind_name p, %p.loc25_16.1
// CHECK:STDOUT: %B.ref.loc25: type = name_ref B, %B.decl [template = constants.%B]
-// CHECK:STDOUT: %.loc25_27: type = ptr_type %B [template = constants.%.15]
-// CHECK:STDOUT: @ConvertCToB.%return: ref %.15 = var
+// CHECK:STDOUT: %.loc25_27: type = ptr_type %B [template = constants.%.18]
+// CHECK:STDOUT: @ConvertCToB.%return: ref %.18 = var
// CHECK:STDOUT: }
// CHECK:STDOUT: %ConvertBToA.decl: %ConvertBToA.type = fn_decl @ConvertBToA [template = constants.%ConvertBToA] {
// CHECK:STDOUT: %B.ref.loc26: type = name_ref B, %B.decl [template = constants.%B]
-// CHECK:STDOUT: %.loc26_20: type = ptr_type %B [template = constants.%.15]
-// CHECK:STDOUT: %p.loc26_16.1: %.15 = param p, runtime_param0
-// CHECK:STDOUT: @ConvertBToA.%p: %.15 = bind_name p, %p.loc26_16.1
+// CHECK:STDOUT: %.loc26_20: type = ptr_type %B [template = constants.%.18]
+// CHECK:STDOUT: %p.loc26_16.1: %.18 = param p, runtime_param0
+// CHECK:STDOUT: @ConvertBToA.%p: %.18 = bind_name p, %p.loc26_16.1
// CHECK:STDOUT: %A.ref.loc26: type = name_ref A, %A.decl [template = constants.%A]
-// CHECK:STDOUT: %.loc26_27: type = ptr_type %A [template = constants.%.19]
-// CHECK:STDOUT: @ConvertBToA.%return: ref %.19 = var
+// CHECK:STDOUT: %.loc26_27: type = ptr_type %A [template = constants.%.22]
+// CHECK:STDOUT: @ConvertBToA.%return: ref %.22 = var
// CHECK:STDOUT: }
// CHECK:STDOUT: %ConvertCToA.decl: %ConvertCToA.type = fn_decl @ConvertCToA [template = constants.%ConvertCToA] {
// CHECK:STDOUT: %C.ref.loc27: type = name_ref C, %C.decl [template = constants.%C]
-// CHECK:STDOUT: %.loc27_20: type = ptr_type %C [template = constants.%.14]
-// CHECK:STDOUT: %p.loc27_16.1: %.14 = param p, runtime_param0
-// CHECK:STDOUT: @ConvertCToA.%p: %.14 = bind_name p, %p.loc27_16.1
+// CHECK:STDOUT: %.loc27_20: type = ptr_type %C [template = constants.%.17]
+// CHECK:STDOUT: %p.loc27_16.1: %.17 = param p, runtime_param0
+// CHECK:STDOUT: @ConvertCToA.%p: %.17 = bind_name p, %p.loc27_16.1
// CHECK:STDOUT: %A.ref.loc27: type = name_ref A, %A.decl [template = constants.%A]
-// CHECK:STDOUT: %.loc27_27: type = ptr_type %A [template = constants.%.19]
-// CHECK:STDOUT: @ConvertCToA.%return: ref %.19 = var
+// CHECK:STDOUT: %.loc27_27: type = ptr_type %A [template = constants.%.22]
+// CHECK:STDOUT: @ConvertCToA.%return: ref %.22 = var
// CHECK:STDOUT: }
// CHECK:STDOUT: %ConvertValue.decl: %ConvertValue.type = fn_decl @ConvertValue [template = constants.%ConvertValue] {
// CHECK:STDOUT: %C.ref.loc29: type = name_ref C, %C.decl [template = constants.%C]
@@ -153,12 +156,12 @@ fn ConvertInit() {
// CHECK:STDOUT: }
// CHECK:STDOUT: %ConvertRef.decl: %ConvertRef.type = fn_decl @ConvertRef [template = constants.%ConvertRef] {
// CHECK:STDOUT: %C.ref.loc33: type = name_ref C, %C.decl [template = constants.%C]
-// CHECK:STDOUT: %.loc33_19: type = ptr_type %C [template = constants.%.14]
-// CHECK:STDOUT: %c.loc33_15.1: %.14 = param c, runtime_param0
-// CHECK:STDOUT: @ConvertRef.%c: %.14 = bind_name c, %c.loc33_15.1
+// CHECK:STDOUT: %.loc33_19: type = ptr_type %C [template = constants.%.17]
+// CHECK:STDOUT: %c.loc33_15.1: %.17 = param c, runtime_param0
+// CHECK:STDOUT: @ConvertRef.%c: %.17 = bind_name c, %c.loc33_15.1
// CHECK:STDOUT: %A.ref.loc33: type = name_ref A, %A.decl [template = constants.%A]
-// CHECK:STDOUT: %.loc33_26: type = ptr_type %A [template = constants.%.19]
-// CHECK:STDOUT: @ConvertRef.%return: ref %.19 = var
+// CHECK:STDOUT: %.loc33_26: type = ptr_type %A [template = constants.%.22]
+// CHECK:STDOUT: @ConvertRef.%return: ref %.22 = var
// CHECK:STDOUT: }
// CHECK:STDOUT: %ConvertInit.decl: %ConvertInit.type = fn_decl @ConvertInit [template = constants.%ConvertInit] {}
// CHECK:STDOUT: }
@@ -168,6 +171,7 @@ fn ConvertInit() {
// CHECK:STDOUT: %.loc12_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
// CHECK:STDOUT: %.loc12_10.2: type = converted %int.make_type_32, %.loc12_10.1 [template = i32]
// CHECK:STDOUT: %.loc12_8: %.2 = field_decl a, element0 [template]
+// CHECK:STDOUT: %.loc13: = complete_type_witness %.3 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%A
@@ -176,11 +180,12 @@ fn ConvertInit() {
// CHECK:STDOUT:
// CHECK:STDOUT: class @B {
// CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A]
-// CHECK:STDOUT: %.loc16: %.5 = base_decl %A, element0 [template]
+// CHECK:STDOUT: %.loc16: %.6 = base_decl %A, element0 [template]
// CHECK:STDOUT: %int.make_type_32: init type = call constants.%Int32() [template = i32]
// CHECK:STDOUT: %.loc17_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
// CHECK:STDOUT: %.loc17_10.2: type = converted %int.make_type_32, %.loc17_10.1 [template = i32]
-// CHECK:STDOUT: %.loc17_8: %.6 = field_decl b, element1 [template]
+// CHECK:STDOUT: %.loc17_8: %.7 = field_decl b, element1 [template]
+// CHECK:STDOUT: %.loc18: = complete_type_witness %.8 [template = constants.%.9]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%B
@@ -191,11 +196,12 @@ fn ConvertInit() {
// CHECK:STDOUT:
// CHECK:STDOUT: class @C {
// CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [template = constants.%B]
-// CHECK:STDOUT: %.loc21: %.11 = base_decl %B, element0 [template]
+// CHECK:STDOUT: %.loc21: %.13 = base_decl %B, element0 [template]
// CHECK:STDOUT: %int.make_type_32: init type = call constants.%Int32() [template = i32]
// CHECK:STDOUT: %.loc22_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
// CHECK:STDOUT: %.loc22_10.2: type = converted %int.make_type_32, %.loc22_10.1 [template = i32]
-// CHECK:STDOUT: %.loc22_8: %.12 = field_decl c, element1 [template]
+// CHECK:STDOUT: %.loc22_8: %.14 = field_decl c, element1 [template]
+// CHECK:STDOUT: %.loc23: = complete_type_witness %.15 [template = constants.%.16]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%C
@@ -206,34 +212,34 @@ fn ConvertInit() {
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
// CHECK:STDOUT:
-// CHECK:STDOUT: fn @ConvertCToB(%p: %.14) -> %.15 {
+// CHECK:STDOUT: fn @ConvertCToB(%p: %.17) -> %.18 {
// CHECK:STDOUT: !entry:
-// CHECK:STDOUT: %p.ref: %.14 = name_ref p, %p
+// CHECK:STDOUT: %p.ref: %.17 = name_ref p, %p
// CHECK:STDOUT: %.loc25_39.1: ref %C = deref %p.ref
// CHECK:STDOUT: %.loc25_39.2: ref %B = class_element_access %.loc25_39.1, element0
-// CHECK:STDOUT: %.loc25_39.3: %.15 = addr_of %.loc25_39.2
-// CHECK:STDOUT: %.loc25_39.4: %.15 = converted %p.ref, %.loc25_39.3
+// CHECK:STDOUT: %.loc25_39.3: %.18 = addr_of %.loc25_39.2
+// CHECK:STDOUT: %.loc25_39.4: %.18 = converted %p.ref, %.loc25_39.3
// CHECK:STDOUT: return %.loc25_39.4
// CHECK:STDOUT: }
// CHECK:STDOUT:
-// CHECK:STDOUT: fn @ConvertBToA(%p: %.15) -> %.19 {
+// CHECK:STDOUT: fn @ConvertBToA(%p: %.18) -> %.22 {
// CHECK:STDOUT: !entry:
-// CHECK:STDOUT: %p.ref: %.15 = name_ref p, %p
+// CHECK:STDOUT: %p.ref: %.18 = name_ref p, %p
// CHECK:STDOUT: %.loc26_39.1: ref %B = deref %p.ref
// CHECK:STDOUT: %.loc26_39.2: ref %A = class_element_access %.loc26_39.1, element0
-// CHECK:STDOUT: %.loc26_39.3: %.19 = addr_of %.loc26_39.2
-// CHECK:STDOUT: %.loc26_39.4: %.19 = converted %p.ref, %.loc26_39.3
+// CHECK:STDOUT: %.loc26_39.3: %.22 = addr_of %.loc26_39.2
+// CHECK:STDOUT: %.loc26_39.4: %.22 = converted %p.ref, %.loc26_39.3
// CHECK:STDOUT: return %.loc26_39.4
// CHECK:STDOUT: }
// CHECK:STDOUT:
-// CHECK:STDOUT: fn @ConvertCToA(%p: %.14) -> %.19 {
+// CHECK:STDOUT: fn @ConvertCToA(%p: %.17) -> %.22 {
// CHECK:STDOUT: !entry:
-// CHECK:STDOUT: %p.ref: %.14 = name_ref p, %p
+// CHECK:STDOUT: %p.ref: %.17 = name_ref p, %p
// CHECK:STDOUT: %.loc27_39.1: ref %C = deref %p.ref
// CHECK:STDOUT: %.loc27_39.2: ref %B = class_element_access %.loc27_39.1, element0
// CHECK:STDOUT: %.loc27_39.3: ref %A = class_element_access %.loc27_39.2, element0
-// CHECK:STDOUT: %.loc27_39.4: %.19 = addr_of %.loc27_39.3
-// CHECK:STDOUT: %.loc27_39.5: %.19 = converted %p.ref, %.loc27_39.4
+// CHECK:STDOUT: %.loc27_39.4: %.22 = addr_of %.loc27_39.3
+// CHECK:STDOUT: %.loc27_39.5: %.22 = converted %p.ref, %.loc27_39.4
// CHECK:STDOUT: return %.loc27_39.5
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -249,41 +255,41 @@ fn ConvertInit() {
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
-// CHECK:STDOUT: fn @ConvertRef(%c: %.14) -> %.19 {
+// CHECK:STDOUT: fn @ConvertRef(%c: %.17) -> %.22 {
// CHECK:STDOUT: !entry:
-// CHECK:STDOUT: %c.ref: %.14 = name_ref c, %c
+// CHECK:STDOUT: %c.ref: %.17 = name_ref c, %c
// CHECK:STDOUT: %.loc34_12: ref %C = deref %c.ref
// CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A]
// CHECK:STDOUT: %.loc34_15.1: ref %B = class_element_access %.loc34_12, element0
// CHECK:STDOUT: %.loc34_15.2: ref %A = class_element_access %.loc34_15.1, element0
// CHECK:STDOUT: %.loc34_15.3: ref %A = converted %.loc34_12, %.loc34_15.2
-// CHECK:STDOUT: %.loc34_10: %.19 = addr_of %.loc34_15.3
+// CHECK:STDOUT: %.loc34_10: %.22 = addr_of %.loc34_15.3
// CHECK:STDOUT: return %.loc34_10
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @ConvertInit() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [template = constants.%A]
-// CHECK:STDOUT: %.loc38_38: i32 = int_literal 1 [template = constants.%.20]
+// CHECK:STDOUT: %.loc38_38: i32 = int_literal 1 [template = constants.%.23]
// CHECK:STDOUT: %.loc38_39.1: %.3 = struct_literal (%.loc38_38)
-// CHECK:STDOUT: %.loc38_47: i32 = int_literal 2 [template = constants.%.21]
-// CHECK:STDOUT: %.loc38_48.1: %.22 = struct_literal (%.loc38_39.1, %.loc38_47)
-// CHECK:STDOUT: %.loc38_56: i32 = int_literal 3 [template = constants.%.23]
-// CHECK:STDOUT: %.loc38_57.1: %.24 = struct_literal (%.loc38_48.1, %.loc38_56)
+// CHECK:STDOUT: %.loc38_47: i32 = int_literal 2 [template = constants.%.24]
+// CHECK:STDOUT: %.loc38_48.1: %.25 = struct_literal (%.loc38_39.1, %.loc38_47)
+// CHECK:STDOUT: %.loc38_56: i32 = int_literal 3 [template = constants.%.26]
+// CHECK:STDOUT: %.loc38_57.1: %.27 = struct_literal (%.loc38_48.1, %.loc38_56)
// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [template = constants.%C]
// CHECK:STDOUT: %.loc38_57.2: ref %C = temporary_storage
// CHECK:STDOUT: %.loc38_57.3: ref %B = class_element_access %.loc38_57.2, element0
// CHECK:STDOUT: %.loc38_48.2: ref %A = class_element_access %.loc38_57.3, element0
// CHECK:STDOUT: %.loc38_39.2: ref i32 = class_element_access %.loc38_48.2, element0
-// CHECK:STDOUT: %.loc38_39.3: init i32 = initialize_from %.loc38_38 to %.loc38_39.2 [template = constants.%.20]
+// CHECK:STDOUT: %.loc38_39.3: init i32 = initialize_from %.loc38_38 to %.loc38_39.2 [template = constants.%.23]
// CHECK:STDOUT: %.loc38_39.4: init %A = class_init (%.loc38_39.3), %.loc38_48.2 [template = constants.%struct.1]
// CHECK:STDOUT: %.loc38_48.3: init %A = converted %.loc38_39.1, %.loc38_39.4 [template = constants.%struct.1]
// CHECK:STDOUT: %.loc38_48.4: ref i32 = class_element_access %.loc38_57.3, element1
-// CHECK:STDOUT: %.loc38_48.5: init i32 = initialize_from %.loc38_47 to %.loc38_48.4 [template = constants.%.21]
+// CHECK:STDOUT: %.loc38_48.5: init i32 = initialize_from %.loc38_47 to %.loc38_48.4 [template = constants.%.24]
// CHECK:STDOUT: %.loc38_48.6: init %B = class_init (%.loc38_48.3, %.loc38_48.5), %.loc38_57.3 [template = constants.%struct.2]
// CHECK:STDOUT: %.loc38_57.4: init %B = converted %.loc38_48.1, %.loc38_48.6 [template = constants.%struct.2]
// CHECK:STDOUT: %.loc38_57.5: ref i32 = class_element_access %.loc38_57.2, element1
-// CHECK:STDOUT: %.loc38_57.6: init i32 = initialize_from %.loc38_56 to %.loc38_57.5 [template = constants.%.23]
+// CHECK:STDOUT: %.loc38_57.6: init i32 = initialize_from %.loc38_56 to %.loc38_57.5 [template = constants.%.26]
// CHECK:STDOUT: %.loc38_57.7: init %C = class_init (%.loc38_57.4, %.loc38_57.6), %.loc38_57.2 [template = constants.%struct.3]
// CHECK:STDOUT: %.loc38_57.8: ref %C = temporary %.loc38_57.2, %.loc38_57.7
// CHECK:STDOUT: %.loc38_59: ref %C = converted %.loc38_57.1, %.loc38_57.8
diff --git a/toolchain/check/testdata/class/extend_adapt.carbon b/toolchain/check/testdata/class/extend_adapt.carbon
index 3d66737006e34..bfd62196c0698 100644
--- a/toolchain/check/testdata/class/extend_adapt.carbon
+++ b/toolchain/check/testdata/class/extend_adapt.carbon
@@ -110,7 +110,9 @@ class StructAdapter {
// CHECK:STDOUT: %AdapterMethod.type: type = fn_type @AdapterMethod [template]
// CHECK:STDOUT: %AdapterMethod: %AdapterMethod.type = struct_value () [template]
// CHECK:STDOUT: %.3: type = struct_type {.a: i32, .b: i32} [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.6: = complete_type_witness %SomeClass [template]
// CHECK:STDOUT: %TestStaticMemberFunction.type: type = fn_type @TestStaticMemberFunction [template]
// CHECK:STDOUT: %TestStaticMemberFunction: %TestStaticMemberFunction.type = struct_value () [template]
// CHECK:STDOUT: %TestAdapterMethod.type: type = fn_type @TestAdapterMethod [template]
@@ -159,6 +161,7 @@ class StructAdapter {
// CHECK:STDOUT: class @SomeClassAdapter {
// CHECK:STDOUT: %SomeClass.ref: type = name_ref SomeClass, file.%SomeClass.decl [template = constants.%SomeClass]
// CHECK:STDOUT: adapt_decl %SomeClass
+// CHECK:STDOUT: %.loc17: = complete_type_witness %SomeClass [template = constants.%.6]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%SomeClassAdapter
@@ -180,6 +183,7 @@ class StructAdapter {
// CHECK:STDOUT: %self.loc12_20.1: %SomeClassAdapter = param self, runtime_param0
// CHECK:STDOUT: %self.loc12_20.2: %SomeClassAdapter = bind_name self, %self.loc12_20.1
// CHECK:STDOUT: }
+// CHECK:STDOUT: %.loc13: = complete_type_witness %.3 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%SomeClass
@@ -220,26 +224,28 @@ class StructAdapter {
// CHECK:STDOUT: %.1: type = tuple_type () [template]
// CHECK:STDOUT: %F.1: %F.type.1 = struct_value () [template]
// CHECK:STDOUT: %.2: type = struct_type {} [template]
+// CHECK:STDOUT: %.3: = complete_type_witness %.2 [template]
// CHECK:STDOUT: %SomeClassAdapter: type = class_type @SomeClassAdapter [template]
-// CHECK:STDOUT: %.3: type = ptr_type %.2 [template]
+// CHECK:STDOUT: %.4: type = ptr_type %.2 [template]
+// CHECK:STDOUT: %.5: = complete_type_witness %SomeClass [template]
// CHECK:STDOUT: %F.type.2: type = fn_type @F.2 [template]
// CHECK:STDOUT: %F.2: %F.type.2 = struct_value () [template]
// CHECK:STDOUT: %ImplicitAs.type: type = generic_interface_type @ImplicitAs [template]
// CHECK:STDOUT: %ImplicitAs: %ImplicitAs.type = struct_value () [template]
// CHECK:STDOUT: %Dest: type = bind_symbolic_name Dest 0 [symbolic]
-// CHECK:STDOUT: %.4: type = interface_type @ImplicitAs, @ImplicitAs(%Dest) [symbolic]
-// CHECK:STDOUT: %Self.1: @ImplicitAs.%.1 (%.4) = bind_symbolic_name Self 1 [symbolic]
-// CHECK:STDOUT: %Self.2: %.4 = bind_symbolic_name Self 1 [symbolic]
+// CHECK:STDOUT: %.6: type = interface_type @ImplicitAs, @ImplicitAs(%Dest) [symbolic]
+// CHECK:STDOUT: %Self.1: @ImplicitAs.%.1 (%.6) = bind_symbolic_name Self 1 [symbolic]
+// CHECK:STDOUT: %Self.2: %.6 = bind_symbolic_name Self 1 [symbolic]
// CHECK:STDOUT: %Convert.type.1: type = fn_type @Convert, @ImplicitAs(%Dest) [symbolic]
// CHECK:STDOUT: %Convert.1: %Convert.type.1 = struct_value () [symbolic]
-// CHECK:STDOUT: %.5: type = assoc_entity_type %.4, %Convert.type.1 [symbolic]
-// CHECK:STDOUT: %.6: %.5 = assoc_entity element0, imports.%import_ref.5 [symbolic]
-// CHECK:STDOUT: %.7: type = interface_type @ImplicitAs, @ImplicitAs(%SomeClass) [template]
+// CHECK:STDOUT: %.7: type = assoc_entity_type %.6, %Convert.type.1 [symbolic]
+// CHECK:STDOUT: %.8: %.7 = assoc_entity element0, imports.%import_ref.5 [symbolic]
+// CHECK:STDOUT: %.9: type = interface_type @ImplicitAs, @ImplicitAs(%SomeClass) [template]
// CHECK:STDOUT: %Convert.type.2: type = fn_type @Convert, @ImplicitAs(%SomeClass) [template]
// CHECK:STDOUT: %Convert.2: %Convert.type.2 = struct_value () [template]
-// CHECK:STDOUT: %.8: type = assoc_entity_type %.7, %Convert.type.2 [template]
-// CHECK:STDOUT: %.9: %.8 = assoc_entity element0, imports.%import_ref.5 [template]
-// CHECK:STDOUT: %.10: %.5 = assoc_entity element0, imports.%import_ref.6 [symbolic]
+// CHECK:STDOUT: %.10: type = assoc_entity_type %.9, %Convert.type.2 [template]
+// CHECK:STDOUT: %.11: %.10 = assoc_entity element0, imports.%import_ref.5 [template]
+// CHECK:STDOUT: %.12: %.7 = assoc_entity element0, imports.%import_ref.6 [symbolic]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -256,7 +262,7 @@ class StructAdapter {
// CHECK:STDOUT: }
// CHECK:STDOUT: %import_ref.1: %ImplicitAs.type = import_ref Core//prelude/operators/as, inst+37, loaded [template = constants.%ImplicitAs]
// CHECK:STDOUT: %import_ref.2 = import_ref Core//prelude/operators/as, inst+42, unloaded
-// CHECK:STDOUT: %import_ref.3: @ImplicitAs.%.2 (%.5) = import_ref Core//prelude/operators/as, inst+59, loaded [symbolic = @ImplicitAs.%.3 (constants.%.10)]
+// CHECK:STDOUT: %import_ref.3: @ImplicitAs.%.2 (%.7) = import_ref Core//prelude/operators/as, inst+59, loaded [symbolic = @ImplicitAs.%.3 (constants.%.12)]
// CHECK:STDOUT: %import_ref.4 = import_ref Core//prelude/operators/as, inst+52, unloaded
// CHECK:STDOUT: %import_ref.5 = import_ref Core//prelude/operators/as, inst+52, unloaded
// CHECK:STDOUT: %import_ref.6 = import_ref Core//prelude/operators/as, inst+52, unloaded
@@ -283,12 +289,12 @@ class StructAdapter {
// CHECK:STDOUT: %Dest: type = bind_symbolic_name Dest 0 [symbolic = %Dest (constants.%Dest)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
-// CHECK:STDOUT: %.1: type = interface_type @ImplicitAs, @ImplicitAs(%Dest) [symbolic = %.1 (constants.%.4)]
-// CHECK:STDOUT: %Self: %.4 = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self.2)]
+// CHECK:STDOUT: %.1: type = interface_type @ImplicitAs, @ImplicitAs(%Dest) [symbolic = %.1 (constants.%.6)]
+// CHECK:STDOUT: %Self: %.6 = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self.2)]
// CHECK:STDOUT: %Convert.type: type = fn_type @Convert, @ImplicitAs(%Dest) [symbolic = %Convert.type (constants.%Convert.type.1)]
// CHECK:STDOUT: %Convert: @ImplicitAs.%Convert.type (%Convert.type.1) = struct_value () [symbolic = %Convert (constants.%Convert.1)]
-// CHECK:STDOUT: %.2: type = assoc_entity_type @ImplicitAs.%.1 (%.4), @ImplicitAs.%Convert.type (%Convert.type.1) [symbolic = %.2 (constants.%.5)]
-// CHECK:STDOUT: %.3: @ImplicitAs.%.2 (%.5) = assoc_entity element0, imports.%import_ref.5 [symbolic = %.3 (constants.%.6)]
+// CHECK:STDOUT: %.2: type = assoc_entity_type @ImplicitAs.%.1 (%.6), @ImplicitAs.%Convert.type (%Convert.type.1) [symbolic = %.2 (constants.%.7)]
+// CHECK:STDOUT: %.3: @ImplicitAs.%.2 (%.7) = assoc_entity element0, imports.%import_ref.5 [symbolic = %.3 (constants.%.8)]
// CHECK:STDOUT:
// CHECK:STDOUT: interface {
// CHECK:STDOUT: !members:
@@ -304,6 +310,7 @@ class StructAdapter {
// CHECK:STDOUT: %self.loc5_8.1: %SomeClass = param self, runtime_param0
// CHECK:STDOUT: %self.loc5_8.2: %SomeClass = bind_name self, %self.loc5_8.1
// CHECK:STDOUT: }
+// CHECK:STDOUT: %.loc6: = complete_type_witness %.2 [template = constants.%.3]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%SomeClass
@@ -313,6 +320,7 @@ class StructAdapter {
// CHECK:STDOUT: class @SomeClassAdapter {
// CHECK:STDOUT: %SomeClass.ref: type = name_ref SomeClass, file.%SomeClass.decl [template = constants.%SomeClass]
// CHECK:STDOUT: adapt_decl %SomeClass
+// CHECK:STDOUT: %.loc10: = complete_type_witness %SomeClass [template = constants.%.5]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%SomeClassAdapter
@@ -326,18 +334,18 @@ class StructAdapter {
// CHECK:STDOUT: %a.ref: %SomeClassAdapter = name_ref a, %a
// CHECK:STDOUT: %F.ref: %F.type.1 = name_ref F, @SomeClass.%F.decl [template = constants.%F.1]
// CHECK:STDOUT: %.loc23_4: = bound_method %a.ref, %F.ref
-// CHECK:STDOUT: %.loc23_6.1: type = interface_type @ImplicitAs, @ImplicitAs(constants.%SomeClass) [template = constants.%.7]
-// CHECK:STDOUT: %.loc23_6.2: %.8 = specific_constant imports.%import_ref.3, @ImplicitAs(constants.%SomeClass) [template = constants.%.9]
-// CHECK:STDOUT: %Convert.ref: %.8 = name_ref Convert, %.loc23_6.2 [template = constants.%.9]
+// CHECK:STDOUT: %.loc23_6.1: type = interface_type @ImplicitAs, @ImplicitAs(constants.%SomeClass) [template = constants.%.9]
+// CHECK:STDOUT: %.loc23_6.2: %.10 = specific_constant imports.%import_ref.3, @ImplicitAs(constants.%SomeClass) [template = constants.%.11]
+// CHECK:STDOUT: %Convert.ref: %.10 = name_ref Convert, %.loc23_6.2 [template = constants.%.11]
// CHECK:STDOUT: %.loc23_6.3: %SomeClass = converted %a.ref, [template = ]
// CHECK:STDOUT: %F.call: init %.1 = call %.loc23_4() [template = ]
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
-// CHECK:STDOUT: generic fn @Convert(constants.%Dest: type, constants.%Self.1: @ImplicitAs.%.1 (%.4)) {
+// CHECK:STDOUT: generic fn @Convert(constants.%Dest: type, constants.%Self.1: @ImplicitAs.%.1 (%.6)) {
// CHECK:STDOUT: %Dest: type = bind_symbolic_name Dest 0 [symbolic = %Dest (constants.%Dest)]
-// CHECK:STDOUT: %.1: type = interface_type @ImplicitAs, @ImplicitAs(%Dest) [symbolic = %.1 (constants.%.4)]
-// CHECK:STDOUT: %Self: %.4 = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self.2)]
+// CHECK:STDOUT: %.1: type = interface_type @ImplicitAs, @ImplicitAs(%Dest) [symbolic = %.1 (constants.%.6)]
+// CHECK:STDOUT: %Self: %.6 = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self.2)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn[%self: @Convert.%Self (%Self.2)]() -> @Convert.%Dest (%Dest);
// CHECK:STDOUT: }
@@ -356,7 +364,7 @@ class StructAdapter {
// CHECK:STDOUT:
// CHECK:STDOUT: specific @Convert(constants.%Dest, constants.%Self.1) {
// CHECK:STDOUT: %Dest => constants.%Dest
-// CHECK:STDOUT: %.1 => constants.%.4
+// CHECK:STDOUT: %.1 => constants.%.6
// CHECK:STDOUT: %Self => constants.%Self.1
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -364,12 +372,12 @@ class StructAdapter {
// CHECK:STDOUT: %Dest => constants.%SomeClass
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
-// CHECK:STDOUT: %.1 => constants.%.7
+// CHECK:STDOUT: %.1 => constants.%.9
// CHECK:STDOUT: %Self => constants.%Self.2
// CHECK:STDOUT: %Convert.type => constants.%Convert.type.2
// CHECK:STDOUT: %Convert => constants.%Convert.2
-// CHECK:STDOUT: %.2 => constants.%.8
-// CHECK:STDOUT: %.3 => constants.%.9
+// CHECK:STDOUT: %.2 => constants.%.10
+// CHECK:STDOUT: %.3 => constants.%.11
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_todo_field_access.carbon
@@ -381,26 +389,28 @@ class StructAdapter {
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
// CHECK:STDOUT: %.2: type = unbound_element_type %SomeClass, i32 [template]
// CHECK:STDOUT: %.3: type = struct_type {.a: i32, .b: i32} [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
// CHECK:STDOUT: %SomeClassAdapter: type = class_type @SomeClassAdapter [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.6: = complete_type_witness %SomeClass [template]
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
// CHECK:STDOUT: %ImplicitAs.type: type = generic_interface_type @ImplicitAs [template]
// CHECK:STDOUT: %ImplicitAs: %ImplicitAs.type = struct_value () [template]
// CHECK:STDOUT: %Dest: type = bind_symbolic_name Dest 0 [symbolic]
-// CHECK:STDOUT: %.5: type = interface_type @ImplicitAs, @ImplicitAs(%Dest) [symbolic]
-// CHECK:STDOUT: %Self.1: @ImplicitAs.%.1 (%.5) = bind_symbolic_name Self 1 [symbolic]
-// CHECK:STDOUT: %Self.2: %.5 = bind_symbolic_name Self 1 [symbolic]
+// CHECK:STDOUT: %.7: type = interface_type @ImplicitAs, @ImplicitAs(%Dest) [symbolic]
+// CHECK:STDOUT: %Self.1: @ImplicitAs.%.1 (%.7) = bind_symbolic_name Self 1 [symbolic]
+// CHECK:STDOUT: %Self.2: %.7 = bind_symbolic_name Self 1 [symbolic]
// CHECK:STDOUT: %Convert.type.1: type = fn_type @Convert, @ImplicitAs(%Dest) [symbolic]
// CHECK:STDOUT: %Convert.1: %Convert.type.1 = struct_value () [symbolic]
-// CHECK:STDOUT: %.6: type = assoc_entity_type %.5, %Convert.type.1 [symbolic]
-// CHECK:STDOUT: %.7: %.6 = assoc_entity element0, imports.%import_ref.6 [symbolic]
-// CHECK:STDOUT: %.8: type = interface_type @ImplicitAs, @ImplicitAs(%SomeClass) [template]
+// CHECK:STDOUT: %.8: type = assoc_entity_type %.7, %Convert.type.1 [symbolic]
+// CHECK:STDOUT: %.9: %.8 = assoc_entity element0, imports.%import_ref.6 [symbolic]
+// CHECK:STDOUT: %.10: type = interface_type @ImplicitAs, @ImplicitAs(%SomeClass) [template]
// CHECK:STDOUT: %Convert.type.2: type = fn_type @Convert, @ImplicitAs(%SomeClass) [template]
// CHECK:STDOUT: %Convert.2: %Convert.type.2 = struct_value () [template]
-// CHECK:STDOUT: %.9: type = assoc_entity_type %.8, %Convert.type.2 [template]
-// CHECK:STDOUT: %.10: %.9 = assoc_entity element0, imports.%import_ref.6 [template]
-// CHECK:STDOUT: %.11: %.6 = assoc_entity element0, imports.%import_ref.7 [symbolic]
+// CHECK:STDOUT: %.11: type = assoc_entity_type %.10, %Convert.type.2 [template]
+// CHECK:STDOUT: %.12: %.11 = assoc_entity element0, imports.%import_ref.6 [template]
+// CHECK:STDOUT: %.13: %.8 = assoc_entity element0, imports.%import_ref.7 [symbolic]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -419,7 +429,7 @@ class StructAdapter {
// CHECK:STDOUT: %import_ref.1: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
// CHECK:STDOUT: %import_ref.2: %ImplicitAs.type = import_ref Core//prelude/operators/as, inst+37, loaded [template = constants.%ImplicitAs]
// CHECK:STDOUT: %import_ref.3 = import_ref Core//prelude/operators/as, inst+42, unloaded
-// CHECK:STDOUT: %import_ref.4: @ImplicitAs.%.2 (%.6) = import_ref Core//prelude/operators/as, inst+59, loaded [symbolic = @ImplicitAs.%.3 (constants.%.11)]
+// CHECK:STDOUT: %import_ref.4: @ImplicitAs.%.2 (%.8) = import_ref Core//prelude/operators/as, inst+59, loaded [symbolic = @ImplicitAs.%.3 (constants.%.13)]
// CHECK:STDOUT: %import_ref.5 = import_ref Core//prelude/operators/as, inst+52, unloaded
// CHECK:STDOUT: %import_ref.6 = import_ref Core//prelude/operators/as, inst+52, unloaded
// CHECK:STDOUT: %import_ref.7 = import_ref Core//prelude/operators/as, inst+52, unloaded
@@ -450,12 +460,12 @@ class StructAdapter {
// CHECK:STDOUT: %Dest: type = bind_symbolic_name Dest 0 [symbolic = %Dest (constants.%Dest)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
-// CHECK:STDOUT: %.1: type = interface_type @ImplicitAs, @ImplicitAs(%Dest) [symbolic = %.1 (constants.%.5)]
-// CHECK:STDOUT: %Self: %.5 = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self.2)]
+// CHECK:STDOUT: %.1: type = interface_type @ImplicitAs, @ImplicitAs(%Dest) [symbolic = %.1 (constants.%.7)]
+// CHECK:STDOUT: %Self: %.7 = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self.2)]
// CHECK:STDOUT: %Convert.type: type = fn_type @Convert, @ImplicitAs(%Dest) [symbolic = %Convert.type (constants.%Convert.type.1)]
// CHECK:STDOUT: %Convert: @ImplicitAs.%Convert.type (%Convert.type.1) = struct_value () [symbolic = %Convert (constants.%Convert.1)]
-// CHECK:STDOUT: %.2: type = assoc_entity_type @ImplicitAs.%.1 (%.5), @ImplicitAs.%Convert.type (%Convert.type.1) [symbolic = %.2 (constants.%.6)]
-// CHECK:STDOUT: %.3: @ImplicitAs.%.2 (%.6) = assoc_entity element0, imports.%import_ref.6 [symbolic = %.3 (constants.%.7)]
+// CHECK:STDOUT: %.2: type = assoc_entity_type @ImplicitAs.%.1 (%.7), @ImplicitAs.%Convert.type (%Convert.type.1) [symbolic = %.2 (constants.%.8)]
+// CHECK:STDOUT: %.3: @ImplicitAs.%.2 (%.8) = assoc_entity element0, imports.%import_ref.6 [symbolic = %.3 (constants.%.9)]
// CHECK:STDOUT:
// CHECK:STDOUT: interface {
// CHECK:STDOUT: !members:
@@ -474,6 +484,7 @@ class StructAdapter {
// CHECK:STDOUT: %.loc6_10.1: type = value_of_initializer %int.make_type_32.loc6 [template = i32]
// CHECK:STDOUT: %.loc6_10.2: type = converted %int.make_type_32.loc6, %.loc6_10.1 [template = i32]
// CHECK:STDOUT: %.loc6_8: %.2 = field_decl b, element1 [template]
+// CHECK:STDOUT: %.loc7: = complete_type_witness %.3 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%SomeClass
@@ -484,6 +495,7 @@ class StructAdapter {
// CHECK:STDOUT: class @SomeClassAdapter {
// CHECK:STDOUT: %SomeClass.ref: type = name_ref SomeClass, file.%SomeClass.decl [template = constants.%SomeClass]
// CHECK:STDOUT: adapt_decl %SomeClass
+// CHECK:STDOUT: %.loc11: = complete_type_witness %SomeClass [template = constants.%.6]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%SomeClassAdapter
@@ -496,18 +508,18 @@ class StructAdapter {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %a.ref: %SomeClassAdapter = name_ref a, %a
// CHECK:STDOUT: %b.ref: %.2 = name_ref b, @SomeClass.%.loc6_8 [template = @SomeClass.%.loc6_8]
-// CHECK:STDOUT: %.loc21_11.1: type = interface_type @ImplicitAs, @ImplicitAs(constants.%SomeClass) [template = constants.%.8]
-// CHECK:STDOUT: %.loc21_11.2: %.9 = specific_constant imports.%import_ref.4, @ImplicitAs(constants.%SomeClass) [template = constants.%.10]
-// CHECK:STDOUT: %Convert.ref: %.9 = name_ref Convert, %.loc21_11.2 [template = constants.%.10]
+// CHECK:STDOUT: %.loc21_11.1: type = interface_type @ImplicitAs, @ImplicitAs(constants.%SomeClass) [template = constants.%.10]
+// CHECK:STDOUT: %.loc21_11.2: %.11 = specific_constant imports.%import_ref.4, @ImplicitAs(constants.%SomeClass) [template = constants.%.12]
+// CHECK:STDOUT: %Convert.ref: %.11 = name_ref Convert, %.loc21_11.2 [template = constants.%.12]
// CHECK:STDOUT: %.loc21_11.3: %SomeClass = converted %a.ref, [template = ]
// CHECK:STDOUT: %.loc21_11.4: i32 = class_element_access , element1 [template = ]
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
-// CHECK:STDOUT: generic fn @Convert(constants.%Dest: type, constants.%Self.1: @ImplicitAs.%.1 (%.5)) {
+// CHECK:STDOUT: generic fn @Convert(constants.%Dest: type, constants.%Self.1: @ImplicitAs.%.1 (%.7)) {
// CHECK:STDOUT: %Dest: type = bind_symbolic_name Dest 0 [symbolic = %Dest (constants.%Dest)]
-// CHECK:STDOUT: %.1: type = interface_type @ImplicitAs, @ImplicitAs(%Dest) [symbolic = %.1 (constants.%.5)]
-// CHECK:STDOUT: %Self: %.5 = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self.2)]
+// CHECK:STDOUT: %.1: type = interface_type @ImplicitAs, @ImplicitAs(%Dest) [symbolic = %.1 (constants.%.7)]
+// CHECK:STDOUT: %Self: %.7 = bind_symbolic_name Self 1 [symbolic = %Self (constants.%Self.2)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn[%self: @Convert.%Self (%Self.2)]() -> @Convert.%Dest (%Dest);
// CHECK:STDOUT: }
@@ -526,7 +538,7 @@ class StructAdapter {
// CHECK:STDOUT:
// CHECK:STDOUT: specific @Convert(constants.%Dest, constants.%Self.1) {
// CHECK:STDOUT: %Dest => constants.%Dest
-// CHECK:STDOUT: %.1 => constants.%.5
+// CHECK:STDOUT: %.1 => constants.%.7
// CHECK:STDOUT: %Self => constants.%Self.1
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -534,12 +546,12 @@ class StructAdapter {
// CHECK:STDOUT: %Dest => constants.%SomeClass
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
-// CHECK:STDOUT: %.1 => constants.%.8
+// CHECK:STDOUT: %.1 => constants.%.10
// CHECK:STDOUT: %Self => constants.%Self.2
// CHECK:STDOUT: %Convert.type => constants.%Convert.type.2
// CHECK:STDOUT: %Convert => constants.%Convert.2
-// CHECK:STDOUT: %.2 => constants.%.9
-// CHECK:STDOUT: %.3 => constants.%.10
+// CHECK:STDOUT: %.2 => constants.%.11
+// CHECK:STDOUT: %.3 => constants.%.12
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_todo_adapt_non_class.carbon
@@ -551,6 +563,7 @@ class StructAdapter {
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
// CHECK:STDOUT: %.2: type = struct_type {.a: i32, .b: i32} [template]
// CHECK:STDOUT: %.3: type = ptr_type %.2 [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.2 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -586,6 +599,7 @@ class StructAdapter {
// CHECK:STDOUT: %.loc8_30.2: type = converted %int.make_type_32.loc8_30, %.loc8_30.1 [template = i32]
// CHECK:STDOUT: %.loc8_33: type = struct_type {.a: i32, .b: i32} [template = constants.%.2]
// CHECK:STDOUT: adapt_decl %.2
+// CHECK:STDOUT: %.loc9: = complete_type_witness %.2 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%StructAdapter
diff --git a/toolchain/check/testdata/class/fail_abstract.carbon b/toolchain/check/testdata/class/fail_abstract.carbon
index 43559eaf94f42..c4ba94f9e2738 100644
--- a/toolchain/check/testdata/class/fail_abstract.carbon
+++ b/toolchain/check/testdata/class/fail_abstract.carbon
@@ -39,24 +39,26 @@ fn Access(d: Derived) -> (i32, i32) {
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
// CHECK:STDOUT: %.2: type = unbound_element_type %Abstract, i32 [template]
// CHECK:STDOUT: %.3: type = struct_type {.a: i32} [template]
+// CHECK:STDOUT: %.4: = complete_type_witness %.3 [template]
// CHECK:STDOUT: %Derived: type = class_type @Derived [template]
-// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
-// CHECK:STDOUT: %.5: type = unbound_element_type %Derived, %Abstract [template]
-// CHECK:STDOUT: %.6: type = unbound_element_type %Derived, i32 [template]
-// CHECK:STDOUT: %.7: type = struct_type {.base: %Abstract, .d: i32} [template]
+// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
+// CHECK:STDOUT: %.6: type = unbound_element_type %Derived, %Abstract [template]
+// CHECK:STDOUT: %.7: type = unbound_element_type %Derived, i32 [template]
+// CHECK:STDOUT: %.8: type = struct_type {.base: %Abstract, .d: i32} [template]
+// CHECK:STDOUT: %.9: = complete_type_witness %.8 [template]
// CHECK:STDOUT: %Make.type: type = fn_type @Make [template]
// CHECK:STDOUT: %Make: %Make.type = struct_value () [template]
-// CHECK:STDOUT: %.8: type = struct_type {.base: %.4, .d: i32} [template]
-// CHECK:STDOUT: %.9: type = ptr_type %.8 [template]
-// CHECK:STDOUT: %.10: type = ptr_type %.7 [template]
-// CHECK:STDOUT: %.11: i32 = int_literal 1 [template]
-// CHECK:STDOUT: %.12: i32 = int_literal 7 [template]
-// CHECK:STDOUT: %.13: type = struct_type {.base: %.3, .d: i32} [template]
-// CHECK:STDOUT: %.14: type = tuple_type (type, type) [template]
-// CHECK:STDOUT: %.15: type = tuple_type (i32, i32) [template]
+// CHECK:STDOUT: %.10: type = struct_type {.base: %.5, .d: i32} [template]
+// CHECK:STDOUT: %.11: type = ptr_type %.10 [template]
+// CHECK:STDOUT: %.12: type = ptr_type %.8 [template]
+// CHECK:STDOUT: %.13: i32 = int_literal 1 [template]
+// CHECK:STDOUT: %.14: i32 = int_literal 7 [template]
+// CHECK:STDOUT: %.15: type = struct_type {.base: %.3, .d: i32} [template]
+// CHECK:STDOUT: %.16: type = tuple_type (type, type) [template]
+// CHECK:STDOUT: %.17: type = tuple_type (i32, i32) [template]
// CHECK:STDOUT: %Access.type: type = fn_type @Access [template]
// CHECK:STDOUT: %Access: %Access.type = struct_value () [template]
-// CHECK:STDOUT: %.16: type = ptr_type %.15 [template]
+// CHECK:STDOUT: %.18: type = ptr_type %.17 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -95,13 +97,13 @@ fn Access(d: Derived) -> (i32, i32) {
// CHECK:STDOUT: @Access.%d: %Derived = bind_name d, %d.loc29_11.1
// CHECK:STDOUT: %int.make_type_32.loc29_27: init type = call constants.%Int32() [template = i32]
// CHECK:STDOUT: %int.make_type_32.loc29_32: init type = call constants.%Int32() [template = i32]
-// CHECK:STDOUT: %.loc29_35.1: %.14 = tuple_literal (%int.make_type_32.loc29_27, %int.make_type_32.loc29_32)
+// CHECK:STDOUT: %.loc29_35.1: %.16 = tuple_literal (%int.make_type_32.loc29_27, %int.make_type_32.loc29_32)
// CHECK:STDOUT: %.loc29_35.2: type = value_of_initializer %int.make_type_32.loc29_27 [template = i32]
// CHECK:STDOUT: %.loc29_35.3: type = converted %int.make_type_32.loc29_27, %.loc29_35.2 [template = i32]
// CHECK:STDOUT: %.loc29_35.4: type = value_of_initializer %int.make_type_32.loc29_32 [template = i32]
// CHECK:STDOUT: %.loc29_35.5: type = converted %int.make_type_32.loc29_32, %.loc29_35.4 [template = i32]
-// CHECK:STDOUT: %.loc29_35.6: type = converted %.loc29_35.1, constants.%.15 [template = constants.%.15]
-// CHECK:STDOUT: @Access.%return: ref %.15 = var
+// CHECK:STDOUT: %.loc29_35.6: type = converted %.loc29_35.1, constants.%.17 [template = constants.%.17]
+// CHECK:STDOUT: @Access.%return: ref %.17 = var
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -110,6 +112,7 @@ fn Access(d: Derived) -> (i32, i32) {
// CHECK:STDOUT: %.loc12_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
// CHECK:STDOUT: %.loc12_10.2: type = converted %int.make_type_32, %.loc12_10.1 [template = i32]
// CHECK:STDOUT: %.loc12_8: %.2 = field_decl a, element0 [template]
+// CHECK:STDOUT: %.loc13: = complete_type_witness %.3 [template = constants.%.4]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%Abstract
@@ -118,11 +121,12 @@ fn Access(d: Derived) -> (i32, i32) {
// CHECK:STDOUT:
// CHECK:STDOUT: class @Derived {
// CHECK:STDOUT: %Abstract.ref: type = name_ref Abstract, file.%Abstract.decl [template = constants.%Abstract]
-// CHECK:STDOUT: %.loc16: %.5 = base_decl %Abstract, element0 [template]
+// CHECK:STDOUT: %.loc16: %.6 = base_decl %Abstract, element0 [template]
// CHECK:STDOUT: %int.make_type_32: init type = call constants.%Int32() [template = i32]
// CHECK:STDOUT: %.loc18_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
// CHECK:STDOUT: %.loc18_10.2: type = converted %int.make_type_32, %.loc18_10.1 [template = i32]
-// CHECK:STDOUT: %.loc18_8: %.6 = field_decl d, element1 [template]
+// CHECK:STDOUT: %.loc18_8: %.7 = field_decl d, element1 [template]
+// CHECK:STDOUT: %.loc19: = complete_type_witness %.8 [template = constants.%.9]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%Derived
@@ -135,33 +139,33 @@ fn Access(d: Derived) -> (i32, i32) {
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Make() -> %return: %Derived {
// CHECK:STDOUT: !entry:
-// CHECK:STDOUT: %.loc26_25: i32 = int_literal 1 [template = constants.%.11]
+// CHECK:STDOUT: %.loc26_25: i32 = int_literal 1 [template = constants.%.13]
// CHECK:STDOUT: %.loc26_26: %.3 = struct_literal (%.loc26_25)
-// CHECK:STDOUT: %.loc26_34: i32 = int_literal 7 [template = constants.%.12]
-// CHECK:STDOUT: %.loc26_35: %.13 = struct_literal (%.loc26_26, %.loc26_34)
+// CHECK:STDOUT: %.loc26_34: i32 = int_literal 7 [template = constants.%.14]
+// CHECK:STDOUT: %.loc26_35: %.15 = struct_literal (%.loc26_26, %.loc26_34)
// CHECK:STDOUT: return to %return
// CHECK:STDOUT: }
// CHECK:STDOUT:
-// CHECK:STDOUT: fn @Access(%d: %Derived) -> %return: %.15 {
+// CHECK:STDOUT: fn @Access(%d: %Derived) -> %return: %.17 {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %d.ref.loc30_11: %Derived = name_ref d, %d
-// CHECK:STDOUT: %d.ref.loc30_12: %.6 = name_ref d, @Derived.%.loc18_8 [template = @Derived.%.loc18_8]
+// CHECK:STDOUT: %d.ref.loc30_12: %.7 = name_ref d, @Derived.%.loc18_8 [template = @Derived.%.loc18_8]
// CHECK:STDOUT: %.loc30_12.1: ref i32 = class_element_access %d.ref.loc30_11, element1
// CHECK:STDOUT: %.loc30_12.2: i32 = bind_value %.loc30_12.1
// CHECK:STDOUT: %d.ref.loc30_16: %Derived = name_ref d, %d
-// CHECK:STDOUT: %base.ref: %.5 = name_ref base, @Derived.%.loc16 [template = @Derived.%.loc16]
+// CHECK:STDOUT: %base.ref: %.6 = name_ref base, @Derived.%.loc16 [template = @Derived.%.loc16]
// CHECK:STDOUT: %.loc30_17.1: ref %Abstract = class_element_access %d.ref.loc30_16, element0
// CHECK:STDOUT: %.loc30_17.2: %Abstract = bind_value %.loc30_17.1
// CHECK:STDOUT: %a.ref: %.2 = name_ref a, @Abstract.%.loc12_8 [template = @Abstract.%.loc12_8]
// CHECK:STDOUT: %.loc30_22.1: ref i32 = class_element_access %.loc30_17.2, element0
// CHECK:STDOUT: %.loc30_22.2: i32 = bind_value %.loc30_22.1
-// CHECK:STDOUT: %.loc30_24.1: %.15 = tuple_literal (%.loc30_12.2, %.loc30_22.2)
+// CHECK:STDOUT: %.loc30_24.1: %.17 = tuple_literal (%.loc30_12.2, %.loc30_22.2)
// CHECK:STDOUT: %.loc30_24.2: ref i32 = tuple_access %return, element0
// CHECK:STDOUT: %.loc30_24.3: init i32 = initialize_from %.loc30_12.2 to %.loc30_24.2
// CHECK:STDOUT: %.loc30_24.4: ref i32 = tuple_access %return, element1
// CHECK:STDOUT: %.loc30_24.5: init i32 = initialize_from %.loc30_22.2 to %.loc30_24.4
-// CHECK:STDOUT: %.loc30_24.6: init %.15 = tuple_init (%.loc30_24.3, %.loc30_24.5) to %return
-// CHECK:STDOUT: %.loc30_25: init %.15 = converted %.loc30_24.1, %.loc30_24.6
+// CHECK:STDOUT: %.loc30_24.6: init %.17 = tuple_init (%.loc30_24.3, %.loc30_24.5) to %return
+// CHECK:STDOUT: %.loc30_25: init %.17 = converted %.loc30_24.1, %.loc30_24.6
// CHECK:STDOUT: return %.loc30_25 to %return
// CHECK:STDOUT: }
// CHECK:STDOUT:
diff --git a/toolchain/check/testdata/class/fail_adapt_bad_decl.carbon b/toolchain/check/testdata/class/fail_adapt_bad_decl.carbon
index 3f67a030456f6..ed109914262a6 100644
--- a/toolchain/check/testdata/class/fail_adapt_bad_decl.carbon
+++ b/toolchain/check/testdata/class/fail_adapt_bad_decl.carbon
@@ -189,6 +189,7 @@ class C {
// CHECK:STDOUT: %Convert.ref: %.7 = name_ref Convert, %.loc12_12.2 [template = constants.%.8]
// CHECK:STDOUT: %.loc12_12.3: type = converted %.loc12_9, [template = ]
// CHECK:STDOUT: adapt_decl
+// CHECK:STDOUT: %.loc13: = complete_type_witness [template = ]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%Bad
@@ -326,6 +327,7 @@ class C {
// CHECK:STDOUT: %Convert.ref: %.7 = name_ref Convert, %.loc12_19.2 [template = constants.%.8]
// CHECK:STDOUT: %.loc12_19.3: type = converted %.loc12_16,