Bladeren bron

Replace form insts with actions (#7100)

See
[here](https://docs.google.com/document/d/1rWcueFwIfZox6GKVGxiUG4cBzjrZ6djXiIDGyJDtrE4/edit?tab=t.0)
for the design doc.

This also removes the default value of the `result_type_inst_id`
parameter of `HandleAction`, moves it before the action in the parameter
list, and documents it. This solves two problems:
- The default made it easy to forget, leading to unnecessary
`TypeOfInst` instructions.
- When it was present, putting it after the fairly "bulky" action
argument tended to make the callsite harder to read.
Geoff Romer 3 dagen geleden
bovenliggende
commit
4c9049346d
97 gewijzigde bestanden met toevoegingen van 1169 en 822 verwijderingen
  1. 106 6
      toolchain/check/action.cpp
  2. 28 6
      toolchain/check/action.h
  3. 5 1
      toolchain/check/convert.cpp
  4. 3 1
      toolchain/check/eval.cpp
  5. 13 6
      toolchain/check/eval_inst.cpp
  6. 1 0
      toolchain/check/eval_inst.h
  7. 6 40
      toolchain/check/function.cpp
  8. 19 7
      toolchain/check/handle_binding_pattern.cpp
  9. 1 2
      toolchain/check/import_ref.cpp
  10. 6 2
      toolchain/check/inst.cpp
  11. 4 4
      toolchain/check/member_access.cpp
  12. 74 6
      toolchain/check/pattern.cpp
  13. 104 98
      toolchain/check/pattern_match.cpp
  14. 5 0
      toolchain/check/testdata/basics/raw_sem_ir/builtins.carbon
  15. 65 65
      toolchain/check/testdata/basics/raw_sem_ir/cpp_interop.carbon
  16. 10 5
      toolchain/check/testdata/basics/raw_sem_ir/multifile.carbon
  17. 10 5
      toolchain/check/testdata/basics/raw_sem_ir/multifile_with_textual_ir.carbon
  18. 224 219
      toolchain/check/testdata/basics/raw_sem_ir/non_core_interfaces.carbon
  19. 5 5
      toolchain/check/testdata/basics/raw_sem_ir/one_file.carbon
  20. 5 0
      toolchain/check/testdata/basics/raw_sem_ir/one_file_with_textual_ir.carbon
  21. 2 2
      toolchain/check/testdata/builtins/cpp/std/initializer_list/make.carbon
  22. 4 4
      toolchain/check/testdata/class/abstract/abstract.carbon
  23. 6 6
      toolchain/check/testdata/class/fail_incomplete.carbon
  24. 1 1
      toolchain/check/testdata/class/generic/basic.carbon
  25. 1 1
      toolchain/check/testdata/class/generic/init.carbon
  26. 1 1
      toolchain/check/testdata/class/generic/member_access.carbon
  27. 5 5
      toolchain/check/testdata/class/generic/member_type.carbon
  28. 1 1
      toolchain/check/testdata/class/virtual_modifiers.carbon
  29. 3 3
      toolchain/check/testdata/deduce/array.carbon
  30. 6 6
      toolchain/check/testdata/deduce/generic_type.carbon
  31. 11 11
      toolchain/check/testdata/deduce/type_operator.carbon
  32. 1 1
      toolchain/check/testdata/eval/aggregates.carbon
  33. 1 1
      toolchain/check/testdata/facet/access.carbon
  34. 2 2
      toolchain/check/testdata/facet/facet_assoc_const.carbon
  35. 5 5
      toolchain/check/testdata/for/actual.carbon
  36. 1 1
      toolchain/check/testdata/for/basic.carbon
  37. 106 37
      toolchain/check/testdata/function/call/form.carbon
  38. 8 8
      toolchain/check/testdata/function/declaration/fail_import_incomplete_return.carbon
  39. 6 6
      toolchain/check/testdata/function/declaration/ref.carbon
  40. 6 6
      toolchain/check/testdata/function/generic/deduce.carbon
  41. 1 1
      toolchain/check/testdata/function/generic/resolve_used.carbon
  42. 1 1
      toolchain/check/testdata/generic/template/unimplemented.carbon
  43. 1 1
      toolchain/check/testdata/generic/template_dependence.carbon
  44. 1 1
      toolchain/check/testdata/impl/assoc_const_self.carbon
  45. 7 6
      toolchain/check/testdata/impl/fail_todo_form_thunk.carbon
  46. 3 3
      toolchain/check/testdata/impl/forward_decls.carbon
  47. 3 3
      toolchain/check/testdata/impl/import_interface_assoc_const.carbon
  48. 2 2
      toolchain/check/testdata/impl/incomplete.carbon
  49. 2 2
      toolchain/check/testdata/impl/lookup/impl_forall.carbon
  50. 4 4
      toolchain/check/testdata/impl/lookup/import.carbon
  51. 3 3
      toolchain/check/testdata/impl/lookup/specialization_with_symbolic_rewrite.carbon
  52. 2 2
      toolchain/check/testdata/impl/use_assoc_entity.carbon
  53. 5 5
      toolchain/check/testdata/interface/generic_method.carbon
  54. 1 1
      toolchain/check/testdata/interface/require.carbon
  55. 8 8
      toolchain/check/testdata/interop/cpp/class/import/access.carbon
  56. 2 2
      toolchain/check/testdata/interop/cpp/class/import/base.carbon
  57. 2 2
      toolchain/check/testdata/interop/cpp/class/import/class.carbon
  58. 4 4
      toolchain/check/testdata/interop/cpp/class/import/method.carbon
  59. 1 1
      toolchain/check/testdata/interop/cpp/class/import/template.carbon
  60. 11 11
      toolchain/check/testdata/interop/cpp/function/import/class.carbon
  61. 1 1
      toolchain/check/testdata/interop/cpp/function/import/extern_c.carbon
  62. 10 10
      toolchain/check/testdata/interop/cpp/function/import/pointer.carbon
  63. 11 11
      toolchain/check/testdata/interop/cpp/function/import/struct.carbon
  64. 10 10
      toolchain/check/testdata/interop/cpp/function/import/union.carbon
  65. 2 2
      toolchain/check/testdata/interop/cpp/function/import/void_pointer.carbon
  66. 3 3
      toolchain/check/testdata/interop/cpp/impls/as.carbon
  67. 1 1
      toolchain/check/testdata/interop/cpp/impls/copy.carbon
  68. 2 2
      toolchain/check/testdata/interop/cpp/impls/destroy.carbon
  69. 2 2
      toolchain/check/testdata/interop/cpp/impls/implicit_as.carbon
  70. 1 1
      toolchain/check/testdata/interop/cpp/operators/arithmetic_operators.carbon
  71. 1 1
      toolchain/check/testdata/interop/cpp/template/alias_template.carbon
  72. 1 1
      toolchain/check/testdata/interop/cpp/template/class_template.carbon
  73. 1 1
      toolchain/check/testdata/interop/cpp/template/non_type_param.carbon
  74. 1 1
      toolchain/check/testdata/interop/cpp/type_alias/import.carbon
  75. 6 2
      toolchain/check/testdata/let/form.carbon
  76. 2 2
      toolchain/check/testdata/named_constraint/incomplete.carbon
  77. 1 1
      toolchain/check/testdata/named_constraint/require.carbon
  78. 4 4
      toolchain/check/testdata/namespace/imported_indirect.carbon
  79. 1 1
      toolchain/check/testdata/operators/overloaded/dec.carbon
  80. 1 1
      toolchain/check/testdata/operators/overloaded/fail_assign_non_ref.carbon
  81. 1 1
      toolchain/check/testdata/operators/overloaded/inc.carbon
  82. 1 1
      toolchain/check/testdata/operators/overloaded/index.carbon
  83. 8 8
      toolchain/check/testdata/packages/cross_package_export.carbon
  84. 2 2
      toolchain/check/testdata/where_expr/equal_rewrite.carbon
  85. 2 3
      toolchain/check/thunk.cpp
  86. 5 0
      toolchain/driver/testdata/stdin.carbon
  87. 0 5
      toolchain/lower/handle.cpp
  88. 2 21
      toolchain/lower/type.cpp
  89. 0 15
      toolchain/sem_ir/expr_info.cpp
  90. 6 1
      toolchain/sem_ir/file.cpp
  91. 9 0
      toolchain/sem_ir/formatter.cpp
  92. 25 3
      toolchain/sem_ir/inst_categories.h
  93. 4 3
      toolchain/sem_ir/inst_kind.def
  94. 5 2
      toolchain/sem_ir/inst_kind.h
  95. 1 1
      toolchain/sem_ir/pattern.cpp
  96. 88 49
      toolchain/sem_ir/typed_insts.h
  97. 13 0
      toolchain/testing/testdata/min_prelude/form.carbon

+ 106 - 6
toolchain/check/action.cpp

@@ -9,6 +9,7 @@
 #include "toolchain/check/inst.h"
 #include "toolchain/check/type.h"
 #include "toolchain/sem_ir/constant.h"
+#include "toolchain/sem_ir/copy_on_write_block.h"
 #include "toolchain/sem_ir/id_kind.h"
 #include "toolchain/sem_ir/inst.h"
 #include "toolchain/sem_ir/typed_insts.h"
@@ -24,6 +25,45 @@ auto PerformAction(Context& context, SemIR::LocId loc_id,
        .source_id = action.inst_id});
 }
 
+auto PerformAction(Context& context, SemIR::LocId loc_id,
+                   SemIR::RefineFormAction action) -> SemIR::InstId {
+  auto expr_const_id = context.constant_values().Get(action.form_id);
+  if (!expr_const_id.is_constant()) {
+    // This is an error which will be diagnosed elsewhere, so we should just
+    // get out of its way.
+    return action.form_id;
+  }
+  auto expr =
+      context.insts().Get(context.constant_values().GetInstId(expr_const_id));
+  CARBON_KIND_SWITCH(expr) {
+    case SemIR::InitForm::Kind:
+    case SemIR::RefForm::Kind:
+    case SemIR::ValueForm::Kind:
+      // Primitive forms have no form operands, so the action is a no-op.
+      return action.form_id;
+    case CARBON_KIND(SemIR::TupleValue tuple_value): {
+      SemIR::CopyOnWriteInstBlock new_inst_block(&context.sem_ir(),
+                                                 tuple_value.elements_id);
+      for (auto [i, element_id] : llvm::enumerate(
+               context.inst_blocks().Get(tuple_value.elements_id))) {
+        new_inst_block.Set(i, HandleAction<SemIR::RefineFormAction>(
+                                  context, loc_id, SemIR::FormType::TypeInstId,
+                                  {.type_id = SemIR::InstType::TypeId,
+                                   .form_id = element_id}));
+      }
+      auto new_inst_block_id = new_inst_block.GetCanonical();
+      if (new_inst_block_id == tuple_value.elements_id) {
+        return action.form_id;
+      }
+      return AddInst<SemIR::TupleValue>(context, loc_id,
+                                        {.type_id = SemIR::FormType::TypeId,
+                                         .elements_id = new_inst_block_id});
+    }
+    default:
+      CARBON_FATAL("Unexpected kind for non-dependent form constant {0}", expr);
+  }
+}
+
 static auto OperandDependence(Context& context, SemIR::ConstantId const_id)
     -> SemIR::ConstantDependence {
   // A type operand makes the instruction dependent if it is a
@@ -92,6 +132,51 @@ auto ActionIsPerformable(Context& context, SemIR::Inst action_inst) -> bool {
            SemIR::ConstantDependence::Template;
   }
 
+  if (auto refine_action = action_inst.TryAs<SemIR::RefineFormAction>()) {
+    auto form_const_id = context.constant_values().Get(refine_action->form_id);
+    auto form_id = context.constant_values().GetInstIdIfValid(form_const_id);
+    if (!form_id.has_value()) {
+      // This is an error which will be diagnosed elsewhere, so we should just
+      // get out of its way.
+      return true;
+    }
+    // A RefineFormAction can be performed if we can identify all of the
+    // subexpressions of `form_id` that are in form positions.
+    CARBON_KIND_SWITCH(context.insts().Get(form_id)) {
+      case SemIR::InitForm::Kind:
+      case SemIR::RefForm::Kind:
+      case SemIR::ValueForm::Kind:
+      case SemIR::TupleValue::Kind:
+        // These inst kinds are not rewritten by constant evaluation except to
+        // substitute values for their operands (i.e. their constant kind is
+        // WheneverPossible, Always, or AlwaysUnique), so we can identify all of
+        // their form subexpressions.
+        return true;
+      default:
+        // All other inst kinds either can't appear in a form position, or
+        // may be rewritten by constant evaluation, so we can't identify
+        // their form subexpressions unless they are already concrete.
+        return OperandDependence(context, form_const_id) ==
+               SemIR::ConstantDependence::None;
+    }
+  }
+
+  // A form-parameterized action is performable if we can see at least the top
+  // level of its form's structure (i.e. it is not an action or a splice).
+  if (auto form_parameterized_action =
+          action_inst.TryAs<SemIR::AnyFormParamAction>()) {
+    auto form_const_id =
+        context.constant_values().Get(form_parameterized_action->form_id);
+    auto form_id = context.constant_values().GetInstIdIfValid(form_const_id);
+    if (!form_id.has_value()) {
+      // This is an error which will be diagnosed elsewhere, so we should just
+      // get out of its way.
+      return true;
+    }
+    return !context.insts().Is<SemIR::RefineFormAction>(form_id) &&
+           !context.insts().Is<SemIR::SpliceInst>(form_id);
+  }
+
   return OperandDependence(context, action_inst.type_id()) <
              SemIR::ConstantDependence::Template &&
          OperandDependence(context, action_inst.arg0_and_kind()) <
@@ -179,6 +264,7 @@ auto Internal::BeginPerformDelayedAction(Context& context) -> void {
   // Note that we assume that actions don't need to create multiple blocks. If
   // this changes, we should push a region too.
   context.inst_block_stack().Push();
+  context.pattern_block_stack().Push();
 }
 
 auto Internal::EndPerformDelayedAction(Context& context,
@@ -186,19 +272,33 @@ auto Internal::EndPerformDelayedAction(Context& context,
     -> SemIR::InstId {
   // If the only created instruction is the result, then we can use it directly.
   auto contents = context.inst_block_stack().PeekCurrentBlockContents();
-  if (contents.size() == 1 && contents[0] == result_id) {
+  auto pattern_contents =
+      context.pattern_block_stack().PeekCurrentBlockContents();
+  if ((contents == llvm::ArrayRef(result_id) && pattern_contents.empty()) ||
+      (pattern_contents == llvm::ArrayRef(result_id) && contents.empty())) {
     context.inst_block_stack().PopAndDiscard();
+    context.pattern_block_stack().PopAndDiscard();
     return result_id;
   }
 
   // Otherwise, create a splice_block to represent the sequence of instructions
   // created by the action.
+  auto block_id = SemIR::InstBlockId::None;
+  if (pattern_contents.empty()) {
+    block_id = context.inst_block_stack().Pop();
+    context.pattern_block_stack().PopAndDiscard();
+  } else {
+    // TODO: pattern insts can depend on non-pattern insts, so we'll probably
+    // eventually need to support actions that produce both.
+    CARBON_CHECK(!contents.empty());
+    block_id = context.pattern_block_stack().Pop();
+    context.inst_block_stack().PopAndDiscard();
+  }
   auto result = context.insts().GetWithLocId(result_id);
-  return AddInstInNoBlock(
-      context, result.loc_id,
-      SemIR::SpliceBlock{.type_id = result.inst.type_id(),
-                         .block_id = context.inst_block_stack().Pop(),
-                         .result_id = result_id});
+  return AddInstInNoBlock(context, result.loc_id,
+                          SemIR::SpliceBlock{.type_id = result.inst.type_id(),
+                                             .block_id = block_id,
+                                             .result_id = result_id});
 }
 
 }  // namespace Carbon::Check

+ 28 - 6
toolchain/check/action.h

@@ -22,12 +22,28 @@ auto PerformAction(Context& context, SemIR::LocId loc_id,
 auto PerformAction(Context& context, SemIR::LocId loc_id,
                    SemIR::ConvertToValueAction action) -> SemIR::InstId;
 
+// Performs a form parameter pattern action. Defined in pattern.cpp.
+auto PerformAction(Context& context, SemIR::LocId loc_id,
+                   SemIR::FormParamPatternAction action) -> SemIR::InstId;
+
+// Performs an output form parameter pattern action. Defined in pattern.cpp.
+auto PerformAction(Context& context, SemIR::LocId loc_id,
+                   SemIR::OutFormParamPatternAction action) -> SemIR::InstId;
+
+// Performs a callee pattern match action. Defined in pattern_match.cpp.
+auto PerformAction(Context& context, SemIR::LocId loc_id,
+                   SemIR::CalleePatternMatchAction action) -> SemIR::InstId;
+
 // Performs a type refinement action, by creating a conversion from an
 // instruction with a template-dependent symbolic type to the corresponding
 // instantiated type.
 auto PerformAction(Context& context, SemIR::LocId loc_id,
                    SemIR::RefineTypeAction action) -> SemIR::InstId;
 
+// Performs a form refinement action.
+auto PerformAction(Context& context, SemIR::LocId loc_id,
+                   SemIR::RefineFormAction action) -> SemIR::InstId;
+
 // Determines whether the given action can be performed immediately (i.e.
 // whether it is non-template-dependent).
 auto ActionIsPerformable(Context& context, SemIR::Inst action_inst) -> bool;
@@ -62,13 +78,19 @@ auto AddDependentActionSplice(Context& context, LocT loc, InstT inst,
 // Handles a new action. If the action is not dependent, it is performed
 // immediately. Otherwise, adds the action to the enclosing template's eval
 // block and creates an instruction to splice in the result of the action.
-template <typename ActionT>
-auto HandleAction(Context& context, SemIR::LocId loc_id, ActionT action_inst,
-                  SemIR::TypeInstId result_type_inst_id =
-                      SemIR::TypeInstId::None) -> SemIR::InstId {
+// `result_type_inst_id` is the type of inst produced by the action. If not
+// known, it can be set to `None`, and a `TypeOfInst` instruction will be added
+// to act as the type of the splice.
+template <typename ActionT, typename LocIdT>
+auto HandleAction(Context& context, LocIdT loc_id,
+                  SemIR::TypeInstId result_type_inst_id, ActionT action_inst)
+    -> SemIR::InstId {
+  CARBON_CHECK(action_inst.type_id == SemIR::InstType::TypeId);
   if (!ActionIsPerformable(context, action_inst)) {
-    return AddDependentActionSplice(
-        context, SemIR::LocIdAndInst(loc_id, action_inst), result_type_inst_id);
+    return AddDependentActionSplice(context,
+                                    SemIR::LocIdAndInst::RuntimeVerified(
+                                        context.sem_ir(), loc_id, action_inst),
+                                    result_type_inst_id);
   }
 
   return PerformAction(context, loc_id, action_inst);

+ 5 - 1
toolchain/check/convert.cpp

@@ -1971,7 +1971,7 @@ auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id,
       target.kind == ConversionTarget::Value) {
     auto target_type_inst_id = context.types().GetTypeInstId(target.type_id);
     SemIR::ConvertToValueAction convert_action = {
-        .type_id = GetSingletonType(context, SemIR::InstType::TypeInstId),
+        .type_id = SemIR::InstType::TypeId,
         .inst_id = expr_id,
         .target_type_inst_id = target_type_inst_id};
     // We don't use `HandleAction` here because it would call `PerformAction`
@@ -2236,6 +2236,10 @@ auto FormExprAsForm(Context& context, SemIR::LocId loc_id,
     return Context::FormExpr::Error;
   }
 
+  form_inst_id = HandleAction<SemIR::RefineFormAction>(
+      context, loc_id, SemIR::FormType::TypeInstId,
+      {.type_id = SemIR::InstType::TypeId, .form_id = form_inst_id});
+
   auto form_const_id = context.constant_values().Get(form_inst_id);
   if (!form_const_id.is_constant()) {
     CARBON_DIAGNOSTIC(FormExprEvaluationFailure, Error,

+ 3 - 1
toolchain/check/eval.cpp

@@ -2369,7 +2369,9 @@ static auto TryEvalTypedInst(EvalContext& eval_context, SemIR::InstId inst_id,
     if constexpr (ConstantKind == SemIR::InstConstantKind::Always ||
                   ConstantKind == SemIR::InstConstantKind::WheneverPossible) {
       return MakeConstantResult(eval_context.context(), inst, phase);
-    } else if constexpr (ConstantKind == SemIR::InstConstantKind::InstAction) {
+    } else if constexpr (ConstantKind ==
+                             SemIR::InstConstantKind::ConstantInstAction ||
+                         ConstantKind == SemIR::InstConstantKind::InstAction) {
       auto result_inst_id = PerformDelayedAction(
           eval_context.context(), SemIR::LocId(inst_id), inst.As<InstT>());
       if (result_inst_id.has_value()) {

+ 13 - 6
toolchain/check/eval_inst.cpp

@@ -655,15 +655,22 @@ auto EvalConstantInst(Context& context, SemIR::SpliceInst inst)
   // being spliced. Note that `inst.inst_id` is the instruction being spliced,
   // so we need to go through another round of obtaining the constant value in
   // addition to the one performed by the eval infrastructure.
-  if (auto inst_value =
-          context.insts().TryGetAs<SemIR::InstValue>(inst.inst_id)) {
+  auto nested_inst = context.insts().Get(inst.inst_id);
+  if (auto inst_value = nested_inst.TryAs<SemIR::InstValue>()) {
     return ConstantEvalResult::Existing(
         context.constant_values().Get(inst_value->inst_id));
   }
-  // TODO: Consider creating a new `ValueOfInst` instruction analogous to
-  // `TypeOfInst` to defer determining the constant value until we know the
-  // instruction. Alternatively, produce a symbolic `SpliceInst` constant.
-  return ConstantEvalResult::NotConstant;
+  switch (nested_inst.kind().constant_kind()) {
+    case SemIR::InstConstantKind::ConstantInstAction:
+      return ConstantEvalResult::NewSamePhase(inst);
+    case SemIR::InstConstantKind::InstAction:
+      // TODO: Consider creating a new `ValueOfInst` instruction analogous to
+      // `TypeOfInst` to defer determining the constant value until we know the
+      // instruction. Alternatively, produce a symbolic `SpliceInst` constant.
+      return ConstantEvalResult::NotConstant;
+    default:
+      CARBON_FATAL("Unexpected inst kind for inst splice: {0}", nested_inst);
+  }
 }
 
 auto EvalConstantInst(Context& context, SemIR::StructAccess inst)

+ 1 - 0
toolchain/check/eval_inst.h

@@ -104,6 +104,7 @@ constexpr auto ConstantKindHasEvalConstantInst(SemIR::InstConstantKind kind)
     -> bool {
   switch (kind) {
     case SemIR::InstConstantKind::Never:
+    case SemIR::InstConstantKind::ConstantInstAction:
     case SemIR::InstConstantKind::InstAction:
     case SemIR::InstConstantKind::WheneverPossible:
     case SemIR::InstConstantKind::Always:

+ 6 - 40
toolchain/check/function.cpp

@@ -6,6 +6,7 @@
 
 #include "common/find.h"
 #include "toolchain/base/kind_switch.h"
+#include "toolchain/check/action.h"
 #include "toolchain/check/convert.h"
 #include "toolchain/check/generic.h"
 #include "toolchain/check/inst.h"
@@ -34,47 +35,12 @@ auto FindSelfPattern(Context& context,
 
 auto AddReturnPattern(Context& context, SemIR::LocId loc_id,
                       Context::FormExpr form_expr) -> SemIR::InstId {
-  auto result_id = SemIR::InstId::None;
-  auto result_type_id = SemIR::TypeId::None;
-  auto form_inst = context.insts().Get(
-      context.constant_values().GetConstantInstId(form_expr.form_inst_id));
-  CARBON_KIND_SWITCH(form_inst) {
-    case SemIR::RefForm::Kind: {
-      result_type_id = GetPatternType(context, form_expr.type_component_id);
-      result_id = AddInst<SemIR::RefReturnPattern>(context, loc_id,
-                                                   {.type_id = result_type_id});
-      break;
-    }
-    case SemIR::ValueForm::Kind: {
-      result_type_id = GetPatternType(context, form_expr.type_component_id);
-      result_id = AddInst<SemIR::ValueReturnPattern>(
-          context, loc_id, {.type_id = result_type_id});
-      break;
-    }
-    case CARBON_KIND(SemIR::InitForm _): {
-      result_type_id = GetPatternType(context, form_expr.type_component_id);
-      result_id = AddInst<SemIR::OutParamPattern>(
-          context, SemIR::LocId(form_expr.form_inst_id),
-          {.type_id = result_type_id,
-           .pretty_name_id = SemIR::NameId::ReturnSlot});
-      break;
-    }
-    case SemIR::SymbolicBinding::Kind:
-      CARBON_CHECK(
-          context.constant_values().Get(form_expr.form_inst_id).is_symbolic());
-      context.TODO(loc_id, "Support symbolic return forms");
-      result_type_id = SemIR::ErrorInst::TypeId;
-      result_id = SemIR::ErrorInst::InstId;
-      break;
-    case SemIR::ErrorInst::Kind:
-      result_type_id = SemIR::ErrorInst::TypeId;
-      result_id = SemIR::ErrorInst::InstId;
-      break;
-    default:
-      CARBON_FATAL("unexpected inst kind: {0}", form_inst);
-  }
+  auto result_type_id = GetPatternType(context, form_expr.type_component_id);
+  auto result_id = HandleAction<SemIR::OutFormParamPatternAction>(
+      context, loc_id, form_expr.type_component_inst_id,
+      {.type_id = SemIR::InstType::TypeId, .form_id = form_expr.form_inst_id});
   return AddInst<SemIR::ReturnSlotPattern>(
-      context, SemIR::LocId(form_expr.form_inst_id),
+      context, loc_id,
       {.type_id = result_type_id,
        .subpattern_id = result_id,
        .type_inst_id = form_expr.type_component_inst_id});

+ 19 - 7
toolchain/check/handle_binding_pattern.cpp

@@ -5,6 +5,7 @@
 #include <utility>
 
 #include "toolchain/base/kind_switch.h"
+#include "toolchain/check/action.h"
 #include "toolchain/check/context.h"
 #include "toolchain/check/convert.h"
 #include "toolchain/check/facet_type.h"
@@ -43,8 +44,6 @@ static auto GetLeafBindingPatternInstKind(Parse::NodeKind node_kind,
                     : SemIR::InstKind::ValueBindingPattern;
     case Parse::NodeKind::VarBindingPattern:
       return SemIR::InstKind::RefBindingPattern;
-    case Parse::NodeKind::FormBindingPattern:
-      return SemIR::InstKind::FormBindingPattern;
     default:
       CARBON_FATAL("Unexpected node kind: {0}", node_kind);
   }
@@ -301,16 +300,26 @@ static auto HandleAnyBindingPattern(Context& context, Parse::NodeId node_id,
                 context, node_id,
                 {.type_id = pattern_type_id, .pretty_name_id = name_id});
           } else if (node_kind == Parse::NodeKind::FormBindingPattern) {
-            param_pattern_id =
-                AddInst<SemIR::FormParamPattern>(context, node_id,
-                                                 {.type_id = pattern_type_id,
-                                                  .pretty_name_id = name_id,
-                                                  .form_id = form_id});
+            auto pattern_type_inst_id =
+                context.types().GetTypeInstId(pattern_type_id);
+            param_pattern_id = HandleAction<SemIR::FormParamPatternAction>(
+                context,
+                context.parse_tree()
+                    .As<Parse::NodeIdForKind<
+                        Parse::NodeKind::FormBindingPattern>>(node_id),
+                pattern_type_inst_id,
+                {.type_id = SemIR::InstType::TypeId,
+                 .form_id = form_id,
+                 .pretty_name_id = name_id});
           } else {
             param_pattern_id = AddInst<SemIR::ValueParamPattern>(
                 context, node_id,
                 {.type_id = pattern_type_id, .pretty_name_id = name_id});
           }
+          if (param_pattern_id == SemIR::ErrorInst::InstId) {
+            result_inst_id = SemIR::ErrorInst::InstId;
+            break;
+          }
           result_inst_id = make_binding_pattern(
               SemIR::WrapperBindingPattern::Kind, param_pattern_id);
           break;
@@ -330,6 +339,9 @@ static auto HandleAnyBindingPattern(Context& context, Parse::NodeId node_id,
     }
 
     case FullPatternStack::Kind::NameBindingDecl: {
+      if (node_kind == Parse::NodeKind::FormBindingPattern) {
+        return context.TODO(node_id, "support local form bindings");
+      }
       auto incomplete_diagnostic_context = [&](auto& builder) {
         CARBON_DIAGNOSTIC(IncompleteTypeInBindingDecl, Context,
                           "binding pattern has incomplete type {0} in name "

+ 1 - 2
toolchain/check/import_ref.cpp

@@ -1552,8 +1552,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
 
 template <typename ParamPatternT>
   requires SemIR::Internal::HasInstCategory<SemIR::AnyLeafParamPattern,
-                                            ParamPatternT> &&
-           (!std::same_as<ParamPatternT, SemIR::FormParamPattern>)
+                                            ParamPatternT>
 static auto TryResolveTypedInst(ImportRefResolver& resolver, ParamPatternT inst,
                                 SemIR::InstId import_inst_id) -> ResolveResult {
   auto type_const_id = GetLocalConstantId(resolver, inst.type_id);

+ 6 - 2
toolchain/check/inst.cpp

@@ -46,7 +46,9 @@ static auto FinishInst(Context& context, SemIR::InstId inst_id,
   // Template-dependent instructions are handled separately by
   // `AddDependentActionInst`.
   CARBON_CHECK(
-      inst.kind().constant_kind() != SemIR::InstConstantKind::InstAction,
+      inst.kind().constant_kind() !=
+              SemIR::InstConstantKind::ConstantInstAction &&
+          inst.kind().constant_kind() != SemIR::InstConstantKind::InstAction,
       "Use AddDependentActionInst to add an action instruction");
 
   // Keep track of dependent instructions.
@@ -63,7 +65,9 @@ auto AddInst(Context& context, SemIR::LocIdAndInst loc_id_and_inst)
       SemIR::ExprCategory::Pattern) {
     auto type_id = loc_id_and_inst.inst.type_id();
     CARBON_CHECK(type_id == SemIR::ErrorInst::TypeId ||
-                 context.types().Is<SemIR::PatternType>(type_id));
+                     context.types().Is<SemIR::PatternType>(type_id),
+                 "Unexpected kind for type {0}",
+                 context.types().GetAsInst(type_id));
     context.pattern_block_stack().AddInstId(inst_id);
   } else {
     context.inst_block_stack().AddInstId(inst_id);

+ 4 - 4
toolchain/check/member_access.cpp

@@ -464,14 +464,14 @@ auto PerformMemberAccess(Context& context, SemIR::LocId loc_id,
   // things.
   if (required) {
     return HandleAction<SemIR::AccessMemberAction>(
-        context, loc_id,
-        {.type_id = GetSingletonType(context, SemIR::InstType::TypeInstId),
+        context, loc_id, SemIR::TypeInstId::None,
+        {.type_id = SemIR::InstType::TypeId,
          .base_id = base_id,
          .name_id = name_id});
   } else {
     return HandleAction<SemIR::AccessOptionalMemberAction>(
-        context, loc_id,
-        {.type_id = GetSingletonType(context, SemIR::InstType::TypeInstId),
+        context, loc_id, SemIR::TypeInstId::None,
+        {.type_id = SemIR::InstType::TypeId,
          .base_id = base_id,
          .name_id = name_id});
   }

+ 74 - 6
toolchain/check/pattern.cpp

@@ -5,6 +5,7 @@
 #include "toolchain/check/pattern.h"
 
 #include "toolchain/base/kind_switch.h"
+#include "toolchain/check/action.h"
 #include "toolchain/check/control_flow.h"
 #include "toolchain/check/inst.h"
 #include "toolchain/check/return.h"
@@ -102,9 +103,6 @@ auto AddBindingPattern(Context& context, SemIR::LocId name_loc,
                        SemIR::AnyBindingPattern pattern) -> BindingPatternInfo {
   SemIR::InstKind bind_name_kind;
   switch (pattern.kind) {
-    case SemIR::FormBindingPattern::Kind:
-      bind_name_kind = SemIR::FormBinding::Kind;
-      break;
     case SemIR::RefBindingPattern::Kind:
       bind_name_kind = SemIR::RefBinding::Kind;
       break;
@@ -117,9 +115,6 @@ auto AddBindingPattern(Context& context, SemIR::LocId name_loc,
     case SemIR::WrapperBindingPattern::Kind: {
       auto subpattern = context.insts().Get(pattern.subpattern_id);
       CARBON_KIND_SWITCH(subpattern) {
-        case SemIR::FormParamPattern::Kind:
-          bind_name_kind = SemIR::FormBinding::Kind;
-          break;
         case SemIR::RefParamPattern::Kind:
         case SemIR::VarPattern::Kind:
           bind_name_kind = SemIR::RefBinding::Kind;
@@ -250,4 +245,77 @@ auto AddParamPattern(Context& context, SemIR::LocId loc_id,
   }
 }
 
+auto PerformAction(Context& context, SemIR::LocId loc_id,
+                   SemIR::FormParamPatternAction action) -> SemIR::InstId {
+  auto form_inst = context.insts().Get(
+      context.constant_values().GetConstantInstId(action.form_id));
+  auto type_id =
+      GetPatternType(context, GetTypeComponent(context, action.form_id));
+  CARBON_KIND_SWITCH(form_inst) {
+    case SemIR::InitForm::Kind: {
+      auto ref_param_pattern_id = AddInst(
+          context,
+          SemIR::LocIdAndInst::RuntimeVerified(
+              context.sem_ir(), loc_id,
+              SemIR::RefParamPattern{.type_id = type_id,
+                                     .pretty_name_id = action.pretty_name_id}));
+      return AddInst(context, SemIR::LocIdAndInst::RuntimeVerified(
+                                  context.sem_ir(), loc_id,
+                                  SemIR::VarPattern{
+                                      .type_id = type_id,
+                                      .subpattern_id = ref_param_pattern_id}));
+    }
+    case SemIR::RefForm::Kind: {
+      return AddInst(
+          context,
+          SemIR::LocIdAndInst::RuntimeVerified(
+              context.sem_ir(), loc_id,
+              SemIR::RefParamPattern{.type_id = type_id,
+                                     .pretty_name_id = action.pretty_name_id}));
+    }
+    case SemIR::ValueForm::Kind: {
+      return AddInst(context,
+                     SemIR::LocIdAndInst::RuntimeVerified(
+                         context.sem_ir(), loc_id,
+                         SemIR::ValueParamPattern{
+                             .type_id = type_id,
+                             .pretty_name_id = action.pretty_name_id}));
+    }
+    case SemIR::ErrorInst::Kind: {
+      return SemIR::ErrorInst::InstId;
+    }
+    default:
+      CARBON_FATAL("Unexpected param pattern form: {0}", form_inst);
+  }
+}
+
+// TODO: can we share code with FormParamPatternAction?
+auto PerformAction(Context& context, SemIR::LocId /*loc_id*/,
+                   SemIR::OutFormParamPatternAction action) -> SemIR::InstId {
+  auto form_inst = context.insts().Get(
+      context.constant_values().GetConstantInstId(action.form_id));
+  auto type_id =
+      GetPatternType(context, GetTypeComponent(context, action.form_id));
+  CARBON_KIND_SWITCH(form_inst) {
+    case SemIR::ValueForm::Kind: {
+      return AddInst<SemIR::ValueReturnPattern>(
+          context, SemIR::LocId(action.form_id), {.type_id = type_id});
+    }
+    case SemIR::RefForm::Kind: {
+      return AddInst<SemIR::RefReturnPattern>(
+          context, SemIR::LocId(action.form_id), {.type_id = type_id});
+    }
+    case CARBON_KIND(SemIR::InitForm _): {
+      return AddInst<SemIR::OutParamPattern>(
+          context, SemIR::LocId(action.form_id),
+          {.type_id = type_id, .pretty_name_id = SemIR::NameId::ReturnSlot});
+    }
+    case SemIR::ErrorInst::Kind: {
+      return SemIR::ErrorInst::InstId;
+    }
+    default:
+      CARBON_FATAL("unexpected inst kind: {0}", form_inst);
+  }
+}
+
 }  // namespace Carbon::Check

+ 104 - 98
toolchain/check/pattern_match.cpp

@@ -12,6 +12,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallVector.h"
 #include "toolchain/base/kind_switch.h"
+#include "toolchain/check/action.h"
 #include "toolchain/check/context.h"
 #include "toolchain/check/control_flow.h"
 #include "toolchain/check/convert.h"
@@ -35,8 +36,32 @@ struct CallerState {
   SemIR::SpecificId callee_specific_id;
 };
 
+// Manages the allocation of call parameter indices.
+class IndexSource {
+ public:
+  // Creates an IndexSource that will allocate indices starting from
+  // `next_index`.
+  explicit IndexSource(SemIR::CallParamIndex next_index)
+      : next_index_(next_index) {}
+
+  // Returns the index that will be allocated next.
+  auto Peek() const -> SemIR::CallParamIndex { return next_index_; }
+
+  // Allocates and returns the next index.
+  auto Allocate() -> SemIR::CallParamIndex {
+    auto result = next_index_;
+    ++next_index_.index;
+    return result;
+  }
+
+ private:
+  SemIR::CallParamIndex next_index_;
+};
+
 // State for callee-side pattern matching.
 struct CalleeState {
+  IndexSource index;
+
   // The in-progress contents of the `Call` parameters block.
   llvm::SmallVector<SemIR::InstId> call_params;
 
@@ -158,6 +183,8 @@ class MatchContext {
                  SemIR::InstId scrutinee_id, WorkItem entry) -> void;
   auto DoPreWork(State state, SemIR::TuplePattern tuple_pattern,
                  SemIR::InstId scrutinee_id, WorkItem entry) -> void;
+  auto DoPreWork(State state, SemIR::SpliceInst splice,
+                 SemIR::InstId scrutinee_id, WorkItem entry) -> void;
 
   // Do the post-work for `entry`. `entry.work` must be a `PostWork`, and
   // the pattern argument must be the value of `entry.pattern_id` in `context_`.
@@ -186,8 +213,8 @@ class MatchContext {
   // Performs the core logic of matching a variable pattern whose type is
   // `pattern_type_id`, but returns the scrutinee that its subpattern should be
   // matched with, rather than pushing it onto the worklist. This is factored
-  // out so it can be reused when handling a `FormBindingPattern` or
-  // `FormParamPattern` with an initializing form.
+  // out so it can be reused by `VarParamPattern`, which needs to do the
+  // pre-work of both a `VarPattern` and a `RefParamPattern`.
   auto DoVarPreWorkImpl(State state, SemIR::TypeId pattern_type_id,
                         SemIR::InstId scrutinee_id, WorkItem entry) const
       -> SemIR::InstId;
@@ -276,8 +303,7 @@ static auto InsertHere(Context& context, SemIR::ExprRegionId region_id)
 // given pattern. Note that this returns `NoOp` for `var` patterns, because
 // their conversion needs special handling, prior to any general-purpose
 // conversion that would use this function.
-static auto ConversionKindFor(Context& context, SemIR::Inst pattern,
-                              MatchContext::WorkItem entry)
+static auto ConversionKindFor(SemIR::Inst pattern, MatchContext::WorkItem entry)
     -> ConversionTarget::Kind {
   CARBON_KIND_SWITCH(pattern) {
     case SemIR::VarParamPattern::Kind:
@@ -298,48 +324,6 @@ static auto ConversionKindFor(Context& context, SemIR::Inst pattern,
     case SemIR::ValueBindingPattern::Kind:
     case SemIR::ValueParamPattern::Kind:
       return ConversionTarget::Value;
-    case CARBON_KIND(SemIR::FormBindingPattern form_binding_pattern): {
-      auto form_id = context.entity_names()
-                         .Get(form_binding_pattern.entity_name_id)
-                         .form_id;
-      auto form_inst = context.insts().Get(form_id);
-
-      switch (form_inst.kind()) {
-        case SemIR::InitForm::Kind:
-          context.TODO(entry.pattern_id, "Support local initializing forms");
-          [[fallthrough]];
-        case SemIR::RefForm::Kind:
-          return ConversionTarget::DurableRef;
-        case SemIR::SymbolicBinding::Kind:
-          context.TODO(entry.pattern_id, "Support symbolic form bindings");
-          [[fallthrough]];
-        case SemIR::ValueForm::Kind:
-        case SemIR::ErrorInst::Kind:
-          return ConversionTarget::Value;
-        default:
-          CARBON_FATAL("Unexpected form {0}", form_inst);
-      }
-    }
-    case CARBON_KIND(SemIR::FormParamPattern form_param_pattern): {
-      auto form_inst = context.insts().Get(form_param_pattern.form_id);
-
-      switch (form_inst.kind()) {
-        case SemIR::InitForm::Kind:
-          return ConversionTarget::NoOp;
-        case SemIR::RefForm::Kind:
-          // TODO: Figure out rules for when the argument must have a `ref` tag.
-          return entry.allow_unmarked_ref ? ConversionTarget::UnmarkedRefParam
-                                          : ConversionTarget::RefParam;
-        case SemIR::SymbolicBinding::Kind:
-          context.TODO(entry.pattern_id, "Support symbolic form params");
-          [[fallthrough]];
-        case SemIR::ErrorInst::Kind:
-        case SemIR::ValueForm::Kind:
-          return ConversionTarget::Value;
-        default:
-          CARBON_FATAL("Unexpected form {0}", form_inst);
-      }
-    }
     default:
       CARBON_FATAL("Unexpected pattern kind in {0}", pattern);
   }
@@ -388,7 +372,7 @@ auto MatchContext::DoPostWork(State state,
   auto value_id = PopResult();
 
   if (value_id.has_value()) {
-    auto conversion_kind = ConversionKindFor(context_, binding_pattern, entry);
+    auto conversion_kind = ConversionKindFor(binding_pattern, entry);
     if (!bind_name_id.has_value()) {
       // TODO: Is this appropriate, or should we perform a conversion based on
       // the category of the `_` binding first, and then separately discard the
@@ -417,8 +401,7 @@ auto MatchContext::DoPostWork(State state,
 
 // Returns the inst kind to use for the parameter corresponding to the given
 // parameter pattern.
-static auto ParamKindFor(Context& context, SemIR::Inst param_pattern,
-                         MatchContext::WorkItem entry) -> SemIR::InstKind {
+static auto ParamKindFor(SemIR::Inst param_pattern) -> SemIR::InstKind {
   CARBON_KIND_SWITCH(param_pattern) {
     case SemIR::OutParamPattern::Kind:
       return SemIR::OutParam::Kind;
@@ -427,22 +410,6 @@ static auto ParamKindFor(Context& context, SemIR::Inst param_pattern,
       return SemIR::RefParam::Kind;
     case SemIR::ValueParamPattern::Kind:
       return SemIR::ValueParam::Kind;
-    case CARBON_KIND(SemIR::FormParamPattern form_param_pattern): {
-      auto form_inst = context.insts().Get(form_param_pattern.form_id);
-      switch (form_inst.kind()) {
-        case SemIR::InitForm::Kind:
-        case SemIR::RefForm::Kind:
-          return SemIR::RefParam::Kind;
-        case SemIR::SymbolicBinding::Kind:
-          context.TODO(entry.pattern_id, "Support symbolic form params");
-          [[fallthrough]];
-        case SemIR::ErrorInst::Kind:
-        case SemIR::ValueForm::Kind:
-          return SemIR::ValueParam::Kind;
-        default:
-          CARBON_FATAL("Unexpected form {0}", form_inst);
-      }
-    }
     default:
       CARBON_FATAL("Unexpected param pattern kind: {0}", param_pattern);
   }
@@ -471,25 +438,12 @@ auto MatchContext::DoPreWork(State state, SemIR::AnyParamPattern param_pattern,
   auto pattern_type_id =
       GetSpecificPatternTypeId(state, entry.pattern_id, param_pattern.type_id);
 
-  // If `param_pattern` has initializing form, match it as a `VarPattern`
-  // before matching it as a parameter pattern.
-  switch (param_pattern.kind) {
-    case SemIR::FormParamPattern::Kind: {
-      auto form_param_pattern =
-          context_.insts().GetAs<SemIR::FormParamPattern>(entry.pattern_id);
-      if (!context_.insts().Is<SemIR::InitForm>(form_param_pattern.form_id)) {
-        break;
-      }
-      [[fallthrough]];
-    }
-    case SemIR::VarParamPattern::Kind: {
-      scrutinee_id =
-          DoVarPreWorkImpl(state, pattern_type_id, scrutinee_id, entry);
-      entry.allow_unmarked_ref = true;
-      break;
-    }
-    default:
-      break;
+  // If `param_pattern` is a `VarParamPattern`, match it as a `VarPattern` here,
+  // and then as a `RefParamPattern` below.
+  if (param_pattern.kind == SemIR::VarParamPattern::Kind) {
+    scrutinee_id =
+        DoVarPreWorkImpl(state, pattern_type_id, scrutinee_id, entry);
+    entry.allow_unmarked_ref = true;
   }
 
   CARBON_KIND_SWITCH(state) {
@@ -500,7 +454,7 @@ auto MatchContext::DoPreWork(State state, SemIR::AnyParamPattern param_pattern,
       } else {
         caller_state->call_args.push_back(
             Convert(context_, SemIR::LocId(scrutinee_id), scrutinee_id,
-                    {.kind = ConversionKindFor(context_, param_pattern, entry),
+                    {.kind = ConversionKindFor(param_pattern, entry),
                      .type_id = pattern_type_id}));
       }
       // Do not traverse farther or schedule PostWork, because the caller side
@@ -508,13 +462,13 @@ auto MatchContext::DoPreWork(State state, SemIR::AnyParamPattern param_pattern,
       break;
     }
     case CARBON_KIND(CalleeState* callee_state): {
-      SemIR::Inst param = SemIR::AnyParam{
-          .kind = ParamKindFor(context_, param_pattern, entry),
-          .type_id =
-              ExtractScrutineeType(context_.sem_ir(), param_pattern.type_id),
-          .index = SemIR::CallParamIndex(callee_state->call_params.size()),
-          .pretty_name_id = SemIR::GetPrettyNameFromPatternId(
-              context_.sem_ir(), entry.pattern_id)};
+      SemIR::Inst param =
+          SemIR::AnyParam{.kind = ParamKindFor(param_pattern),
+                          .type_id = ExtractScrutineeType(
+                              context_.sem_ir(), param_pattern.type_id),
+                          .index = callee_state->index.Allocate(),
+                          .pretty_name_id = SemIR::GetPrettyNameFromPatternId(
+                              context_.sem_ir(), entry.pattern_id)};
       auto loc_id = SemIR::LocId(entry.pattern_id);
       auto param_id = SemIR::InstId::None;
       // TODO: find a way to avoid this boilerplate.
@@ -592,7 +546,8 @@ auto MatchContext::DoPreWork(State state,
     AddAsPostWork(entry);
   }
   AddWork({.pattern_id = return_slot_pattern.subpattern_id,
-           .work = PreWork{.scrutinee_id = scrutinee_id}});
+           .work = PreWork{.scrutinee_id = scrutinee_id},
+           .allow_unmarked_ref = entry.allow_unmarked_ref});
 }
 
 auto MatchContext::DoPostWork(State state,
@@ -719,7 +674,8 @@ auto MatchContext::DoPreWork(State state, SemIR::TuplePattern tuple_pattern,
         for (auto [subpattern_id, subscrutinee_id] :
              llvm::reverse(llvm::zip_equal(subpattern_ids, subscrutinee_ids))) {
           AddWork({.pattern_id = subpattern_id,
-                   .work = PreWork{.scrutinee_id = subscrutinee_id}});
+                   .work = PreWork{.scrutinee_id = subscrutinee_id},
+                   .allow_unmarked_ref = entry.allow_unmarked_ref});
         }
       };
   if (!scrutinee_id.has_value()) {
@@ -729,7 +685,8 @@ auto MatchContext::DoPreWork(State state, SemIR::TuplePattern tuple_pattern,
     // pattern, so the subpatterns don't have a scrutinee either.
     for (auto subpattern_id : llvm::reverse(subpattern_ids)) {
       AddWork({.pattern_id = subpattern_id,
-               .work = PreWork{.scrutinee_id = SemIR::InstId::None}});
+               .work = PreWork{.scrutinee_id = SemIR::InstId::None},
+               .allow_unmarked_ref = entry.allow_unmarked_ref});
     }
     return;
   }
@@ -791,6 +748,34 @@ auto MatchContext::DoPostWork(State /*state*/,
   results_stack_.AppendToTop(tuple_value_id);
 }
 
+auto MatchContext::DoPreWork(State state, SemIR::SpliceInst splice,
+                             SemIR::InstId scrutinee_id, WorkItem entry)
+    -> void {
+  CARBON_KIND_SWITCH(state) {
+    case CARBON_KIND(CallerState* _): {
+      CARBON_FATAL("TODO: support caller-side matching of pattern splices");
+    }
+    case CARBON_KIND(ThunkState* _): {
+      CARBON_FATAL("TODO: support thunk matching of pattern splices");
+    }
+    case CARBON_KIND(LocalState* _): {
+      CARBON_FATAL("TODO: support local matching of pattern splices");
+    }
+    case CARBON_KIND(CalleeState* callee_state): {
+      CARBON_CHECK(!scrutinee_id.has_value());
+      auto result_id = HandleAction<SemIR::CalleePatternMatchAction>(
+          context_, SemIR::LocId(entry.pattern_id),
+          context_.types().GetTypeInstId(splice.type_id),
+          {.type_id = SemIR::InstType::TypeId,
+           .pattern_id = entry.pattern_id,
+           .parent_index = callee_state->index.Allocate()});
+      callee_state->call_param_patterns.push_back(entry.pattern_id);
+      callee_state->call_params.push_back(result_id);
+      results_stack_.AppendToTop(result_id);
+    }
+  }
+}
+
 auto MatchContext::DoPreWork(State state,
                              SemIR::AnyReturnPattern return_pattern,
                              SemIR::InstId /*scrutinee_id*/, WorkItem entry)
@@ -861,6 +846,10 @@ auto MatchContext::Dispatch(State state, WorkItem entry) -> void {
           DoPreWork(state, tuple_pattern, work.scrutinee_id, entry);
           break;
         }
+        case CARBON_KIND(SemIR::SpliceInst splice_inst): {
+          DoPreWork(state, splice_inst, work.scrutinee_id, entry);
+          break;
+        }
         default: {
           CARBON_FATAL("Inst kind not handled: {0}", pattern.kind());
         }
@@ -914,7 +903,7 @@ auto CalleePatternMatch(Context& context,
             .param_ranges = SemIR::Function::CallParamIndexRanges::Empty};
   }
 
-  CalleeState state;
+  CalleeState state = {.index = IndexSource(SemIR::CallParamIndex(0))};
   MatchContext match(context);
 
   // We add work to the stack in reverse so that the results will be produced
@@ -969,20 +958,37 @@ auto ThunkPatternMatch(Context& context, SemIR::InstId self_pattern_id,
     inner_args.push_back(match.MatchWithResult(
         &state,
         {.pattern_id = self_pattern_id,
-         .work = MatchContext::PreWork{.scrutinee_id = SemIR::InstId::None}}));
+         .work = MatchContext::PreWork{.scrutinee_id = SemIR::InstId::None},
+         .allow_unmarked_ref = true}));
   }
 
   for (SemIR::InstId inst_id : param_pattern_ids) {
     inner_args.push_back(match.MatchWithResult(
         &state,
         {.pattern_id = inst_id,
-         .work = MatchContext::PreWork{.scrutinee_id = SemIR::InstId::None}}));
+         .work = MatchContext::PreWork{.scrutinee_id = SemIR::InstId::None},
+         .allow_unmarked_ref = true}));
   }
 
   return {.syntactic_args = std::move(inner_args),
           .ignored_call_args = state.outer_call_args};
 }
 
+auto PerformAction(Context& context, SemIR::LocId /*loc_id*/,
+                   SemIR::CalleePatternMatchAction action) -> SemIR::InstId {
+  CalleeState state = {.index = IndexSource(action.parent_index)};
+  MatchContext match(context);
+
+  auto result_id = match.MatchWithResult(
+      &state,
+      {.pattern_id = action.pattern_id,
+       .work = MatchContext::PreWork{.scrutinee_id = SemIR::InstId::None},
+       .allow_unmarked_ref = true});
+  CARBON_CHECK(state.index.Peek().index <= action.parent_index.index + 1,
+               "TODO: add support for composite forms");
+  return result_id;
+}
+
 auto CallerPatternMatch(Context& context, SemIR::SpecificId specific_id,
                         SemIR::InstId self_pattern_id,
                         SemIR::InstBlockId param_patterns_id,

+ 5 - 0
toolchain/check/testdata/basics/raw_sem_ir/builtins.carbon

@@ -50,6 +50,11 @@
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
+// CHECK:STDOUT:     'type(inst(InstType))':
+// CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(InstType))}
+// CHECK:STDOUT:       object_layout:
+// CHECK:STDOUT:         size:            0
+// CHECK:STDOUT:         alignment:       1
 // CHECK:STDOUT:     'type(inst(NamespaceType))':
 // CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(NamespaceType))}
 // CHECK:STDOUT:       object_layout:

+ 65 - 65
toolchain/check/testdata/basics/raw_sem_ir/cpp_interop.carbon

@@ -55,7 +55,7 @@ fn G(x: Cpp.X) {
 // CHECK:STDOUT:   clang_decls:
 // CHECK:STDOUT:     clang_decl_id50000000: {key: "namespace Carbon {\n}", inst_id: instF}
 // CHECK:STDOUT:     clang_decl_id50000001: {key: "<translation unit>", inst_id: inst50000011}
-// CHECK:STDOUT:     clang_decl_id50000002: {key: "struct X {}", inst_id: inst50000014}
+// CHECK:STDOUT:     clang_decl_id50000002: {key: "struct X {}", inst_id: inst50000013}
 // CHECK:STDOUT:     clang_decl_id50000003: {key: "X * _Nonnull p", inst_id: inst50000022}
 // CHECK:STDOUT:     clang_decl_id50000004: {key: {decl: "void f(X x = {})", kind: normal, num_params: 0}, inst_id: inst5000002D}
 // CHECK:STDOUT:     clang_decl_id50000005: {key: {decl: "inline void f__carbon_thunk()", kind: normal, num_params: 0}, inst_id: inst50000030}
@@ -63,9 +63,9 @@ fn G(x: Cpp.X) {
 // CHECK:STDOUT:     clang_decl_id50000007: {key: {decl: "inline void f__carbon_thunk(X * _Nonnull x)", kind: normal, num_params: 1}, inst_id: inst50000043}
 // CHECK:STDOUT:     clang_decl_id50000008: {key: "X * _Nonnull global", inst_id: inst5000004E}
 // CHECK:STDOUT:   name_scopes:
-// CHECK:STDOUT:     name_scope0:     {inst: instF, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name(Cpp): inst50000011, name0: inst5000001D}}
-// CHECK:STDOUT:     name_scope50000001: {inst: inst50000011, parent_scope: name_scope0, has_error: false, extended_scopes: [], names: {name2: inst50000014, name3: inst5000002A, name4: inst5000004E}}
-// CHECK:STDOUT:     name_scope50000002: {inst: inst50000014, parent_scope: name_scope50000001, has_error: false, extended_scopes: [], names: {}}
+// CHECK:STDOUT:     name_scope0:     {inst: instF, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name(Cpp): inst50000011, name0: inst5000001C}}
+// CHECK:STDOUT:     name_scope50000001: {inst: inst50000011, parent_scope: name_scope0, has_error: false, extended_scopes: [], names: {name2: inst50000013, name3: inst5000002A, name4: inst5000004E}}
+// CHECK:STDOUT:     name_scope50000002: {inst: inst50000013, parent_scope: name_scope50000001, has_error: false, extended_scopes: [], names: {}}
 // CHECK:STDOUT:   entity_names:
 // CHECK:STDOUT:     entity_name50000000: {name: name1, parent_scope: name_scope<none>, index: -1, is_template: 0, is_unused: 0, form: inst<none>}
 // CHECK:STDOUT:     entity_name50000001: {name: name1, parent_scope: name_scope<none>, index: -1, is_template: 0, is_unused: 0, form: inst<none>}
@@ -80,7 +80,7 @@ fn G(x: Cpp.X) {
 // CHECK:STDOUT:     function50000003: {name: name3, parent_scope: name_scope50000001, call_param_patterns_id: inst_block5000000F, call_params_id: inst_block50000010}
 // CHECK:STDOUT:     function50000004: {name: name6, parent_scope: name_scope50000001, call_param_patterns_id: inst_block50000015, call_params_id: inst_block50000016}
 // CHECK:STDOUT:   classes:
-// CHECK:STDOUT:     class50000000:   {name: name2, parent_scope: name_scope50000001, self_type_id: type(inst50000015), inheritance_kind: Base, is_dynamic: 0, scope_id: name_scope50000002, body_block_id: inst_block5000000C, adapt_id: inst<none>, base_id: inst<none>, complete_type_witness_id: inst50000025, vtable_decl_id: inst<none>}}
+// CHECK:STDOUT:     class50000000:   {name: name2, parent_scope: name_scope50000001, self_type_id: type(inst50000014), inheritance_kind: Base, is_dynamic: 0, scope_id: name_scope50000002, body_block_id: inst_block5000000C, adapt_id: inst<none>, base_id: inst<none>, complete_type_witness_id: inst50000025, vtable_decl_id: inst<none>}}
 // CHECK:STDOUT:   interfaces:      {}
 // CHECK:STDOUT:   associated_constants: {}
 // CHECK:STDOUT:   impls:           {}
@@ -109,23 +109,23 @@ fn G(x: Cpp.X) {
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
-// CHECK:STDOUT:     'type(inst(NamespaceType))':
-// CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(NamespaceType))}
+// CHECK:STDOUT:     'type(inst(InstType))':
+// CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(InstType))}
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
-// CHECK:STDOUT:     'type(inst(InstType))':
-// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst50000013)}
+// CHECK:STDOUT:     'type(inst(NamespaceType))':
+// CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(NamespaceType))}
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
-// CHECK:STDOUT:     'type(inst50000013)':
-// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst50000013)}
+// CHECK:STDOUT:     'type(inst5000001D)':
+// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst5000001E)}
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
 // CHECK:STDOUT:     'type(inst5000001E)':
-// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst50000013)}
+// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst5000001E)}
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
@@ -149,33 +149,33 @@ fn G(x: Cpp.X) {
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            8
 // CHECK:STDOUT:         alignment:       8
-// CHECK:STDOUT:     'type(inst50000015)':
+// CHECK:STDOUT:     'type(inst50000014)':
 // CHECK:STDOUT:       value_repr:      {kind: pointer, type: type(inst50000027)}
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            8
 // CHECK:STDOUT:         alignment:       8
 // CHECK:STDOUT:     'type(inst50000029)':
-// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst50000013)}
+// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst5000001E)}
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
 // CHECK:STDOUT:     'type(inst5000002E)':
-// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst50000013)}
+// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst5000001E)}
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
 // CHECK:STDOUT:     'type(inst50000031)':
-// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst50000013)}
+// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst5000001E)}
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
 // CHECK:STDOUT:     'type(inst5000003C)':
-// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst50000013)}
+// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst5000001E)}
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
 // CHECK:STDOUT:     'type(inst50000044)':
-// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst50000013)}
+// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst5000001E)}
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
@@ -200,21 +200,21 @@ fn G(x: Cpp.X) {
 // CHECK:STDOUT:     inst50000010:    {kind: ImportCppDecl}
 // CHECK:STDOUT:     inst50000011:    {kind: Namespace, arg0: name_scope50000001, arg1: inst50000010, type: type(inst(NamespaceType))}
 // CHECK:STDOUT:     inst50000012:    {kind: NameRef, arg0: name(Cpp), arg1: inst50000011, type: type(inst(NamespaceType))}
-// CHECK:STDOUT:     inst50000013:    {kind: TupleType, arg0: inst_block_empty, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000014:    {kind: ClassDecl, arg0: class50000000, arg1: inst_block<none>, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000015:    {kind: ClassType, arg0: class50000000, arg1: specific<none>, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000016:    {kind: NameRef, arg0: name2, arg1: inst50000014, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000017:    {kind: PatternType, arg0: inst50000015, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000018:    {kind: ValueParamPattern, arg0: name1, type: type(inst50000017)}
-// CHECK:STDOUT:     inst50000019:    {kind: ValueBinding, arg0: entity_name50000000, arg1: inst5000001B, type: type(inst50000015)}
-// CHECK:STDOUT:     inst5000001A:    {kind: WrapperBindingPattern, arg0: entity_name50000000, arg1: inst50000018, type: type(inst50000017)}
-// CHECK:STDOUT:     inst5000001B:    {kind: ValueParam, arg0: call_param0, arg1: name1, type: type(inst50000015)}
-// CHECK:STDOUT:     inst5000001C:    {kind: SpliceBlock, arg0: inst_block50000005, arg1: inst50000016, type: type(TypeType)}
-// CHECK:STDOUT:     inst5000001D:    {kind: FunctionDecl, arg0: function50000000, arg1: inst_block5000000A, type: type(inst5000001E)}
-// CHECK:STDOUT:     inst5000001E:    {kind: FunctionType, arg0: function50000000, arg1: specific<none>, type: type(TypeType)}
-// CHECK:STDOUT:     inst5000001F:    {kind: StructValue, arg0: inst_block_empty, type: type(inst5000001E)}
-// CHECK:STDOUT:     inst50000020:    {kind: PointerType, arg0: inst50000015, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000021:    {kind: UnboundElementType, arg0: inst50000015, arg1: inst50000020, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000013:    {kind: ClassDecl, arg0: class50000000, arg1: inst_block<none>, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000014:    {kind: ClassType, arg0: class50000000, arg1: specific<none>, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000015:    {kind: NameRef, arg0: name2, arg1: inst50000013, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000016:    {kind: PatternType, arg0: inst50000014, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000017:    {kind: ValueParamPattern, arg0: name1, type: type(inst50000016)}
+// CHECK:STDOUT:     inst50000018:    {kind: ValueBinding, arg0: entity_name50000000, arg1: inst5000001A, type: type(inst50000014)}
+// CHECK:STDOUT:     inst50000019:    {kind: WrapperBindingPattern, arg0: entity_name50000000, arg1: inst50000017, type: type(inst50000016)}
+// CHECK:STDOUT:     inst5000001A:    {kind: ValueParam, arg0: call_param0, arg1: name1, type: type(inst50000014)}
+// CHECK:STDOUT:     inst5000001B:    {kind: SpliceBlock, arg0: inst_block50000005, arg1: inst50000015, type: type(TypeType)}
+// CHECK:STDOUT:     inst5000001C:    {kind: FunctionDecl, arg0: function50000000, arg1: inst_block5000000A, type: type(inst5000001D)}
+// CHECK:STDOUT:     inst5000001D:    {kind: FunctionType, arg0: function50000000, arg1: specific<none>, type: type(TypeType)}
+// CHECK:STDOUT:     inst5000001E:    {kind: TupleType, arg0: inst_block_empty, type: type(TypeType)}
+// CHECK:STDOUT:     inst5000001F:    {kind: StructValue, arg0: inst_block_empty, type: type(inst5000001D)}
+// CHECK:STDOUT:     inst50000020:    {kind: PointerType, arg0: inst50000014, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000021:    {kind: UnboundElementType, arg0: inst50000014, arg1: inst50000020, type: type(TypeType)}
 // CHECK:STDOUT:     inst50000022:    {kind: FieldDecl, arg0: name5, arg1: element0, type: type(inst50000021)}
 // CHECK:STDOUT:     inst50000023:    {kind: CustomLayoutType, arg0: struct_type_fields50000001, arg1: custom_layout50000001, type: type(TypeType)}
 // CHECK:STDOUT:     inst50000024:    {kind: CustomLayoutType, arg0: struct_type_fields50000002, arg1: custom_layout50000001, type: type(TypeType)}
@@ -232,14 +232,14 @@ fn G(x: Cpp.X) {
 // CHECK:STDOUT:     inst50000030:    {kind: FunctionDecl, arg0: function50000002, arg1: inst_block_empty, type: type(inst50000031)}
 // CHECK:STDOUT:     inst50000031:    {kind: FunctionType, arg0: function50000002, arg1: specific<none>, type: type(TypeType)}
 // CHECK:STDOUT:     inst50000032:    {kind: StructValue, arg0: inst_block_empty, type: type(inst50000031)}
-// CHECK:STDOUT:     inst50000033:    {kind: Call, arg0: inst50000030, arg1: inst_block_empty, type: type(inst50000013)}
+// CHECK:STDOUT:     inst50000033:    {kind: Call, arg0: inst50000030, arg1: inst_block_empty, type: type(inst5000001E)}
 // CHECK:STDOUT:     inst50000034:    {kind: NameRef, arg0: name(Cpp), arg1: inst50000011, type: type(inst(NamespaceType))}
 // CHECK:STDOUT:     inst50000035:    {kind: NameRef, arg0: name3, arg1: inst5000002A, type: type(inst50000029)}
-// CHECK:STDOUT:     inst50000036:    {kind: NameRef, arg0: name1, arg1: inst50000019, type: type(inst50000015)}
-// CHECK:STDOUT:     inst50000037:    {kind: ValueParamPattern, arg0: name1, type: type(inst50000017)}
-// CHECK:STDOUT:     inst50000038:    {kind: ValueBinding, arg0: entity_name50000001, arg1: inst5000003A, type: type(inst50000015)}
-// CHECK:STDOUT:     inst50000039:    {kind: WrapperBindingPattern, arg0: entity_name50000001, arg1: inst50000037, type: type(inst50000017)}
-// CHECK:STDOUT:     inst5000003A:    {kind: ValueParam, arg0: call_param0, arg1: name1, type: type(inst50000015)}
+// CHECK:STDOUT:     inst50000036:    {kind: NameRef, arg0: name1, arg1: inst50000018, type: type(inst50000014)}
+// CHECK:STDOUT:     inst50000037:    {kind: ValueParamPattern, arg0: name1, type: type(inst50000016)}
+// CHECK:STDOUT:     inst50000038:    {kind: ValueBinding, arg0: entity_name50000001, arg1: inst5000003A, type: type(inst50000014)}
+// CHECK:STDOUT:     inst50000039:    {kind: WrapperBindingPattern, arg0: entity_name50000001, arg1: inst50000037, type: type(inst50000016)}
+// CHECK:STDOUT:     inst5000003A:    {kind: ValueParam, arg0: call_param0, arg1: name1, type: type(inst50000014)}
 // CHECK:STDOUT:     inst5000003B:    {kind: FunctionDecl, arg0: function50000003, arg1: inst_block50000012, type: type(inst5000003C)}
 // CHECK:STDOUT:     inst5000003C:    {kind: FunctionType, arg0: function50000003, arg1: specific<none>, type: type(TypeType)}
 // CHECK:STDOUT:     inst5000003D:    {kind: StructValue, arg0: inst_block_empty, type: type(inst5000003C)}
@@ -251,9 +251,9 @@ fn G(x: Cpp.X) {
 // CHECK:STDOUT:     inst50000043:    {kind: FunctionDecl, arg0: function50000004, arg1: inst_block50000018, type: type(inst50000044)}
 // CHECK:STDOUT:     inst50000044:    {kind: FunctionType, arg0: function50000004, arg1: specific<none>, type: type(TypeType)}
 // CHECK:STDOUT:     inst50000045:    {kind: StructValue, arg0: inst_block_empty, type: type(inst50000044)}
-// CHECK:STDOUT:     inst50000046:    {kind: ValueAsRef, arg0: inst50000036, type: type(inst50000015)}
+// CHECK:STDOUT:     inst50000046:    {kind: ValueAsRef, arg0: inst50000036, type: type(inst50000014)}
 // CHECK:STDOUT:     inst50000047:    {kind: AddrOf, arg0: inst50000046, type: type(inst50000020)}
-// CHECK:STDOUT:     inst50000048:    {kind: Call, arg0: inst50000043, arg1: inst_block5000001A, type: type(inst50000013)}
+// CHECK:STDOUT:     inst50000048:    {kind: Call, arg0: inst50000043, arg1: inst_block5000001A, type: type(inst5000001E)}
 // CHECK:STDOUT:     inst50000049:    {kind: NameRef, arg0: name(Cpp), arg1: inst50000011, type: type(inst(NamespaceType))}
 // CHECK:STDOUT:     inst5000004A:    {kind: NameRef, arg0: name3, arg1: inst5000002A, type: type(inst50000029)}
 // CHECK:STDOUT:     inst5000004B:    {kind: NameRef, arg0: name(Cpp), arg1: inst50000011, type: type(inst(NamespaceType))}
@@ -262,11 +262,11 @@ fn G(x: Cpp.X) {
 // CHECK:STDOUT:     inst5000004E:    {kind: VarStorage, arg0: inst5000004D, type: type(inst50000020)}
 // CHECK:STDOUT:     inst5000004F:    {kind: NameRef, arg0: name4, arg1: inst5000004E, type: type(inst50000020)}
 // CHECK:STDOUT:     inst50000050:    {kind: AcquireValue, arg0: inst5000004F, type: type(inst50000020)}
-// CHECK:STDOUT:     inst50000051:    {kind: Deref, arg0: inst50000050, type: type(inst50000015)}
-// CHECK:STDOUT:     inst50000052:    {kind: AcquireValue, arg0: inst50000051, type: type(inst50000015)}
-// CHECK:STDOUT:     inst50000053:    {kind: ValueAsRef, arg0: inst50000052, type: type(inst50000015)}
+// CHECK:STDOUT:     inst50000051:    {kind: Deref, arg0: inst50000050, type: type(inst50000014)}
+// CHECK:STDOUT:     inst50000052:    {kind: AcquireValue, arg0: inst50000051, type: type(inst50000014)}
+// CHECK:STDOUT:     inst50000053:    {kind: ValueAsRef, arg0: inst50000052, type: type(inst50000014)}
 // CHECK:STDOUT:     inst50000054:    {kind: AddrOf, arg0: inst50000053, type: type(inst50000020)}
-// CHECK:STDOUT:     inst50000055:    {kind: Call, arg0: inst50000043, arg1: inst_block5000001C, type: type(inst50000013)}
+// CHECK:STDOUT:     inst50000055:    {kind: Call, arg0: inst50000043, arg1: inst_block5000001C, type: type(inst5000001E)}
 // CHECK:STDOUT:     inst50000056:    {kind: Return}
 // CHECK:STDOUT:   constant_values:
 // CHECK:STDOUT:     values:
@@ -288,15 +288,15 @@ fn G(x: Cpp.X) {
 // CHECK:STDOUT:       instF:           concrete_constant(instF)
 // CHECK:STDOUT:       inst50000011:    concrete_constant(inst50000011)
 // CHECK:STDOUT:       inst50000012:    concrete_constant(inst50000011)
-// CHECK:STDOUT:       inst50000013:    concrete_constant(inst50000013)
-// CHECK:STDOUT:       inst50000014:    concrete_constant(inst50000015)
-// CHECK:STDOUT:       inst50000015:    concrete_constant(inst50000015)
-// CHECK:STDOUT:       inst50000016:    concrete_constant(inst50000015)
+// CHECK:STDOUT:       inst50000013:    concrete_constant(inst50000014)
+// CHECK:STDOUT:       inst50000014:    concrete_constant(inst50000014)
+// CHECK:STDOUT:       inst50000015:    concrete_constant(inst50000014)
+// CHECK:STDOUT:       inst50000016:    concrete_constant(inst50000016)
 // CHECK:STDOUT:       inst50000017:    concrete_constant(inst50000017)
-// CHECK:STDOUT:       inst50000018:    concrete_constant(inst50000018)
-// CHECK:STDOUT:       inst5000001A:    concrete_constant(inst5000001A)
-// CHECK:STDOUT:       inst5000001C:    concrete_constant(inst50000015)
-// CHECK:STDOUT:       inst5000001D:    concrete_constant(inst5000001F)
+// CHECK:STDOUT:       inst50000019:    concrete_constant(inst50000019)
+// CHECK:STDOUT:       inst5000001B:    concrete_constant(inst50000014)
+// CHECK:STDOUT:       inst5000001C:    concrete_constant(inst5000001F)
+// CHECK:STDOUT:       inst5000001D:    concrete_constant(inst5000001D)
 // CHECK:STDOUT:       inst5000001E:    concrete_constant(inst5000001E)
 // CHECK:STDOUT:       inst5000001F:    concrete_constant(inst5000001F)
 // CHECK:STDOUT:       inst50000020:    concrete_constant(inst50000020)
@@ -342,11 +342,11 @@ fn G(x: Cpp.X) {
 // CHECK:STDOUT:   inst_blocks:
 // CHECK:STDOUT:     inst_block_empty: {}
 // CHECK:STDOUT:     exports:
-// CHECK:STDOUT:       0:               inst5000001D
+// CHECK:STDOUT:       0:               inst5000001C
 // CHECK:STDOUT:     generated:       {}
 // CHECK:STDOUT:     imports:
 // CHECK:STDOUT:       0:               inst50000011
-// CHECK:STDOUT:       1:               inst50000014
+// CHECK:STDOUT:       1:               inst50000013
 // CHECK:STDOUT:       2:               inst5000002A
 // CHECK:STDOUT:       3:               inst5000002D
 // CHECK:STDOUT:       4:               inst50000030
@@ -358,20 +358,20 @@ fn G(x: Cpp.X) {
 // CHECK:STDOUT:     global_init:     {}
 // CHECK:STDOUT:     inst_block50000005:
 // CHECK:STDOUT:       0:               inst50000012
-// CHECK:STDOUT:       1:               inst50000016
+// CHECK:STDOUT:       1:               inst50000015
 // CHECK:STDOUT:     inst_block50000006:
-// CHECK:STDOUT:       0:               inst5000001A
+// CHECK:STDOUT:       0:               inst50000019
 // CHECK:STDOUT:     inst_block50000007:
-// CHECK:STDOUT:       0:               inst50000018
+// CHECK:STDOUT:       0:               inst50000017
 // CHECK:STDOUT:     inst_block50000008:
-// CHECK:STDOUT:       0:               inst5000001B
+// CHECK:STDOUT:       0:               inst5000001A
 // CHECK:STDOUT:     inst_block50000009:
-// CHECK:STDOUT:       0:               inst50000018
-// CHECK:STDOUT:       1:               inst5000001A
+// CHECK:STDOUT:       0:               inst50000017
+// CHECK:STDOUT:       1:               inst50000019
 // CHECK:STDOUT:     inst_block5000000A:
-// CHECK:STDOUT:       0:               inst5000001B
-// CHECK:STDOUT:       1:               inst5000001C
-// CHECK:STDOUT:       2:               inst50000019
+// CHECK:STDOUT:       0:               inst5000001A
+// CHECK:STDOUT:       1:               inst5000001B
+// CHECK:STDOUT:       2:               inst50000018
 // CHECK:STDOUT:     inst_block5000000B:
 // CHECK:STDOUT:       0:               inst50000028
 // CHECK:STDOUT:       1:               inst5000002C
@@ -434,7 +434,7 @@ fn G(x: Cpp.X) {
 // CHECK:STDOUT:     inst_block5000001D:
 // CHECK:STDOUT:       0:               instF
 // CHECK:STDOUT:       1:               inst50000010
-// CHECK:STDOUT:       2:               inst5000001D
+// CHECK:STDOUT:       2:               inst5000001C
 // CHECK:STDOUT:   value_stores:
 // CHECK:STDOUT:     shared_values:
 // CHECK:STDOUT:       ints:            {}

+ 10 - 5
toolchain/check/testdata/basics/raw_sem_ir/multifile.carbon

@@ -68,6 +68,11 @@ fn B() {
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
+// CHECK:STDOUT:     'type(inst(InstType))':
+// CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(InstType))}
+// CHECK:STDOUT:       object_layout:
+// CHECK:STDOUT:         size:            0
+// CHECK:STDOUT:         alignment:       1
 // CHECK:STDOUT:     'type(inst(NamespaceType))':
 // CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(NamespaceType))}
 // CHECK:STDOUT:       object_layout:
@@ -169,6 +174,11 @@ fn B() {
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
+// CHECK:STDOUT:     'type(inst(InstType))':
+// CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(InstType))}
+// CHECK:STDOUT:       object_layout:
+// CHECK:STDOUT:         size:            0
+// CHECK:STDOUT:         alignment:       1
 // CHECK:STDOUT:     'type(inst(NamespaceType))':
 // CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(NamespaceType))}
 // CHECK:STDOUT:       object_layout:
@@ -184,11 +194,6 @@ fn B() {
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
-// CHECK:STDOUT:     'type(inst(InstType))':
-// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst70000014)}
-// CHECK:STDOUT:       object_layout:
-// CHECK:STDOUT:         size:            0
-// CHECK:STDOUT:         alignment:       1
 // CHECK:STDOUT:   facet_types:     {}
 // CHECK:STDOUT:   insts:
 // CHECK:STDOUT:     instF:           {kind: Namespace, arg0: name_scope0, arg1: inst<none>, type: type(inst(NamespaceType))}

+ 10 - 5
toolchain/check/testdata/basics/raw_sem_ir/multifile_with_textual_ir.carbon

@@ -68,6 +68,11 @@ fn B() {
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
+// CHECK:STDOUT:     'type(inst(InstType))':
+// CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(InstType))}
+// CHECK:STDOUT:       object_layout:
+// CHECK:STDOUT:         size:            0
+// CHECK:STDOUT:         alignment:       1
 // CHECK:STDOUT:     'type(inst(NamespaceType))':
 // CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(NamespaceType))}
 // CHECK:STDOUT:       object_layout:
@@ -188,6 +193,11 @@ fn B() {
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
+// CHECK:STDOUT:     'type(inst(InstType))':
+// CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(InstType))}
+// CHECK:STDOUT:       object_layout:
+// CHECK:STDOUT:         size:            0
+// CHECK:STDOUT:         alignment:       1
 // CHECK:STDOUT:     'type(inst(NamespaceType))':
 // CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(NamespaceType))}
 // CHECK:STDOUT:       object_layout:
@@ -203,11 +213,6 @@ fn B() {
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
-// CHECK:STDOUT:     'type(inst(InstType))':
-// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst70000014)}
-// CHECK:STDOUT:       object_layout:
-// CHECK:STDOUT:         size:            0
-// CHECK:STDOUT:         alignment:       1
 // CHECK:STDOUT:   facet_types:     {}
 // CHECK:STDOUT:   insts:
 // CHECK:STDOUT:     instF:           {kind: Namespace, arg0: name_scope0, arg1: inst<none>, type: type(inst(NamespaceType))}

+ 224 - 219
toolchain/check/testdata/basics/raw_sem_ir/non_core_interfaces.carbon

@@ -85,6 +85,11 @@ fn UseLocalCopy[T:! Copy](_: T.T1, _: T.T2) {}
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
+// CHECK:STDOUT:     'type(inst(InstType))':
+// CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(InstType))}
+// CHECK:STDOUT:       object_layout:
+// CHECK:STDOUT:         size:            0
+// CHECK:STDOUT:         alignment:       1
 // CHECK:STDOUT:     'type(inst(NamespaceType))':
 // CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(NamespaceType))}
 // CHECK:STDOUT:       object_layout:
@@ -205,12 +210,12 @@ fn UseLocalCopy[T:! Copy](_: T.T1, _: T.T2) {}
 // CHECK:STDOUT:     import_ir_instC: {ir_id: import_ir50000002, inst_id: inst6000001C}
 // CHECK:STDOUT:   clang_decls:     {}
 // CHECK:STDOUT:   name_scopes:
-// CHECK:STDOUT:     name_scope0:     {inst: instF, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name0: inst50000011, name1: inst50000012, name4: inst50000061, name7: inst50000095}}
-// CHECK:STDOUT:     name_scope50000001: {inst: inst50000011, parent_scope: name_scope0, has_error: false, extended_scopes: [], names: {name6: inst50000026}}
+// CHECK:STDOUT:     name_scope0:     {inst: instF, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name0: inst50000011, name1: inst50000012, name4: inst50000060, name7: inst50000095}}
+// CHECK:STDOUT:     name_scope50000001: {inst: inst50000011, parent_scope: name_scope0, has_error: false, extended_scopes: [], names: {name6: inst50000025}}
 // CHECK:STDOUT:     name_scope50000002: {inst: inst50000012, parent_scope: name_scope0, has_error: false, extended_scopes: [], names: {name(SelfType): inst50000014}}
 // CHECK:STDOUT:     name_scope50000003: {inst: inst50000017, parent_scope: name_scope50000002, has_error: false, extended_scopes: [], names: {name2: inst5000001B, name3: inst5000001F}}
-// CHECK:STDOUT:     name_scope50000004: {inst: inst50000027, parent_scope: name_scope50000001, has_error: false, extended_scopes: [], names: {name(SelfType): inst50000030}}
-// CHECK:STDOUT:     name_scope50000005: {inst: inst50000029, parent_scope: name_scope50000004, has_error: false, extended_scopes: [], names: {name2: inst5000002B, name3: inst5000002C}}
+// CHECK:STDOUT:     name_scope50000004: {inst: inst50000026, parent_scope: name_scope50000001, has_error: false, extended_scopes: [], names: {name(SelfType): inst5000002F}}
+// CHECK:STDOUT:     name_scope50000005: {inst: inst50000028, parent_scope: name_scope50000004, has_error: false, extended_scopes: [], names: {name2: inst5000002A, name3: inst5000002B}}
 // CHECK:STDOUT:   entity_names:
 // CHECK:STDOUT:     entity_name50000000: {name: name(SelfType), parent_scope: name_scope50000002, index: 0, is_template: 0, is_unused: 0, form: inst<none>}
 // CHECK:STDOUT:     entity_name50000001: {name: name(PeriodSelf), parent_scope: name_scope<none>, index: -1, is_template: 0, is_unused: 0, form: inst<none>}
@@ -236,14 +241,14 @@ fn UseLocalCopy[T:! Copy](_: T.T1, _: T.T2) {}
 // CHECK:STDOUT:   associated_constants:
 // CHECK:STDOUT:     assoc_const50000000: {name: name2, parent_scope: name_scope50000003, decl_id: inst50000019, default_value_id: inst<none>}
 // CHECK:STDOUT:     assoc_const50000001: {name: name3, parent_scope: name_scope50000003, decl_id: inst5000001E, default_value_id: inst<none>}
-// CHECK:STDOUT:     assoc_const50000002: {name: name2, parent_scope: name_scope50000005, decl_id: inst50000042, default_value_id: inst<none>}
-// CHECK:STDOUT:     assoc_const50000003: {name: name3, parent_scope: name_scope50000005, decl_id: inst50000053, default_value_id: inst<none>}
+// CHECK:STDOUT:     assoc_const50000002: {name: name2, parent_scope: name_scope50000005, decl_id: inst50000041, default_value_id: inst<none>}
+// CHECK:STDOUT:     assoc_const50000003: {name: name3, parent_scope: name_scope50000005, decl_id: inst50000052, default_value_id: inst<none>}
 // CHECK:STDOUT:   impls:           {}
 // CHECK:STDOUT:   generics:
 // CHECK:STDOUT:     generic50000000: {decl: inst<none>, bindings: inst_block<none>, self_specific_id: specific<none>, decl_block_id: inst_block<none>, definition_block_id: inst_block<none>}
 // CHECK:STDOUT:     generic50000001: {decl: inst50000017, bindings: inst_block50000005, self_specific_id: specific50000000, decl_block_id: inst_block_empty, definition_block_id: inst_block_empty}
-// CHECK:STDOUT:     generic50000002: {decl: inst50000029, bindings: inst_block50000010, self_specific_id: specific50000001, decl_block_id: inst_block_empty, definition_block_id: inst_block_empty}
-// CHECK:STDOUT:     generic50000003: {decl: inst50000061, bindings: inst_block5000001C, self_specific_id: specific50000003, decl_block_id: inst_block5000001D, definition_block_id: inst_block50000020}
+// CHECK:STDOUT:     generic50000002: {decl: inst50000028, bindings: inst_block50000010, self_specific_id: specific50000001, decl_block_id: inst_block_empty, definition_block_id: inst_block_empty}
+// CHECK:STDOUT:     generic50000003: {decl: inst50000060, bindings: inst_block5000001C, self_specific_id: specific50000003, decl_block_id: inst_block5000001D, definition_block_id: inst_block50000020}
 // CHECK:STDOUT:     generic50000004: {decl: inst50000095, bindings: inst_block5000002C, self_specific_id: specific50000005, decl_block_id: inst_block5000002D, definition_block_id: inst_block50000030}
 // CHECK:STDOUT:   specifics:
 // CHECK:STDOUT:     specific50000000: {generic: generic50000001, args: inst_block50000006, decl_block_id: inst_block_empty, decl_has_error: 0, definition_block_id: inst_block_empty, definition_has_error: 0}
@@ -273,23 +278,18 @@ fn UseLocalCopy[T:! Copy](_: T.T1, _: T.T2) {}
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
-// CHECK:STDOUT:     'type(inst(NamespaceType))':
-// CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(NamespaceType))}
-// CHECK:STDOUT:       object_layout:
-// CHECK:STDOUT:         size:            0
-// CHECK:STDOUT:         alignment:       1
 // CHECK:STDOUT:     'type(inst(InstType))':
-// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst50000025)}
+// CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(InstType))}
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
-// CHECK:STDOUT:     'type(inst50000025)':
-// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst50000025)}
+// CHECK:STDOUT:     'type(inst(NamespaceType))':
+// CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(NamespaceType))}
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
-// CHECK:STDOUT:     'type(inst50000028)':
-// CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst50000028)}
+// CHECK:STDOUT:     'type(inst50000027)':
+// CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst50000027)}
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
@@ -298,8 +298,13 @@ fn UseLocalCopy[T:! Copy](_: T.T1, _: T.T2) {}
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
+// CHECK:STDOUT:     'type(inst50000061)':
+// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst50000062)}
+// CHECK:STDOUT:       object_layout:
+// CHECK:STDOUT:         size:            0
+// CHECK:STDOUT:         alignment:       1
 // CHECK:STDOUT:     'type(inst50000062)':
-// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst50000025)}
+// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst50000062)}
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
@@ -319,7 +324,7 @@ fn UseLocalCopy[T:! Copy](_: T.T1, _: T.T2) {}
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
 // CHECK:STDOUT:     'type(inst50000096)':
-// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst50000025)}
+// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst50000062)}
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
@@ -360,75 +365,75 @@ fn UseLocalCopy[T:! Copy](_: T.T1, _: T.T2) {}
 // CHECK:STDOUT:     inst50000022:    {kind: SymbolicBinding, arg0: entity_name50000001, arg1: inst<none>, type: type(inst50000021)}
 // CHECK:STDOUT:     inst50000023:    {kind: SymbolicBinding, arg0: entity_name50000001, arg1: inst<none>, type: type(inst50000021)}
 // CHECK:STDOUT:     inst50000024:    {kind: NameRef, arg0: name0, arg1: inst50000011, type: type(inst(NamespaceType))}
-// CHECK:STDOUT:     inst50000025:    {kind: TupleType, arg0: inst_block_empty, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000026:    {kind: ImportRefLoaded, arg0: import_ir_inst0, arg1: entity_name50000002, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000027:    {kind: InterfaceDecl, arg0: interface50000001, arg1: inst_block_empty, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000028:    {kind: FacetType, arg0: facet_type50000002, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000029:    {kind: InterfaceWithSelfDecl, arg0: interface50000001}
-// CHECK:STDOUT:     inst5000002A:    {kind: SymbolicBinding, arg0: entity_name50000003, arg1: inst<none>, type: type(inst50000028)}
-// CHECK:STDOUT:     inst5000002B:    {kind: ImportRefLoaded, arg0: import_ir_inst3, arg1: entity_name<none>, type: type(inst5000003C)}
-// CHECK:STDOUT:     inst5000002C:    {kind: ImportRefLoaded, arg0: import_ir_inst4, arg1: entity_name<none>, type: type(inst5000003C)}
-// CHECK:STDOUT:     inst5000002D:    {kind: ImportRefUnloaded, arg0: import_ir_inst5, arg1: entity_name50000004}
-// CHECK:STDOUT:     inst5000002E:    {kind: ImportRefUnloaded, arg0: import_ir_inst6, arg1: entity_name50000005}
-// CHECK:STDOUT:     inst5000002F:    {kind: ImportRefLoaded, arg0: import_ir_inst7, arg1: entity_name<none>, type: type(inst50000028)}
-// CHECK:STDOUT:     inst50000030:    {kind: ImportRefUnloaded, arg0: import_ir_inst8, arg1: entity_name<none>}
-// CHECK:STDOUT:     inst50000031:    {kind: NameRef, arg0: name6, arg1: inst50000026, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000032:    {kind: PatternType, arg0: inst50000028, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000033:    {kind: SymbolicBinding, arg0: entity_name50000007, arg1: inst<none>, type: type(inst50000028)}
-// CHECK:STDOUT:     inst50000034:    {kind: SymbolicBinding, arg0: entity_name50000007, arg1: inst<none>, type: type(inst50000028)}
-// CHECK:STDOUT:     inst50000035:    {kind: SymbolicBinding, arg0: entity_name50000007, arg1: inst<none>, type: type(inst50000028)}
-// CHECK:STDOUT:     inst50000036:    {kind: SymbolicBindingPattern, arg0: entity_name50000007, type: type(inst50000032)}
-// CHECK:STDOUT:     inst50000037:    {kind: NameRef, arg0: name5, arg1: inst50000033, type: type(inst50000028)}
-// CHECK:STDOUT:     inst50000038:    {kind: FacetAccessType, arg0: inst50000037, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000025:    {kind: ImportRefLoaded, arg0: import_ir_inst0, arg1: entity_name50000002, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000026:    {kind: InterfaceDecl, arg0: interface50000001, arg1: inst_block_empty, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000027:    {kind: FacetType, arg0: facet_type50000002, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000028:    {kind: InterfaceWithSelfDecl, arg0: interface50000001}
+// CHECK:STDOUT:     inst50000029:    {kind: SymbolicBinding, arg0: entity_name50000003, arg1: inst<none>, type: type(inst50000027)}
+// CHECK:STDOUT:     inst5000002A:    {kind: ImportRefLoaded, arg0: import_ir_inst3, arg1: entity_name<none>, type: type(inst5000003B)}
+// CHECK:STDOUT:     inst5000002B:    {kind: ImportRefLoaded, arg0: import_ir_inst4, arg1: entity_name<none>, type: type(inst5000003B)}
+// CHECK:STDOUT:     inst5000002C:    {kind: ImportRefUnloaded, arg0: import_ir_inst5, arg1: entity_name50000004}
+// CHECK:STDOUT:     inst5000002D:    {kind: ImportRefUnloaded, arg0: import_ir_inst6, arg1: entity_name50000005}
+// CHECK:STDOUT:     inst5000002E:    {kind: ImportRefLoaded, arg0: import_ir_inst7, arg1: entity_name<none>, type: type(inst50000027)}
+// CHECK:STDOUT:     inst5000002F:    {kind: ImportRefUnloaded, arg0: import_ir_inst8, arg1: entity_name<none>}
+// CHECK:STDOUT:     inst50000030:    {kind: NameRef, arg0: name6, arg1: inst50000025, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000031:    {kind: PatternType, arg0: inst50000027, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000032:    {kind: SymbolicBinding, arg0: entity_name50000007, arg1: inst<none>, type: type(inst50000027)}
+// CHECK:STDOUT:     inst50000033:    {kind: SymbolicBinding, arg0: entity_name50000007, arg1: inst<none>, type: type(inst50000027)}
+// CHECK:STDOUT:     inst50000034:    {kind: SymbolicBinding, arg0: entity_name50000007, arg1: inst<none>, type: type(inst50000027)}
+// CHECK:STDOUT:     inst50000035:    {kind: SymbolicBindingPattern, arg0: entity_name50000007, type: type(inst50000031)}
+// CHECK:STDOUT:     inst50000036:    {kind: NameRef, arg0: name5, arg1: inst50000032, type: type(inst50000027)}
+// CHECK:STDOUT:     inst50000037:    {kind: FacetAccessType, arg0: inst50000036, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000038:    {kind: FacetAccessType, arg0: inst50000033, type: type(TypeType)}
 // CHECK:STDOUT:     inst50000039:    {kind: FacetAccessType, arg0: inst50000034, type: type(TypeType)}
-// CHECK:STDOUT:     inst5000003A:    {kind: FacetAccessType, arg0: inst50000035, type: type(TypeType)}
-// CHECK:STDOUT:     inst5000003B:    {kind: Converted, arg0: inst50000037, arg1: inst50000038, type: type(TypeType)}
-// CHECK:STDOUT:     inst5000003C:    {kind: AssociatedEntityType, arg0: interface50000001, arg1: specific<none>, type: type(TypeType)}
-// CHECK:STDOUT:     inst5000003D:    {kind: ImportRefLoaded, arg0: import_ir_inst9, arg1: entity_name<none>, type: type(TypeType)}
-// CHECK:STDOUT:     inst5000003E:    {kind: AssociatedEntity, arg0: element0, arg1: inst5000003D, type: type(inst5000003C)}
-// CHECK:STDOUT:     inst5000003F:    {kind: NameRef, arg0: name2, arg1: inst5000002B, type: type(inst5000003C)}
-// CHECK:STDOUT:     inst50000040:    {kind: LookupImplWitness, arg0: inst50000034, arg1: specific_interface50000000, type: type(inst(WitnessType))}
-// CHECK:STDOUT:     inst50000041:    {kind: LookupImplWitness, arg0: inst50000034, arg1: specific_interface50000000, type: type(inst(WitnessType))}
-// CHECK:STDOUT:     inst50000042:    {kind: AssociatedConstantDecl, arg0: assoc_const50000002, arg1: inst_block_empty, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000043:    {kind: ImplWitnessAccess, arg0: inst50000041, arg1: element0, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000044:    {kind: ImplWitnessAccess, arg0: inst50000041, arg1: element0, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000045:    {kind: LookupImplWitness, arg0: inst50000035, arg1: specific_interface50000000, type: type(inst(WitnessType))}
-// CHECK:STDOUT:     inst50000046:    {kind: ImplWitnessAccess, arg0: inst50000045, arg1: element0, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000047:    {kind: PatternType, arg0: inst50000044, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000048:    {kind: ValueParamPattern, arg0: name(Underscore), type: type(symbolic_constant5000000D)}
-// CHECK:STDOUT:     inst50000049:    {kind: PatternType, arg0: inst50000046, type: type(TypeType)}
-// CHECK:STDOUT:     inst5000004A:    {kind: ValueBinding, arg0: entity_name50000008, arg1: inst5000005D, type: type(symbolic_constant5000000B)}
-// CHECK:STDOUT:     inst5000004B:    {kind: WrapperBindingPattern, arg0: entity_name50000008, arg1: inst50000048, type: type(symbolic_constant5000000D)}
-// CHECK:STDOUT:     inst5000004C:    {kind: NameRef, arg0: name5, arg1: inst50000033, type: type(inst50000028)}
-// CHECK:STDOUT:     inst5000004D:    {kind: FacetAccessType, arg0: inst5000004C, type: type(TypeType)}
-// CHECK:STDOUT:     inst5000004E:    {kind: Converted, arg0: inst5000004C, arg1: inst5000004D, type: type(TypeType)}
-// CHECK:STDOUT:     inst5000004F:    {kind: ImportRefLoaded, arg0: import_ir_instB, arg1: entity_name<none>, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000050:    {kind: AssociatedEntity, arg0: element1, arg1: inst5000004F, type: type(inst5000003C)}
-// CHECK:STDOUT:     inst50000051:    {kind: NameRef, arg0: name3, arg1: inst5000002C, type: type(inst5000003C)}
-// CHECK:STDOUT:     inst50000052:    {kind: LookupImplWitness, arg0: inst50000034, arg1: specific_interface50000000, type: type(inst(WitnessType))}
-// CHECK:STDOUT:     inst50000053:    {kind: AssociatedConstantDecl, arg0: assoc_const50000003, arg1: inst_block_empty, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000054:    {kind: ImplWitnessAccess, arg0: inst50000041, arg1: element1, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000055:    {kind: ImplWitnessAccess, arg0: inst50000041, arg1: element1, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000056:    {kind: ImplWitnessAccess, arg0: inst50000045, arg1: element1, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000057:    {kind: PatternType, arg0: inst50000055, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000058:    {kind: ValueParamPattern, arg0: name(Underscore), type: type(symbolic_constant50000011)}
-// CHECK:STDOUT:     inst50000059:    {kind: PatternType, arg0: inst50000056, type: type(TypeType)}
-// CHECK:STDOUT:     inst5000005A:    {kind: ValueBinding, arg0: entity_name50000009, arg1: inst5000005F, type: type(symbolic_constant5000000F)}
-// CHECK:STDOUT:     inst5000005B:    {kind: WrapperBindingPattern, arg0: entity_name50000009, arg1: inst50000058, type: type(symbolic_constant50000011)}
-// CHECK:STDOUT:     inst5000005C:    {kind: SpliceBlock, arg0: inst_block5000000E, arg1: inst50000031, type: type(TypeType)}
-// CHECK:STDOUT:     inst5000005D:    {kind: ValueParam, arg0: call_param0, arg1: name(Underscore), type: type(symbolic_constant5000000B)}
-// CHECK:STDOUT:     inst5000005E:    {kind: SpliceBlock, arg0: inst_block50000013, arg1: inst50000043, type: type(TypeType)}
-// CHECK:STDOUT:     inst5000005F:    {kind: ValueParam, arg0: call_param1, arg1: name(Underscore), type: type(symbolic_constant5000000F)}
-// CHECK:STDOUT:     inst50000060:    {kind: SpliceBlock, arg0: inst_block50000016, arg1: inst50000054, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000061:    {kind: FunctionDecl, arg0: function50000000, arg1: inst_block5000001B, type: type(inst50000062)}
-// CHECK:STDOUT:     inst50000062:    {kind: FunctionType, arg0: function50000000, arg1: specific<none>, type: type(TypeType)}
-// CHECK:STDOUT:     inst50000063:    {kind: StructValue, arg0: inst_block_empty, type: type(inst50000062)}
-// CHECK:STDOUT:     inst50000064:    {kind: RequireCompleteType, arg0: inst50000044, type: type(inst(WitnessType))}
-// CHECK:STDOUT:     inst50000065:    {kind: RequireCompleteType, arg0: inst50000044, type: type(inst(WitnessType))}
-// CHECK:STDOUT:     inst50000066:    {kind: RequireCompleteType, arg0: inst50000046, type: type(inst(WitnessType))}
-// CHECK:STDOUT:     inst50000067:    {kind: RequireCompleteType, arg0: inst50000055, type: type(inst(WitnessType))}
-// CHECK:STDOUT:     inst50000068:    {kind: RequireCompleteType, arg0: inst50000055, type: type(inst(WitnessType))}
-// CHECK:STDOUT:     inst50000069:    {kind: RequireCompleteType, arg0: inst50000056, type: type(inst(WitnessType))}
+// CHECK:STDOUT:     inst5000003A:    {kind: Converted, arg0: inst50000036, arg1: inst50000037, type: type(TypeType)}
+// CHECK:STDOUT:     inst5000003B:    {kind: AssociatedEntityType, arg0: interface50000001, arg1: specific<none>, type: type(TypeType)}
+// CHECK:STDOUT:     inst5000003C:    {kind: ImportRefLoaded, arg0: import_ir_inst9, arg1: entity_name<none>, type: type(TypeType)}
+// CHECK:STDOUT:     inst5000003D:    {kind: AssociatedEntity, arg0: element0, arg1: inst5000003C, type: type(inst5000003B)}
+// CHECK:STDOUT:     inst5000003E:    {kind: NameRef, arg0: name2, arg1: inst5000002A, type: type(inst5000003B)}
+// CHECK:STDOUT:     inst5000003F:    {kind: LookupImplWitness, arg0: inst50000033, arg1: specific_interface50000000, type: type(inst(WitnessType))}
+// CHECK:STDOUT:     inst50000040:    {kind: LookupImplWitness, arg0: inst50000033, arg1: specific_interface50000000, type: type(inst(WitnessType))}
+// CHECK:STDOUT:     inst50000041:    {kind: AssociatedConstantDecl, arg0: assoc_const50000002, arg1: inst_block_empty, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000042:    {kind: ImplWitnessAccess, arg0: inst50000040, arg1: element0, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000043:    {kind: ImplWitnessAccess, arg0: inst50000040, arg1: element0, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000044:    {kind: LookupImplWitness, arg0: inst50000034, arg1: specific_interface50000000, type: type(inst(WitnessType))}
+// CHECK:STDOUT:     inst50000045:    {kind: ImplWitnessAccess, arg0: inst50000044, arg1: element0, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000046:    {kind: PatternType, arg0: inst50000043, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000047:    {kind: ValueParamPattern, arg0: name(Underscore), type: type(symbolic_constant5000000D)}
+// CHECK:STDOUT:     inst50000048:    {kind: PatternType, arg0: inst50000045, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000049:    {kind: ValueBinding, arg0: entity_name50000008, arg1: inst5000005C, type: type(symbolic_constant5000000B)}
+// CHECK:STDOUT:     inst5000004A:    {kind: WrapperBindingPattern, arg0: entity_name50000008, arg1: inst50000047, type: type(symbolic_constant5000000D)}
+// CHECK:STDOUT:     inst5000004B:    {kind: NameRef, arg0: name5, arg1: inst50000032, type: type(inst50000027)}
+// CHECK:STDOUT:     inst5000004C:    {kind: FacetAccessType, arg0: inst5000004B, type: type(TypeType)}
+// CHECK:STDOUT:     inst5000004D:    {kind: Converted, arg0: inst5000004B, arg1: inst5000004C, type: type(TypeType)}
+// CHECK:STDOUT:     inst5000004E:    {kind: ImportRefLoaded, arg0: import_ir_instB, arg1: entity_name<none>, type: type(TypeType)}
+// CHECK:STDOUT:     inst5000004F:    {kind: AssociatedEntity, arg0: element1, arg1: inst5000004E, type: type(inst5000003B)}
+// CHECK:STDOUT:     inst50000050:    {kind: NameRef, arg0: name3, arg1: inst5000002B, type: type(inst5000003B)}
+// CHECK:STDOUT:     inst50000051:    {kind: LookupImplWitness, arg0: inst50000033, arg1: specific_interface50000000, type: type(inst(WitnessType))}
+// CHECK:STDOUT:     inst50000052:    {kind: AssociatedConstantDecl, arg0: assoc_const50000003, arg1: inst_block_empty, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000053:    {kind: ImplWitnessAccess, arg0: inst50000040, arg1: element1, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000054:    {kind: ImplWitnessAccess, arg0: inst50000040, arg1: element1, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000055:    {kind: ImplWitnessAccess, arg0: inst50000044, arg1: element1, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000056:    {kind: PatternType, arg0: inst50000054, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000057:    {kind: ValueParamPattern, arg0: name(Underscore), type: type(symbolic_constant50000011)}
+// CHECK:STDOUT:     inst50000058:    {kind: PatternType, arg0: inst50000055, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000059:    {kind: ValueBinding, arg0: entity_name50000009, arg1: inst5000005E, type: type(symbolic_constant5000000F)}
+// CHECK:STDOUT:     inst5000005A:    {kind: WrapperBindingPattern, arg0: entity_name50000009, arg1: inst50000057, type: type(symbolic_constant50000011)}
+// CHECK:STDOUT:     inst5000005B:    {kind: SpliceBlock, arg0: inst_block5000000E, arg1: inst50000030, type: type(TypeType)}
+// CHECK:STDOUT:     inst5000005C:    {kind: ValueParam, arg0: call_param0, arg1: name(Underscore), type: type(symbolic_constant5000000B)}
+// CHECK:STDOUT:     inst5000005D:    {kind: SpliceBlock, arg0: inst_block50000013, arg1: inst50000042, type: type(TypeType)}
+// CHECK:STDOUT:     inst5000005E:    {kind: ValueParam, arg0: call_param1, arg1: name(Underscore), type: type(symbolic_constant5000000F)}
+// CHECK:STDOUT:     inst5000005F:    {kind: SpliceBlock, arg0: inst_block50000016, arg1: inst50000053, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000060:    {kind: FunctionDecl, arg0: function50000000, arg1: inst_block5000001B, type: type(inst50000061)}
+// CHECK:STDOUT:     inst50000061:    {kind: FunctionType, arg0: function50000000, arg1: specific<none>, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000062:    {kind: TupleType, arg0: inst_block_empty, type: type(TypeType)}
+// CHECK:STDOUT:     inst50000063:    {kind: StructValue, arg0: inst_block_empty, type: type(inst50000061)}
+// CHECK:STDOUT:     inst50000064:    {kind: RequireCompleteType, arg0: inst50000043, type: type(inst(WitnessType))}
+// CHECK:STDOUT:     inst50000065:    {kind: RequireCompleteType, arg0: inst50000043, type: type(inst(WitnessType))}
+// CHECK:STDOUT:     inst50000066:    {kind: RequireCompleteType, arg0: inst50000045, type: type(inst(WitnessType))}
+// CHECK:STDOUT:     inst50000067:    {kind: RequireCompleteType, arg0: inst50000054, type: type(inst(WitnessType))}
+// CHECK:STDOUT:     inst50000068:    {kind: RequireCompleteType, arg0: inst50000054, type: type(inst(WitnessType))}
+// CHECK:STDOUT:     inst50000069:    {kind: RequireCompleteType, arg0: inst50000055, type: type(inst(WitnessType))}
 // CHECK:STDOUT:     inst5000006A:    {kind: Return}
 // CHECK:STDOUT:     inst5000006B:    {kind: SymbolicBinding, arg0: entity_name50000001, arg1: inst<none>, type: type(inst50000021)}
 // CHECK:STDOUT:     inst5000006C:    {kind: NameRef, arg0: name1, arg1: inst50000012, type: type(TypeType)}
@@ -505,61 +510,61 @@ fn UseLocalCopy[T:! Copy](_: T.T1, _: T.T2) {}
 // CHECK:STDOUT:       inst50000022:    symbolic_constant50000002
 // CHECK:STDOUT:       inst50000023:    symbolic_constant50000002
 // CHECK:STDOUT:       inst50000024:    concrete_constant(inst50000011)
-// CHECK:STDOUT:       inst50000025:    concrete_constant(inst50000025)
-// CHECK:STDOUT:       inst50000026:    concrete_constant(inst50000028)
-// CHECK:STDOUT:       inst50000027:    concrete_constant(inst50000028)
+// CHECK:STDOUT:       inst50000025:    concrete_constant(inst50000027)
+// CHECK:STDOUT:       inst50000026:    concrete_constant(inst50000027)
+// CHECK:STDOUT:       inst50000027:    concrete_constant(inst50000027)
 // CHECK:STDOUT:       inst50000028:    concrete_constant(inst50000028)
-// CHECK:STDOUT:       inst50000029:    concrete_constant(inst50000029)
-// CHECK:STDOUT:       inst5000002A:    symbolic_constant50000003
-// CHECK:STDOUT:       inst5000002B:    concrete_constant(inst5000003E)
-// CHECK:STDOUT:       inst5000002C:    concrete_constant(inst50000050)
+// CHECK:STDOUT:       inst50000029:    symbolic_constant50000003
+// CHECK:STDOUT:       inst5000002A:    concrete_constant(inst5000003D)
+// CHECK:STDOUT:       inst5000002B:    concrete_constant(inst5000004F)
+// CHECK:STDOUT:       inst5000002C:    constant<none>
 // CHECK:STDOUT:       inst5000002D:    constant<none>
-// CHECK:STDOUT:       inst5000002E:    constant<none>
-// CHECK:STDOUT:       inst5000002F:    symbolic_constant50000003
-// CHECK:STDOUT:       inst50000030:    constant<none>
-// CHECK:STDOUT:       inst50000031:    concrete_constant(inst50000028)
-// CHECK:STDOUT:       inst50000032:    concrete_constant(inst50000032)
-// CHECK:STDOUT:       inst50000033:    symbolic_constant50000005
-// CHECK:STDOUT:       inst50000034:    symbolic_constant50000004
-// CHECK:STDOUT:       inst50000035:    symbolic_constant50000005
-// CHECK:STDOUT:       inst50000036:    concrete_constant(inst50000036)
-// CHECK:STDOUT:       inst50000037:    symbolic_constant50000005
-// CHECK:STDOUT:       inst50000038:    symbolic_constant50000007
-// CHECK:STDOUT:       inst50000039:    symbolic_constant50000006
+// CHECK:STDOUT:       inst5000002E:    symbolic_constant50000003
+// CHECK:STDOUT:       inst5000002F:    constant<none>
+// CHECK:STDOUT:       inst50000030:    concrete_constant(inst50000027)
+// CHECK:STDOUT:       inst50000031:    concrete_constant(inst50000031)
+// CHECK:STDOUT:       inst50000032:    symbolic_constant50000005
+// CHECK:STDOUT:       inst50000033:    symbolic_constant50000004
+// CHECK:STDOUT:       inst50000034:    symbolic_constant50000005
+// CHECK:STDOUT:       inst50000035:    concrete_constant(inst50000035)
+// CHECK:STDOUT:       inst50000036:    symbolic_constant50000005
+// CHECK:STDOUT:       inst50000037:    symbolic_constant50000007
+// CHECK:STDOUT:       inst50000038:    symbolic_constant50000006
+// CHECK:STDOUT:       inst50000039:    symbolic_constant50000007
 // CHECK:STDOUT:       inst5000003A:    symbolic_constant50000007
-// CHECK:STDOUT:       inst5000003B:    symbolic_constant50000007
-// CHECK:STDOUT:       inst5000003C:    concrete_constant(inst5000003C)
-// CHECK:STDOUT:       inst5000003D:    concrete_constant(inst50000042)
-// CHECK:STDOUT:       inst5000003E:    concrete_constant(inst5000003E)
-// CHECK:STDOUT:       inst5000003F:    concrete_constant(inst5000003E)
-// CHECK:STDOUT:       inst50000041:    symbolic_constant50000008
-// CHECK:STDOUT:       inst50000042:    concrete_constant(inst50000042)
-// CHECK:STDOUT:       inst50000043:    symbolic_constant5000000B
-// CHECK:STDOUT:       inst50000044:    symbolic_constant50000009
-// CHECK:STDOUT:       inst50000045:    symbolic_constant5000000A
-// CHECK:STDOUT:       inst50000046:    symbolic_constant5000000B
-// CHECK:STDOUT:       inst50000047:    symbolic_constant5000000C
-// CHECK:STDOUT:       inst50000048:    concrete_constant(inst50000048)
-// CHECK:STDOUT:       inst50000049:    symbolic_constant5000000D
-// CHECK:STDOUT:       inst5000004B:    concrete_constant(inst5000004B)
-// CHECK:STDOUT:       inst5000004C:    symbolic_constant50000005
+// CHECK:STDOUT:       inst5000003B:    concrete_constant(inst5000003B)
+// CHECK:STDOUT:       inst5000003C:    concrete_constant(inst50000041)
+// CHECK:STDOUT:       inst5000003D:    concrete_constant(inst5000003D)
+// CHECK:STDOUT:       inst5000003E:    concrete_constant(inst5000003D)
+// CHECK:STDOUT:       inst50000040:    symbolic_constant50000008
+// CHECK:STDOUT:       inst50000041:    concrete_constant(inst50000041)
+// CHECK:STDOUT:       inst50000042:    symbolic_constant5000000B
+// CHECK:STDOUT:       inst50000043:    symbolic_constant50000009
+// CHECK:STDOUT:       inst50000044:    symbolic_constant5000000A
+// CHECK:STDOUT:       inst50000045:    symbolic_constant5000000B
+// CHECK:STDOUT:       inst50000046:    symbolic_constant5000000C
+// CHECK:STDOUT:       inst50000047:    concrete_constant(inst50000047)
+// CHECK:STDOUT:       inst50000048:    symbolic_constant5000000D
+// CHECK:STDOUT:       inst5000004A:    concrete_constant(inst5000004A)
+// CHECK:STDOUT:       inst5000004B:    symbolic_constant50000005
+// CHECK:STDOUT:       inst5000004C:    symbolic_constant50000007
 // CHECK:STDOUT:       inst5000004D:    symbolic_constant50000007
-// CHECK:STDOUT:       inst5000004E:    symbolic_constant50000007
-// CHECK:STDOUT:       inst5000004F:    concrete_constant(inst50000053)
-// CHECK:STDOUT:       inst50000050:    concrete_constant(inst50000050)
-// CHECK:STDOUT:       inst50000051:    concrete_constant(inst50000050)
-// CHECK:STDOUT:       inst50000053:    concrete_constant(inst50000053)
-// CHECK:STDOUT:       inst50000054:    symbolic_constant5000000F
-// CHECK:STDOUT:       inst50000055:    symbolic_constant5000000E
-// CHECK:STDOUT:       inst50000056:    symbolic_constant5000000F
-// CHECK:STDOUT:       inst50000057:    symbolic_constant50000010
-// CHECK:STDOUT:       inst50000058:    concrete_constant(inst50000058)
-// CHECK:STDOUT:       inst50000059:    symbolic_constant50000011
-// CHECK:STDOUT:       inst5000005B:    concrete_constant(inst5000005B)
-// CHECK:STDOUT:       inst5000005C:    concrete_constant(inst50000028)
-// CHECK:STDOUT:       inst5000005E:    symbolic_constant5000000B
-// CHECK:STDOUT:       inst50000060:    symbolic_constant5000000F
-// CHECK:STDOUT:       inst50000061:    concrete_constant(inst50000063)
+// CHECK:STDOUT:       inst5000004E:    concrete_constant(inst50000052)
+// CHECK:STDOUT:       inst5000004F:    concrete_constant(inst5000004F)
+// CHECK:STDOUT:       inst50000050:    concrete_constant(inst5000004F)
+// CHECK:STDOUT:       inst50000052:    concrete_constant(inst50000052)
+// CHECK:STDOUT:       inst50000053:    symbolic_constant5000000F
+// CHECK:STDOUT:       inst50000054:    symbolic_constant5000000E
+// CHECK:STDOUT:       inst50000055:    symbolic_constant5000000F
+// CHECK:STDOUT:       inst50000056:    symbolic_constant50000010
+// CHECK:STDOUT:       inst50000057:    concrete_constant(inst50000057)
+// CHECK:STDOUT:       inst50000058:    symbolic_constant50000011
+// CHECK:STDOUT:       inst5000005A:    concrete_constant(inst5000005A)
+// CHECK:STDOUT:       inst5000005B:    concrete_constant(inst50000027)
+// CHECK:STDOUT:       inst5000005D:    symbolic_constant5000000B
+// CHECK:STDOUT:       inst5000005F:    symbolic_constant5000000F
+// CHECK:STDOUT:       inst50000060:    concrete_constant(inst50000063)
+// CHECK:STDOUT:       inst50000061:    concrete_constant(inst50000061)
 // CHECK:STDOUT:       inst50000062:    concrete_constant(inst50000062)
 // CHECK:STDOUT:       inst50000063:    concrete_constant(inst50000063)
 // CHECK:STDOUT:       inst50000064:    symbolic_constant50000013
@@ -617,21 +622,21 @@ fn UseLocalCopy[T:! Copy](_: T.T1, _: T.T2) {}
 // CHECK:STDOUT:       symbolic_constant50000000: {inst: inst50000015, kind: checked, attached: null}
 // CHECK:STDOUT:       symbolic_constant50000001: {inst: inst50000015, kind: checked, attached: {generic: generic50000000, index: generic_inst_in_def0}}
 // CHECK:STDOUT:       symbolic_constant50000002: {inst: inst50000023, kind: self, attached: null}
-// CHECK:STDOUT:       symbolic_constant50000003: {inst: inst5000002A, kind: checked, attached: null}
-// CHECK:STDOUT:       symbolic_constant50000004: {inst: inst50000034, kind: checked, attached: null}
-// CHECK:STDOUT:       symbolic_constant50000005: {inst: inst50000034, kind: checked, attached: {generic: generic50000003, index: generic_inst_in_decl0}}
-// CHECK:STDOUT:       symbolic_constant50000006: {inst: inst50000039, kind: checked, attached: null}
-// CHECK:STDOUT:       symbolic_constant50000007: {inst: inst50000039, kind: checked, attached: {generic: generic50000003, index: generic_inst_in_decl1}}
-// CHECK:STDOUT:       symbolic_constant50000008: {inst: inst50000041, kind: checked, attached: null}
-// CHECK:STDOUT:       symbolic_constant50000009: {inst: inst50000044, kind: checked, attached: null}
-// CHECK:STDOUT:       symbolic_constant5000000A: {inst: inst50000041, kind: checked, attached: {generic: generic50000003, index: generic_inst_in_decl2}}
-// CHECK:STDOUT:       symbolic_constant5000000B: {inst: inst50000044, kind: checked, attached: {generic: generic50000003, index: generic_inst_in_decl3}}
-// CHECK:STDOUT:       symbolic_constant5000000C: {inst: inst50000047, kind: checked, attached: null}
-// CHECK:STDOUT:       symbolic_constant5000000D: {inst: inst50000047, kind: checked, attached: {generic: generic50000003, index: generic_inst_in_decl4}}
-// CHECK:STDOUT:       symbolic_constant5000000E: {inst: inst50000055, kind: checked, attached: null}
-// CHECK:STDOUT:       symbolic_constant5000000F: {inst: inst50000055, kind: checked, attached: {generic: generic50000003, index: generic_inst_in_decl5}}
-// CHECK:STDOUT:       symbolic_constant50000010: {inst: inst50000057, kind: checked, attached: null}
-// CHECK:STDOUT:       symbolic_constant50000011: {inst: inst50000057, kind: checked, attached: {generic: generic50000003, index: generic_inst_in_decl6}}
+// CHECK:STDOUT:       symbolic_constant50000003: {inst: inst50000029, kind: checked, attached: null}
+// CHECK:STDOUT:       symbolic_constant50000004: {inst: inst50000033, kind: checked, attached: null}
+// CHECK:STDOUT:       symbolic_constant50000005: {inst: inst50000033, kind: checked, attached: {generic: generic50000003, index: generic_inst_in_decl0}}
+// CHECK:STDOUT:       symbolic_constant50000006: {inst: inst50000038, kind: checked, attached: null}
+// CHECK:STDOUT:       symbolic_constant50000007: {inst: inst50000038, kind: checked, attached: {generic: generic50000003, index: generic_inst_in_decl1}}
+// CHECK:STDOUT:       symbolic_constant50000008: {inst: inst50000040, kind: checked, attached: null}
+// CHECK:STDOUT:       symbolic_constant50000009: {inst: inst50000043, kind: checked, attached: null}
+// CHECK:STDOUT:       symbolic_constant5000000A: {inst: inst50000040, kind: checked, attached: {generic: generic50000003, index: generic_inst_in_decl2}}
+// CHECK:STDOUT:       symbolic_constant5000000B: {inst: inst50000043, kind: checked, attached: {generic: generic50000003, index: generic_inst_in_decl3}}
+// CHECK:STDOUT:       symbolic_constant5000000C: {inst: inst50000046, kind: checked, attached: null}
+// CHECK:STDOUT:       symbolic_constant5000000D: {inst: inst50000046, kind: checked, attached: {generic: generic50000003, index: generic_inst_in_decl4}}
+// CHECK:STDOUT:       symbolic_constant5000000E: {inst: inst50000054, kind: checked, attached: null}
+// CHECK:STDOUT:       symbolic_constant5000000F: {inst: inst50000054, kind: checked, attached: {generic: generic50000003, index: generic_inst_in_decl5}}
+// CHECK:STDOUT:       symbolic_constant50000010: {inst: inst50000056, kind: checked, attached: null}
+// CHECK:STDOUT:       symbolic_constant50000011: {inst: inst50000056, kind: checked, attached: {generic: generic50000003, index: generic_inst_in_decl6}}
 // CHECK:STDOUT:       symbolic_constant50000012: {inst: inst50000065, kind: checked, attached: null}
 // CHECK:STDOUT:       symbolic_constant50000013: {inst: inst50000065, kind: checked, attached: {generic: generic50000003, index: generic_inst_in_def0}}
 // CHECK:STDOUT:       symbolic_constant50000014: {inst: inst50000068, kind: checked, attached: null}
@@ -658,24 +663,24 @@ fn UseLocalCopy[T:! Copy](_: T.T1, _: T.T2) {}
 // CHECK:STDOUT:     inst_block_empty: {}
 // CHECK:STDOUT:     exports:
 // CHECK:STDOUT:       0:               inst50000012
-// CHECK:STDOUT:       1:               inst50000061
+// CHECK:STDOUT:       1:               inst50000060
 // CHECK:STDOUT:       2:               inst50000095
 // CHECK:STDOUT:     generated:       {}
 // CHECK:STDOUT:     imports:
 // CHECK:STDOUT:       0:               inst50000011
-// CHECK:STDOUT:       1:               inst50000026
-// CHECK:STDOUT:       2:               inst50000027
-// CHECK:STDOUT:       3:               inst50000029
-// CHECK:STDOUT:       4:               inst5000002B
-// CHECK:STDOUT:       5:               inst5000002C
-// CHECK:STDOUT:       6:               inst5000002D
-// CHECK:STDOUT:       7:               inst5000002E
-// CHECK:STDOUT:       8:               inst5000002F
-// CHECK:STDOUT:       9:               inst50000030
-// CHECK:STDOUT:       10:              inst5000003D
-// CHECK:STDOUT:       11:              inst50000042
-// CHECK:STDOUT:       12:              inst5000004F
-// CHECK:STDOUT:       13:              inst50000053
+// CHECK:STDOUT:       1:               inst50000025
+// CHECK:STDOUT:       2:               inst50000026
+// CHECK:STDOUT:       3:               inst50000028
+// CHECK:STDOUT:       4:               inst5000002A
+// CHECK:STDOUT:       5:               inst5000002B
+// CHECK:STDOUT:       6:               inst5000002C
+// CHECK:STDOUT:       7:               inst5000002D
+// CHECK:STDOUT:       8:               inst5000002E
+// CHECK:STDOUT:       9:               inst5000002F
+// CHECK:STDOUT:       10:              inst5000003C
+// CHECK:STDOUT:       11:              inst50000041
+// CHECK:STDOUT:       12:              inst5000004E
+// CHECK:STDOUT:       13:              inst50000052
 // CHECK:STDOUT:     global_init:     {}
 // CHECK:STDOUT:     inst_block50000005:
 // CHECK:STDOUT:       0:               inst50000014
@@ -701,74 +706,74 @@ fn UseLocalCopy[T:! Copy](_: T.T1, _: T.T2) {}
 // CHECK:STDOUT:     inst_block5000000E:
 // CHECK:STDOUT:       0:               inst50000022
 // CHECK:STDOUT:       1:               inst50000024
-// CHECK:STDOUT:       2:               inst50000031
+// CHECK:STDOUT:       2:               inst50000030
 // CHECK:STDOUT:     inst_block5000000F:
-// CHECK:STDOUT:       0:               inst5000002D
-// CHECK:STDOUT:       1:               inst5000002E
+// CHECK:STDOUT:       0:               inst5000002C
+// CHECK:STDOUT:       1:               inst5000002D
 // CHECK:STDOUT:     inst_block50000010:
-// CHECK:STDOUT:       0:               inst5000002F
+// CHECK:STDOUT:       0:               inst5000002E
 // CHECK:STDOUT:     inst_block50000011:
-// CHECK:STDOUT:       0:               inst5000002A
+// CHECK:STDOUT:       0:               inst50000029
 // CHECK:STDOUT:     inst_block50000012:
-// CHECK:STDOUT:       0:               inst50000036
+// CHECK:STDOUT:       0:               inst50000035
 // CHECK:STDOUT:     inst_block50000013:
-// CHECK:STDOUT:       0:               inst50000037
-// CHECK:STDOUT:       1:               inst50000038
-// CHECK:STDOUT:       2:               inst5000003B
-// CHECK:STDOUT:       3:               inst5000003F
-// CHECK:STDOUT:       4:               inst50000043
+// CHECK:STDOUT:       0:               inst50000036
+// CHECK:STDOUT:       1:               inst50000037
+// CHECK:STDOUT:       2:               inst5000003A
+// CHECK:STDOUT:       3:               inst5000003E
+// CHECK:STDOUT:       4:               inst50000042
 // CHECK:STDOUT:     inst_block50000014:
-// CHECK:STDOUT:       0:               inst50000034
+// CHECK:STDOUT:       0:               inst50000033
 // CHECK:STDOUT:     inst_block50000015:
-// CHECK:STDOUT:       0:               inst50000041
+// CHECK:STDOUT:       0:               inst50000040
 // CHECK:STDOUT:     inst_block50000016:
-// CHECK:STDOUT:       0:               inst5000004C
-// CHECK:STDOUT:       1:               inst5000004D
-// CHECK:STDOUT:       2:               inst5000004E
-// CHECK:STDOUT:       3:               inst50000051
-// CHECK:STDOUT:       4:               inst50000054
-// CHECK:STDOUT:     inst_block50000017:
 // CHECK:STDOUT:       0:               inst5000004B
-// CHECK:STDOUT:       1:               inst5000005B
+// CHECK:STDOUT:       1:               inst5000004C
+// CHECK:STDOUT:       2:               inst5000004D
+// CHECK:STDOUT:       3:               inst50000050
+// CHECK:STDOUT:       4:               inst50000053
+// CHECK:STDOUT:     inst_block50000017:
+// CHECK:STDOUT:       0:               inst5000004A
+// CHECK:STDOUT:       1:               inst5000005A
 // CHECK:STDOUT:     inst_block50000018:
-// CHECK:STDOUT:       0:               inst50000048
-// CHECK:STDOUT:       1:               inst50000058
+// CHECK:STDOUT:       0:               inst50000047
+// CHECK:STDOUT:       1:               inst50000057
 // CHECK:STDOUT:     inst_block50000019:
-// CHECK:STDOUT:       0:               inst5000005D
-// CHECK:STDOUT:       1:               inst5000005F
+// CHECK:STDOUT:       0:               inst5000005C
+// CHECK:STDOUT:       1:               inst5000005E
 // CHECK:STDOUT:     inst_block5000001A:
-// CHECK:STDOUT:       0:               inst50000036
-// CHECK:STDOUT:       1:               inst50000048
-// CHECK:STDOUT:       2:               inst5000004B
-// CHECK:STDOUT:       3:               inst50000058
-// CHECK:STDOUT:       4:               inst5000005B
+// CHECK:STDOUT:       0:               inst50000035
+// CHECK:STDOUT:       1:               inst50000047
+// CHECK:STDOUT:       2:               inst5000004A
+// CHECK:STDOUT:       3:               inst50000057
+// CHECK:STDOUT:       4:               inst5000005A
 // CHECK:STDOUT:     inst_block5000001B:
-// CHECK:STDOUT:       0:               inst5000005C
-// CHECK:STDOUT:       1:               inst50000033
-// CHECK:STDOUT:       2:               inst5000005D
-// CHECK:STDOUT:       3:               inst5000005E
-// CHECK:STDOUT:       4:               inst5000004A
-// CHECK:STDOUT:       5:               inst5000005F
-// CHECK:STDOUT:       6:               inst50000060
-// CHECK:STDOUT:       7:               inst5000005A
+// CHECK:STDOUT:       0:               inst5000005B
+// CHECK:STDOUT:       1:               inst50000032
+// CHECK:STDOUT:       2:               inst5000005C
+// CHECK:STDOUT:       3:               inst5000005D
+// CHECK:STDOUT:       4:               inst50000049
+// CHECK:STDOUT:       5:               inst5000005E
+// CHECK:STDOUT:       6:               inst5000005F
+// CHECK:STDOUT:       7:               inst50000059
 // CHECK:STDOUT:     inst_block5000001C:
-// CHECK:STDOUT:       0:               inst50000033
+// CHECK:STDOUT:       0:               inst50000032
 // CHECK:STDOUT:     inst_block5000001D:
-// CHECK:STDOUT:       0:               inst50000035
-// CHECK:STDOUT:       1:               inst5000003A
-// CHECK:STDOUT:       2:               inst50000045
-// CHECK:STDOUT:       3:               inst50000046
-// CHECK:STDOUT:       4:               inst50000049
-// CHECK:STDOUT:       5:               inst50000056
-// CHECK:STDOUT:       6:               inst50000059
-// CHECK:STDOUT:     inst_block5000001E:
 // CHECK:STDOUT:       0:               inst50000034
 // CHECK:STDOUT:       1:               inst50000039
-// CHECK:STDOUT:       2:               inst50000041
-// CHECK:STDOUT:       3:               inst50000044
-// CHECK:STDOUT:       4:               inst50000047
+// CHECK:STDOUT:       2:               inst50000044
+// CHECK:STDOUT:       3:               inst50000045
+// CHECK:STDOUT:       4:               inst50000048
 // CHECK:STDOUT:       5:               inst50000055
-// CHECK:STDOUT:       6:               inst50000057
+// CHECK:STDOUT:       6:               inst50000058
+// CHECK:STDOUT:     inst_block5000001E:
+// CHECK:STDOUT:       0:               inst50000033
+// CHECK:STDOUT:       1:               inst50000038
+// CHECK:STDOUT:       2:               inst50000040
+// CHECK:STDOUT:       3:               inst50000043
+// CHECK:STDOUT:       4:               inst50000046
+// CHECK:STDOUT:       5:               inst50000054
+// CHECK:STDOUT:       6:               inst50000056
 // CHECK:STDOUT:     inst_block5000001F:
 // CHECK:STDOUT:       0:               inst5000006A
 // CHECK:STDOUT:     inst_block50000020:
@@ -846,7 +851,7 @@ fn UseLocalCopy[T:! Copy](_: T.T1, _: T.T2) {}
 // CHECK:STDOUT:       0:               instF
 // CHECK:STDOUT:       1:               inst50000010
 // CHECK:STDOUT:       2:               inst50000012
-// CHECK:STDOUT:       3:               inst50000061
+// CHECK:STDOUT:       3:               inst50000060
 // CHECK:STDOUT:       4:               inst50000095
 // CHECK:STDOUT:   value_stores:
 // CHECK:STDOUT:     shared_values:

+ 5 - 5
toolchain/check/testdata/basics/raw_sem_ir/one_file.carbon

@@ -412,6 +412,11 @@ fn Foo[T:! type](p: T*) -> (T*, ()) {
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
+// CHECK:STDOUT:     'type(inst(InstType))':
+// CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(InstType))}
+// CHECK:STDOUT:       object_layout:
+// CHECK:STDOUT:         size:            0
+// CHECK:STDOUT:         alignment:       1
 // CHECK:STDOUT:     'type(inst(NamespaceType))':
 // CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(NamespaceType))}
 // CHECK:STDOUT:       object_layout:
@@ -467,11 +472,6 @@ fn Foo[T:! type](p: T*) -> (T*, ()) {
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            8
 // CHECK:STDOUT:         alignment:       8
-// CHECK:STDOUT:     'type(inst(InstType))':
-// CHECK:STDOUT:       value_repr:      {kind: none, type: type(inst78000026)}
-// CHECK:STDOUT:       object_layout:
-// CHECK:STDOUT:         size:            0
-// CHECK:STDOUT:         alignment:       1
 // CHECK:STDOUT:     'type(inst78000050)':
 // CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst78000050)}
 // CHECK:STDOUT:       object_layout:

+ 5 - 0
toolchain/check/testdata/basics/raw_sem_ir/one_file_with_textual_ir.carbon

@@ -60,6 +60,11 @@ fn Foo(n: ()) -> ((), ()) {
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
+// CHECK:STDOUT:     'type(inst(InstType))':
+// CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(InstType))}
+// CHECK:STDOUT:       object_layout:
+// CHECK:STDOUT:         size:            0
+// CHECK:STDOUT:         alignment:       1
 // CHECK:STDOUT:     'type(inst(NamespaceType))':
 // CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(NamespaceType))}
 // CHECK:STDOUT:       object_layout:

+ 2 - 2
toolchain/check/testdata/builtins/cpp/std/initializer_list/make.carbon

@@ -58,9 +58,9 @@ library "[[@TEST_NAME]]";
 
 class FailIncomplete;
 
-// CHECK:STDERR: fail_incomplete.carbon:[[@LINE+11]]:20: error: function returns incomplete type `FailIncomplete` [IncompleteTypeInFunctionReturnType]
+// CHECK:STDERR: fail_incomplete.carbon:[[@LINE+11]]:17: error: function returns incomplete type `FailIncomplete` [IncompleteTypeInFunctionReturnType]
 // CHECK:STDERR: fn Make(n: i32) -> FailIncomplete = "cpp.std.initializer_list.make";
-// CHECK:STDERR:                    ^~~~~~~~~~~~~~
+// CHECK:STDERR:                 ^~~~~~~~~~~~~~~~~
 // CHECK:STDERR: fail_incomplete.carbon:[[@LINE-5]]:1: note: class was forward declared here [ClassForwardDeclaredHere]
 // CHECK:STDERR: class FailIncomplete;
 // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~

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

@@ -130,9 +130,9 @@ class Derived {
   var d: {};
 }
 
-// CHECK:STDERR: fail_return_abstract.carbon:[[@LINE+7]]:27: error: function returns abstract type `Abstract` [AbstractTypeInFunctionReturnType]
+// CHECK:STDERR: fail_return_abstract.carbon:[[@LINE+7]]:24: error: function returns abstract type `Abstract` [AbstractTypeInFunctionReturnType]
 // CHECK:STDERR: fn Return(a: Abstract) -> Abstract {
-// CHECK:STDERR:                           ^~~~~~~~
+// CHECK:STDERR:                        ^~~~~~~~~~~
 // CHECK:STDERR: fail_return_abstract.carbon:[[@LINE-12]]:1: note: class was declared abstract here [ClassAbstractHere]
 // CHECK:STDERR: abstract class Abstract {
 // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~
@@ -222,9 +222,9 @@ fn CallReturnAbstract() {
   // CHECK:STDERR: fail_call_abstract_return.carbon:[[@LINE-9]]:1: note: class was declared abstract here [ClassAbstractHere]
   // CHECK:STDERR: abstract class Abstract {
   // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~
-  // CHECK:STDERR: fail_call_abstract_return.carbon:[[@LINE-9]]:24: note: return type declared here [IncompleteReturnTypeHere]
+  // CHECK:STDERR: fail_call_abstract_return.carbon:[[@LINE-9]]:21: note: return type declared here [IncompleteReturnTypeHere]
   // CHECK:STDERR: fn ReturnAbstract() -> Abstract;
-  // CHECK:STDERR:                        ^~~~~~~~
+  // CHECK:STDERR:                     ^~~~~~~~~~~
   // CHECK:STDERR:
   ReturnAbstract();
 }

+ 6 - 6
toolchain/check/testdata/class/fail_incomplete.carbon

@@ -45,9 +45,9 @@ fn CallClassFunction() {
 // CHECK:STDERR:
 var global_var: Class;
 
-// CHECK:STDERR: fail_forward_decl.carbon:[[@LINE+7]]:27: error: function returns incomplete type `Class` [IncompleteTypeInFunctionReturnType]
+// CHECK:STDERR: fail_forward_decl.carbon:[[@LINE+7]]:24: error: function returns incomplete type `Class` [IncompleteTypeInFunctionReturnType]
 // CHECK:STDERR: fn ConvertFromStruct() -> Class { return {}; }
-// CHECK:STDERR:                           ^~~~~
+// CHECK:STDERR:                        ^~~~~~~~
 // CHECK:STDERR: fail_forward_decl.carbon:[[@LINE-34]]:1: note: class was forward declared here [ClassForwardDeclaredHere]
 // CHECK:STDERR: class Class;
 // CHECK:STDERR: ^~~~~~~~~~~~
@@ -76,9 +76,9 @@ fn MemberAccess(p: Class*) -> () {
   return (*p).n;
 }
 
-// CHECK:STDERR: fail_forward_decl.carbon:[[@LINE+7]]:23: error: function returns incomplete type `Class` [IncompleteTypeInFunctionReturnType]
+// CHECK:STDERR: fail_forward_decl.carbon:[[@LINE+7]]:20: error: function returns incomplete type `Class` [IncompleteTypeInFunctionReturnType]
 // CHECK:STDERR: fn Copy(p: Class*) -> Class {
-// CHECK:STDERR:                       ^~~~~
+// CHECK:STDERR:                    ^~~~~~~~
 // CHECK:STDERR: fail_forward_decl.carbon:[[@LINE-65]]:1: note: class was forward declared here [ClassForwardDeclaredHere]
 // CHECK:STDERR: class Class;
 // CHECK:STDERR: ^~~~~~~~~~~~
@@ -135,9 +135,9 @@ fn CallReturnIncomplete() {
   // CHECK:STDERR: fail_forward_decl.carbon:[[@LINE-118]]:1: note: class was forward declared here [ClassForwardDeclaredHere]
   // CHECK:STDERR: class Class;
   // CHECK:STDERR: ^~~~~~~~~~~~
-  // CHECK:STDERR: fail_forward_decl.carbon:[[@LINE-35]]:26: note: return type declared here [IncompleteReturnTypeHere]
+  // CHECK:STDERR: fail_forward_decl.carbon:[[@LINE-35]]:23: note: return type declared here [IncompleteReturnTypeHere]
   // CHECK:STDERR: fn ReturnIncomplete() -> Class;
-  // CHECK:STDERR:                          ^~~~~
+  // CHECK:STDERR:                       ^~~~~~~~
   // CHECK:STDERR:
   ReturnIncomplete();
 }

+ 1 - 1
toolchain/check/testdata/class/generic/basic.carbon

@@ -193,7 +193,7 @@ class Declaration(T:! type);
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc6_22: <witness> = require_complete_type %Class [symbolic = %require_complete.loc6_22 (constants.%require_complete.904)]
-// CHECK:STDOUT:   %require_complete.loc6_36: <witness> = require_complete_type %ptr.loc6_36.1 [symbolic = %require_complete.loc6_36 (constants.%require_complete.b60)]
+// CHECK:STDOUT:   %require_complete.loc6_32: <witness> = require_complete_type %ptr.loc6_36.1 [symbolic = %require_complete.loc6_32 (constants.%require_complete.b60)]
 // CHECK:STDOUT:   %Class.elem: type = unbound_element_type %Class, %T.as_type.loc6_36.1 [symbolic = %Class.elem (constants.%Class.elem)]
 // CHECK:STDOUT:   %.loc7_12.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.as_type.loc6_36.1) [symbolic = %.loc7_12.1 (constants.%.e85)]
 // CHECK:STDOUT:   %Copy.lookup_impl_witness: <witness> = lookup_impl_witness %ptr.loc6_36.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.b83)]

+ 1 - 1
toolchain/check/testdata/class/generic/init.carbon

@@ -51,9 +51,9 @@ fn InitFromAdaptedSpecific(x: i32) -> i32 {
 // CHECK:STDOUT: --- from_struct.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Destroy.type: type = facet_type <@Destroy> [concrete]
 // CHECK:STDOUT:   %Class.type: type = generic_class_type @Class [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Class.generic: %Class.type = struct_value () [concrete]
 // CHECK:STDOUT:   %Copy.type: type = facet_type <@Copy> [concrete]
 // CHECK:STDOUT:   %BitAndWith.type.f2e: type = generic_interface_type @BitAndWith [concrete]

+ 1 - 1
toolchain/check/testdata/class/generic/member_access.carbon

@@ -353,7 +353,7 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc13_22 => constants.%complete_type.1ec
-// CHECK:STDOUT:   %require_complete.loc13_36 => constants.%complete_type.3d0
+// CHECK:STDOUT:   %require_complete.loc13_32 => constants.%complete_type.3d0
 // CHECK:STDOUT:   %Class.elem => constants.%Class.elem.da5
 // CHECK:STDOUT:   %.loc15_12.1 => constants.%.cab
 // CHECK:STDOUT:   %Copy.lookup_impl_witness => constants.%Copy.impl_witness.843

+ 5 - 5
toolchain/check/testdata/class/generic/member_type.carbon

@@ -61,11 +61,11 @@ fn Test() -> i32 {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %type: type = facet_type <type> [concrete]
 // CHECK:STDOUT:   %.Self: %type = symbolic_binding .Self [symbolic_self]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Copy.type: type = facet_type <@Copy> [concrete]
 // CHECK:STDOUT:   %pattern_type.ce2: type = pattern_type %Copy.type [concrete]
 // CHECK:STDOUT:   %T.035: %Copy.type = symbolic_binding T, 0 [symbolic]
 // CHECK:STDOUT:   %Outer.type: type = generic_class_type @Outer [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Outer.generic: %Outer.type = struct_value () [concrete]
 // CHECK:STDOUT:   %Outer.4b9: type = class_type @Outer, @Outer(%T.035) [symbolic]
 // CHECK:STDOUT:   %Inner.bcf: type = class_type @Inner, @Inner(%T.035) [symbolic]
@@ -265,7 +265,7 @@ fn Test() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc9_9: <witness> = require_complete_type %T.as_type.loc9_11.1 [symbolic = %require_complete.loc9_9 (constants.%require_complete.89e)]
-// CHECK:STDOUT:   %require_complete.loc9_17: <witness> = require_complete_type %Inner [symbolic = %require_complete.loc9_17 (constants.%require_complete.e6c)]
+// CHECK:STDOUT:   %require_complete.loc9_14: <witness> = require_complete_type %Inner [symbolic = %require_complete.loc9_14 (constants.%require_complete.e6c)]
 // CHECK:STDOUT:   %struct_type.n: type = struct_type {.n: @Outer.F.%T.as_type.loc9_11.1 (%T.as_type)} [symbolic = %struct_type.n (constants.%struct_type.n.50e)]
 // CHECK:STDOUT:   %Copy.WithSelf.Op.type: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%T) [symbolic = %Copy.WithSelf.Op.type (constants.%Copy.WithSelf.Op.type.735e75.2)]
 // CHECK:STDOUT:   %.loc9_38: type = fn_type_with_self_type %Copy.WithSelf.Op.type, %T [symbolic = %.loc9_38 (constants.%.023)]
@@ -418,7 +418,7 @@ fn Test() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc9_9 => constants.%complete_type.f8a
-// CHECK:STDOUT:   %require_complete.loc9_17 => constants.%complete_type.54b
+// CHECK:STDOUT:   %require_complete.loc9_14 => constants.%complete_type.54b
 // CHECK:STDOUT:   %struct_type.n => constants.%struct_type.n.033
 // CHECK:STDOUT:   %Copy.WithSelf.Op.type => constants.%Copy.WithSelf.Op.type.081
 // CHECK:STDOUT:   %.loc9_38 => constants.%.8e2
@@ -741,7 +741,7 @@ fn Test() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc11_16: <witness> = require_complete_type %C [symbolic = %require_complete.loc11_16 (constants.%require_complete.4fd)]
-// CHECK:STDOUT:   %require_complete.loc11_26: <witness> = require_complete_type %T [symbolic = %require_complete.loc11_26 (constants.%require_complete.944)]
+// CHECK:STDOUT:   %require_complete.loc11_23: <witness> = require_complete_type %T [symbolic = %require_complete.loc11_23 (constants.%require_complete.944)]
 // CHECK:STDOUT:   %Inner.type: type = facet_type <@Inner, @Inner(%T)> [symbolic = %Inner.type (constants.%Inner.type.6ef)]
 // CHECK:STDOUT:   %require_complete.loc11_48: <witness> = require_complete_type %Inner.type [symbolic = %require_complete.loc11_48 (constants.%require_complete.8b6)]
 // CHECK:STDOUT:   %Inner.assoc_type: type = assoc_entity_type @Inner, @Inner(%T) [symbolic = %Inner.assoc_type (constants.%Inner.assoc_type.be2)]
@@ -1003,7 +1003,7 @@ fn Test() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc11_16 => constants.%complete_type.357
-// CHECK:STDOUT:   %require_complete.loc11_26 => constants.%complete_type.f8a
+// CHECK:STDOUT:   %require_complete.loc11_23 => constants.%complete_type.f8a
 // CHECK:STDOUT:   %Inner.type => constants.%Inner.type.94a
 // CHECK:STDOUT:   %require_complete.loc11_48 => constants.%complete_type.087
 // CHECK:STDOUT:   %Inner.assoc_type => constants.%Inner.assoc_type.564

+ 1 - 1
toolchain/check/testdata/class/virtual_modifiers.carbon

@@ -620,7 +620,6 @@ class T2(G2:! type) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Derived: type = class_type @Derived [concrete]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Base: type = class_type @Base [concrete]
 // CHECK:STDOUT:   %ptr.454: type = ptr_type <vtable> [concrete]
 // CHECK:STDOUT:   %struct_type.vptr: type = struct_type {.<vptr>: %ptr.454} [concrete]
@@ -628,6 +627,7 @@ class T2(G2:! type) {
 // CHECK:STDOUT:   %Derived.elem: type = unbound_element_type %Derived, %Base [concrete]
 // CHECK:STDOUT:   %pattern_type.9f6: type = pattern_type %Derived [concrete]
 // CHECK:STDOUT:   %Derived.H.type: type = fn_type @Derived.H [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Derived.H: %Derived.H.type = struct_value () [concrete]
 // CHECK:STDOUT:   %Base.H.type: type = fn_type @Base.H [concrete]
 // CHECK:STDOUT:   %Base.H: %Base.H.type = struct_value () [concrete]

+ 3 - 3
toolchain/check/testdata/deduce/array.carbon

@@ -356,7 +356,6 @@ fn G() {
 // CHECK:STDOUT:   %complete_type.357: <witness> = complete_type_witness %empty_struct_type [concrete]
 // CHECK:STDOUT:   %type: type = facet_type <type> [concrete]
 // CHECK:STDOUT:   %.Self: %type = symbolic_binding .Self [symbolic_self]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %IntLiteral.type: type = fn_type @IntLiteral [concrete]
 // CHECK:STDOUT:   %IntLiteral: %IntLiteral.type = struct_value () [concrete]
 // CHECK:STDOUT:   %pattern_type.dc0: type = pattern_type Core.IntLiteral [concrete]
@@ -365,6 +364,7 @@ fn G() {
 // CHECK:STDOUT:   %pattern_type.cc9: type = pattern_type %array_type.c79 [symbolic]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [concrete]
 // CHECK:STDOUT:   %Int.type: type = generic_class_type @Int [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Int.generic: %Int.type = struct_value () [concrete]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [concrete]
 // CHECK:STDOUT:   %.ff5: Core.Form = init_form %i32 [concrete]
@@ -590,7 +590,6 @@ fn G() {
 // CHECK:STDOUT:   %.Self: %type = symbolic_binding .Self [symbolic_self]
 // CHECK:STDOUT:   %pattern_type.98f: type = pattern_type type [concrete]
 // CHECK:STDOUT:   %T: type = symbolic_binding T, 0 [symbolic]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %IntLiteral.type: type = fn_type @IntLiteral [concrete]
 // CHECK:STDOUT:   %IntLiteral: %IntLiteral.type = struct_value () [concrete]
 // CHECK:STDOUT:   %pattern_type.dc0: type = pattern_type Core.IntLiteral [concrete]
@@ -598,6 +597,7 @@ fn G() {
 // CHECK:STDOUT:   %array_type.6d2: type = array_type %N, %T [symbolic]
 // CHECK:STDOUT:   %pattern_type.4d8: type = pattern_type %array_type.6d2 [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [concrete]
 // CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %array_type.6d2 [symbolic]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [concrete]
@@ -983,7 +983,6 @@ fn G() {
 // CHECK:STDOUT:   %D: type = class_type @D [concrete]
 // CHECK:STDOUT:   %type: type = facet_type <type> [concrete]
 // CHECK:STDOUT:   %.Self: %type = symbolic_binding .Self [symbolic_self]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %IntLiteral.type: type = fn_type @IntLiteral [concrete]
 // CHECK:STDOUT:   %IntLiteral: %IntLiteral.type = struct_value () [concrete]
 // CHECK:STDOUT:   %pattern_type.dc0: type = pattern_type Core.IntLiteral [concrete]
@@ -992,6 +991,7 @@ fn G() {
 // CHECK:STDOUT:   %pattern_type.cc9: type = pattern_type %array_type.c79 [symbolic]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [concrete]
 // CHECK:STDOUT:   %Int.type: type = generic_class_type @Int [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Int.generic: %Int.type = struct_value () [concrete]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [concrete]
 // CHECK:STDOUT:   %.ff5: Core.Form = init_form %i32 [concrete]

+ 6 - 6
toolchain/check/testdata/deduce/generic_type.carbon

@@ -200,7 +200,7 @@ fn G() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc7_17: <witness> = require_complete_type %C.loc7_22.1 [symbolic = %require_complete.loc7_17 (constants.%require_complete.32c)]
-// CHECK:STDOUT:   %require_complete.loc7_28: <witness> = require_complete_type %T.loc7_7.1 [symbolic = %require_complete.loc7_28 (constants.%require_complete.944)]
+// CHECK:STDOUT:   %require_complete.loc7_25: <witness> = require_complete_type %T.loc7_7.1 [symbolic = %require_complete.loc7_25 (constants.%require_complete.944)]
 // CHECK:STDOUT:   %F.specific_fn.loc7_39.2: <specific function> = specific_function constants.%F, @F(%T.loc7_7.1) [symbolic = %F.specific_fn.loc7_39.2 (constants.%F.specific_fn.643)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%p.param: @F.%C.loc7_22.1 (%C.5a3)) -> out %return.param: @F.%T.loc7_7.1 (%T) {
@@ -239,7 +239,7 @@ fn G() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc7_17 => constants.%require_complete.32c
-// CHECK:STDOUT:   %require_complete.loc7_28 => constants.%require_complete.944
+// CHECK:STDOUT:   %require_complete.loc7_25 => constants.%require_complete.944
 // CHECK:STDOUT:   %F.specific_fn.loc7_39.2 => constants.%F.specific_fn.643
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -258,7 +258,7 @@ fn G() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc7_17 => constants.%complete_type
-// CHECK:STDOUT:   %require_complete.loc7_28 => constants.%complete_type
+// CHECK:STDOUT:   %require_complete.loc7_25 => constants.%complete_type
 // CHECK:STDOUT:   %F.specific_fn.loc7_39.2 => constants.%F.specific_fn.e8a
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -652,7 +652,7 @@ fn G() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc13_27: <witness> = require_complete_type %Inner.loc13_45.1 [symbolic = %require_complete.loc13_27 (constants.%require_complete.41c)]
-// CHECK:STDOUT:   %require_complete.loc13_56: <witness> = require_complete_type %tuple.type [symbolic = %require_complete.loc13_56 (constants.%require_complete.220)]
+// CHECK:STDOUT:   %require_complete.loc13_48: <witness> = require_complete_type %tuple.type [symbolic = %require_complete.loc13_48 (constants.%require_complete.220)]
 // CHECK:STDOUT:   %F.specific_fn.loc13_67.2: <specific function> = specific_function constants.%F, @F(%T.loc13_7.1, %U.loc13_17.1) [symbolic = %F.specific_fn.loc13_67.2 (constants.%F.specific_fn.a54)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%p.param: @F.%Inner.loc13_45.1 (%Inner.e21)) -> out %return.param: @F.%tuple.type (%tuple.type.a5e) {
@@ -706,7 +706,7 @@ fn G() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc13_27 => constants.%require_complete.41c
-// CHECK:STDOUT:   %require_complete.loc13_56 => constants.%require_complete.220
+// CHECK:STDOUT:   %require_complete.loc13_48 => constants.%require_complete.220
 // CHECK:STDOUT:   %F.specific_fn.loc13_67.2 => constants.%F.specific_fn.a54
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -740,7 +740,7 @@ fn G() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc13_27 => constants.%complete_type.357
-// CHECK:STDOUT:   %require_complete.loc13_56 => constants.%complete_type.734
+// CHECK:STDOUT:   %require_complete.loc13_48 => constants.%complete_type.734
 // CHECK:STDOUT:   %F.specific_fn.loc13_67.2 => constants.%F.specific_fn.107
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 11 - 11
toolchain/check/testdata/deduce/type_operator.carbon

@@ -171,7 +171,7 @@ fn G(p: C*) -> const C {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc6_17: <witness> = require_complete_type %ptr.loc6_20.1 [symbolic = %require_complete.loc6_17 (constants.%require_complete.ef1)]
-// CHECK:STDOUT:   %require_complete.loc6_26: <witness> = require_complete_type %T.loc6_7.1 [symbolic = %require_complete.loc6_26 (constants.%require_complete.944)]
+// CHECK:STDOUT:   %require_complete.loc6_23: <witness> = require_complete_type %T.loc6_7.1 [symbolic = %require_complete.loc6_23 (constants.%require_complete.944)]
 // CHECK:STDOUT:   %F.specific_fn.loc6_37.2: <specific function> = specific_function constants.%F, @F(%T.loc6_7.1) [symbolic = %F.specific_fn.loc6_37.2 (constants.%F.specific_fn.643)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%p.param: @F.%ptr.loc6_20.1 (%ptr.e8f)) -> out %return.param: @F.%T.loc6_7.1 (%T) {
@@ -204,7 +204,7 @@ fn G(p: C*) -> const C {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc6_17 => constants.%require_complete.ef1
-// CHECK:STDOUT:   %require_complete.loc6_26 => constants.%require_complete.944
+// CHECK:STDOUT:   %require_complete.loc6_23 => constants.%require_complete.944
 // CHECK:STDOUT:   %F.specific_fn.loc6_37.2 => constants.%F.specific_fn.643
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -217,7 +217,7 @@ fn G(p: C*) -> const C {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc6_17 => constants.%complete_type.17a
-// CHECK:STDOUT:   %require_complete.loc6_26 => constants.%complete_type.357
+// CHECK:STDOUT:   %require_complete.loc6_23 => constants.%complete_type.357
 // CHECK:STDOUT:   %F.specific_fn.loc6_37.2 => constants.%F.specific_fn.540
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -330,7 +330,7 @@ fn G(p: C*) -> const C {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc6_17: <witness> = require_complete_type %ptr.loc6_26.1 [symbolic = %require_complete.loc6_17 (constants.%require_complete.0c1)]
-// CHECK:STDOUT:   %require_complete.loc6_32: <witness> = require_complete_type %T.loc6_7.1 [symbolic = %require_complete.loc6_32 (constants.%require_complete.944)]
+// CHECK:STDOUT:   %require_complete.loc6_29: <witness> = require_complete_type %T.loc6_7.1 [symbolic = %require_complete.loc6_29 (constants.%require_complete.944)]
 // CHECK:STDOUT:   %F.specific_fn.loc6_43.2: <specific function> = specific_function constants.%F, @F(%T.loc6_7.1) [symbolic = %F.specific_fn.loc6_43.2 (constants.%F.specific_fn.643)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%p.param: @F.%ptr.loc6_26.1 (%ptr.a15)) -> out %return.param: @F.%T.loc6_7.1 (%T) {
@@ -364,7 +364,7 @@ fn G(p: C*) -> const C {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc6_17 => constants.%require_complete.0c1
-// CHECK:STDOUT:   %require_complete.loc6_32 => constants.%require_complete.944
+// CHECK:STDOUT:   %require_complete.loc6_29 => constants.%require_complete.944
 // CHECK:STDOUT:   %F.specific_fn.loc6_43.2 => constants.%F.specific_fn.643
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -378,7 +378,7 @@ fn G(p: C*) -> const C {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc6_17 => constants.%complete_type.e6f
-// CHECK:STDOUT:   %require_complete.loc6_32 => constants.%complete_type.357
+// CHECK:STDOUT:   %require_complete.loc6_29 => constants.%complete_type.357
 // CHECK:STDOUT:   %F.specific_fn.loc6_43.2 => constants.%F.specific_fn.540
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -489,7 +489,7 @@ fn G(p: C*) -> const C {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc6_17: <witness> = require_complete_type %ptr.loc6_20.1 [symbolic = %require_complete.loc6_17 (constants.%require_complete.ef1)]
-// CHECK:STDOUT:   %require_complete.loc6_26: <witness> = require_complete_type %T.loc6_7.1 [symbolic = %require_complete.loc6_26 (constants.%require_complete.944)]
+// CHECK:STDOUT:   %require_complete.loc6_23: <witness> = require_complete_type %T.loc6_7.1 [symbolic = %require_complete.loc6_23 (constants.%require_complete.944)]
 // CHECK:STDOUT:   %F.specific_fn.loc6_37.2: <specific function> = specific_function constants.%F, @F(%T.loc6_7.1) [symbolic = %F.specific_fn.loc6_37.2 (constants.%F.specific_fn.643)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%p.param: @F.%ptr.loc6_20.1 (%ptr.e8f)) -> out %return.param: @F.%T.loc6_7.1 (%T) {
@@ -522,7 +522,7 @@ fn G(p: C*) -> const C {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc6_17 => constants.%require_complete.ef1
-// CHECK:STDOUT:   %require_complete.loc6_26 => constants.%require_complete.944
+// CHECK:STDOUT:   %require_complete.loc6_23 => constants.%require_complete.944
 // CHECK:STDOUT:   %F.specific_fn.loc6_37.2 => constants.%F.specific_fn.643
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -535,7 +535,7 @@ fn G(p: C*) -> const C {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc6_17 => constants.%complete_type.e6f
-// CHECK:STDOUT:   %require_complete.loc6_26 => constants.%complete_type.357
+// CHECK:STDOUT:   %require_complete.loc6_23 => constants.%complete_type.357
 // CHECK:STDOUT:   %F.specific_fn.loc6_37.2 => constants.%F.specific_fn.98a
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -646,7 +646,7 @@ fn G(p: C*) -> const C {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc6_17: <witness> = require_complete_type %ptr.loc6_26.1 [symbolic = %require_complete.loc6_17 (constants.%require_complete.0c1)]
-// CHECK:STDOUT:   %require_complete.loc6_32: <witness> = require_complete_type %T.loc6_7.1 [symbolic = %require_complete.loc6_32 (constants.%require_complete.944)]
+// CHECK:STDOUT:   %require_complete.loc6_29: <witness> = require_complete_type %T.loc6_7.1 [symbolic = %require_complete.loc6_29 (constants.%require_complete.944)]
 // CHECK:STDOUT:   %F.specific_fn.loc6_43.2: <specific function> = specific_function constants.%F, @F(%T.loc6_7.1) [symbolic = %F.specific_fn.loc6_43.2 (constants.%F.specific_fn)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%p.param: @F.%ptr.loc6_26.1 (%ptr.a15)) -> out %return.param: @F.%T.loc6_7.1 (%T) {
@@ -677,7 +677,7 @@ fn G(p: C*) -> const C {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc6_17 => constants.%require_complete.0c1
-// CHECK:STDOUT:   %require_complete.loc6_32 => constants.%require_complete.944
+// CHECK:STDOUT:   %require_complete.loc6_29 => constants.%require_complete.944
 // CHECK:STDOUT:   %F.specific_fn.loc6_43.2 => constants.%F.specific_fn
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 1
toolchain/check/testdata/eval/aggregates.carbon

@@ -484,9 +484,9 @@ fn G(N:! i32) {
 // CHECK:STDOUT: --- symbolic.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Destroy.type: type = facet_type <@Destroy> [concrete]
 // CHECK:STDOUT:   %T.765: %Destroy.type = symbolic_binding T, 0 [symbolic]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %T.as_type.2e9: type = facet_access_type %T.765 [symbolic]
 // CHECK:STDOUT:   %ptr.e44: type = ptr_type %T.as_type.2e9 [symbolic]
 // CHECK:STDOUT:   %const: type = const_type %T.as_type.2e9 [symbolic]

+ 1 - 1
toolchain/check/testdata/facet/access.carbon

@@ -630,10 +630,10 @@ fn F2(U:! Z) {
 // CHECK:STDOUT:   %A.assoc_type: type = assoc_entity_type @A [concrete]
 // CHECK:STDOUT:   %assoc0: %A.assoc_type = assoc_entity element0, @A.WithSelf.%X [concrete]
 // CHECK:STDOUT:   %.Self.091: %A.type = symbolic_binding .Self [symbolic_self]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self.091 [symbolic_self]
 // CHECK:STDOUT:   %A.lookup_impl_witness.6a5: <witness> = lookup_impl_witness %.Self.091, @A [symbolic_self]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %A.lookup_impl_witness.6a5, element0 [symbolic_self]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
 // CHECK:STDOUT:   %A_where.type: type = facet_type <@A where %impl.elem0 = %empty_tuple.type> [concrete]
 // CHECK:STDOUT:   %pattern_type.dc8: type = pattern_type %A_where.type [concrete]

+ 2 - 2
toolchain/check/testdata/facet/facet_assoc_const.carbon

@@ -99,7 +99,7 @@ library "[[@TEST_NAME]]";
 
 interface L { let W:! type; }
 
-// CHECK:STDERR: fail_two_different_combined_from_bitand.carbon:[[@LINE+4]]:17: error: associated constant `.(L.W)` given two different values `()` and `{}` [AssociatedConstantWithDifferentValues]
+// CHECK:STDERR: fail_two_different_combined_from_bitand.carbon:[[@LINE+4]]:17: error: associated constant `.(L.W)` given two different values `{}` and `()` [AssociatedConstantWithDifferentValues]
 // CHECK:STDERR: fn F(unused T:! (L where .W = {}) & (L where .W = ())) {}
 // CHECK:STDERR:                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // CHECK:STDERR:
@@ -648,12 +648,12 @@ fn F(unused T:! I & J where .I1 = .J1.I2) {}
 // CHECK:STDOUT:   %assoc1: %M.assoc_type = assoc_entity element1, @M.WithSelf.%Y [concrete]
 // CHECK:STDOUT:   %assoc2: %M.assoc_type = assoc_entity element2, @M.WithSelf.%Z [concrete]
 // CHECK:STDOUT:   %.Self.b4d: %M.type = symbolic_binding .Self [symbolic_self]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self.b4d [symbolic_self]
 // CHECK:STDOUT:   %M.lookup_impl_witness: <witness> = lookup_impl_witness %.Self.b4d, @M [symbolic_self]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %M.lookup_impl_witness, element0 [symbolic_self]
 // CHECK:STDOUT:   %impl.elem1: type = impl_witness_access %M.lookup_impl_witness, element1 [symbolic_self]
 // CHECK:STDOUT:   %impl.elem2: type = impl_witness_access %M.lookup_impl_witness, element2 [symbolic_self]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [concrete]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [concrete]

+ 5 - 5
toolchain/check/testdata/for/actual.carbon

@@ -54,12 +54,12 @@ fn Read(y:! Core.IntLiteral()) {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %type: type = facet_type <type> [concrete]
 // CHECK:STDOUT:   %.Self.c39: %type = symbolic_binding .Self [symbolic_self]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %IntLiteral.type: type = fn_type @IntLiteral [concrete]
 // CHECK:STDOUT:   %IntLiteral: %IntLiteral.type = struct_value () [concrete]
 // CHECK:STDOUT:   %pattern_type.dc0: type = pattern_type Core.IntLiteral [concrete]
 // CHECK:STDOUT:   %N: Core.IntLiteral = symbolic_binding N, 0 [symbolic]
 // CHECK:STDOUT:   %IntRange.type: type = generic_class_type @IntRange [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %IntRange.generic: %IntRange.type = struct_value () [concrete]
 // CHECK:STDOUT:   %IntRange.265: type = class_type @IntRange, @IntRange(%N) [symbolic]
 // CHECK:STDOUT:   %Int.type: type = generic_class_type @Int [concrete]
@@ -488,7 +488,7 @@ fn Read(y:! Core.IntLiteral()) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc5_16: <witness> = require_complete_type %Int.loc5_28.1 [symbolic = %require_complete.loc5_16 (constants.%require_complete.9019d7.1)]
-// CHECK:STDOUT:   %require_complete.loc5_52: <witness> = require_complete_type %IntRange [symbolic = %require_complete.loc5_52 (constants.%require_complete.8a1)]
+// CHECK:STDOUT:   %require_complete.loc5_49: <witness> = require_complete_type %IntRange [symbolic = %require_complete.loc5_49 (constants.%require_complete.8a1)]
 // CHECK:STDOUT:   %struct_type.start.end: type = struct_type {.start: @IntRange.Make.%Int.loc5_28.1 (%Int.fc6021.1), .end: @IntRange.Make.%Int.loc5_28.1 (%Int.fc6021.1)} [symbolic = %struct_type.start.end (constants.%struct_type.start.end.ff1)]
 // CHECK:STDOUT:   %.loc6_22.1: require_specific_def_type = require_specific_def @Int.as.Copy.impl(%N) [symbolic = %.loc6_22.1 (constants.%.4f8)]
 // CHECK:STDOUT:   %Copy.lookup_impl_witness: <witness> = lookup_impl_witness %Int.loc5_28.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.7a8)]
@@ -578,7 +578,7 @@ fn Read(y:! Core.IntLiteral()) {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc11_17: <witness> = require_complete_type %IntRange [symbolic = %require_complete.loc11_17 (constants.%require_complete.8a1)]
 // CHECK:STDOUT:   %require_complete.loc11_31: <witness> = require_complete_type %ptr.loc11_44.1 [symbolic = %require_complete.loc11_31 (constants.%require_complete.45c)]
-// CHECK:STDOUT:   %require_complete.loc11_75: <witness> = require_complete_type %Optional.loc11_75.1 [symbolic = %require_complete.loc11_75 (constants.%require_complete.0bc)]
+// CHECK:STDOUT:   %require_complete.loc11_47: <witness> = require_complete_type %Optional.loc11_75.1 [symbolic = %require_complete.loc11_47 (constants.%require_complete.0bc)]
 // CHECK:STDOUT:   %require_complete.loc12: <witness> = require_complete_type %Int.loc11_43.1 [symbolic = %require_complete.loc12 (constants.%require_complete.9019d7.1)]
 // CHECK:STDOUT:   %pattern_type.loc12: type = pattern_type %Int.loc11_43.1 [symbolic = %pattern_type.loc12 (constants.%pattern_type.764eab.1)]
 // CHECK:STDOUT:   %.loc12_32.3: require_specific_def_type = require_specific_def @Int.as.Copy.impl(%N) [symbolic = %.loc12_32.3 (constants.%.4f8)]
@@ -832,7 +832,7 @@ fn Read(y:! Core.IntLiteral()) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc5_16 => constants.%complete_type.f8a
-// CHECK:STDOUT:   %require_complete.loc5_52 => constants.%complete_type.c45
+// CHECK:STDOUT:   %require_complete.loc5_49 => constants.%complete_type.c45
 // CHECK:STDOUT:   %struct_type.start.end => constants.%struct_type.start.end.d0a
 // CHECK:STDOUT:   %.loc6_22.1 => constants.%.14e
 // CHECK:STDOUT:   %Copy.lookup_impl_witness => constants.%Copy.impl_witness.f17
@@ -848,12 +848,12 @@ fn Read(y:! Core.IntLiteral()) {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %type: type = facet_type <type> [concrete]
 // CHECK:STDOUT:   %.Self: %type = symbolic_binding .Self [symbolic_self]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %IntLiteral.type: type = fn_type @IntLiteral [concrete]
 // CHECK:STDOUT:   %IntLiteral: %IntLiteral.type = struct_value () [concrete]
 // CHECK:STDOUT:   %pattern_type.dc0: type = pattern_type Core.IntLiteral [concrete]
 // CHECK:STDOUT:   %y: Core.IntLiteral = symbolic_binding y, 0 [symbolic]
 // CHECK:STDOUT:   %Read.type: type = fn_type @Read [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Read: %Read.type = struct_value () [concrete]
 // CHECK:STDOUT:   %IntRange.type: type = generic_class_type @IntRange [concrete]
 // CHECK:STDOUT:   %IntRange.generic: %IntRange.type = struct_value () [concrete]

+ 1 - 1
toolchain/check/testdata/for/basic.carbon

@@ -57,9 +57,9 @@ fn Run() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %TrivialRange: type = class_type @TrivialRange [concrete]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Iterate.type: type = facet_type <@Iterate> [concrete]
 // CHECK:STDOUT:   %Copy.type: type = facet_type <@Copy> [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %T.035: %Copy.type = symbolic_binding T, 0 [symbolic]
 // CHECK:STDOUT:   %Optional.Get.type.5bc: type = fn_type @Optional.Get, @Optional(%T.035) [symbolic]
 // CHECK:STDOUT:   %Optional.Get.fa5: %Optional.Get.type.5bc = struct_value () [symbolic]

+ 106 - 37
toolchain/check/testdata/function/call/form.carbon

@@ -123,15 +123,7 @@ fn G() {
 library "[[@TEST_NAME]]";
 
 fn F() {
-  // CHECK:STDERR: fail_todo_local_init_form_binding.carbon:[[@LINE+12]]:7: error: semantics TODO: `Support local initializing forms` [SemanticsTodo]
-  // CHECK:STDERR:   let x:? form(var i32) = 0;
-  // CHECK:STDERR:       ^~~~~~~~~~~~~~~~~
-  // CHECK:STDERR:
-  // CHECK:STDERR: fail_todo_local_init_form_binding.carbon:[[@LINE+8]]:27: error: cannot bind durable reference to non-reference value of type `i32` [ConversionFailureNonRefToRef]
-  // CHECK:STDERR:   let x:? form(var i32) = 0;
-  // CHECK:STDERR:                           ^
-  // CHECK:STDERR:
-  // CHECK:STDERR: fail_todo_local_init_form_binding.carbon:[[@LINE+4]]:7: warning: binding `x` unused [UnusedBinding]
+  // CHECK:STDERR: fail_todo_local_init_form_binding.carbon:[[@LINE+4]]:7: error: semantics TODO: `support local form bindings` [SemanticsTodo]
   // CHECK:STDERR:   let x:? form(var i32) = 0;
   // CHECK:STDERR:       ^~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
@@ -214,13 +206,12 @@ fn F() ->? i32;
 // CHECK:STDERR:
 fn F() ->? ref i32;
 
-// --- fail_todo_form_generic_return.carbon
+// --- form_generic_return.carbon
+library "[[@TEST_NAME]]";
 
-// CHECK:STDERR: fail_todo_form_generic_return.carbon:[[@LINE+4]]:26: error: semantics TODO: `Support symbolic return forms` [SemanticsTodo]
-// CHECK:STDERR: fn F(Form:! Core.Form()) ->? Form;
-// CHECK:STDERR:                          ^~~~~~~~
-// CHECK:STDERR:
+//@dump-sem-ir-begin
 fn F(Form:! Core.Form()) ->? Form;
+//@dump-sem-ir-end
 
 // CHECK:STDOUT: --- ref_form_param.carbon
 // CHECK:STDOUT:
@@ -236,15 +227,15 @@ fn F(Form:! Core.Form()) ->? Form;
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
-// CHECK:STDOUT:     %.loc4_7: %pattern_type.7ce = form_param_pattern [concrete]
-// CHECK:STDOUT:     %x.patt: %pattern_type.7ce = at_binding_pattern x, %.loc4_7 [concrete]
+// CHECK:STDOUT:     %x.param_patt: %pattern_type.7ce = ref_param_pattern [concrete]
+// CHECK:STDOUT:     %x.patt: %pattern_type.7ce = at_binding_pattern x, %x.param_patt [concrete]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %x.param: ref %i32 = ref_param call_param0
 // CHECK:STDOUT:     %.loc4_15.1: Core.Form = splice_block %.loc4_15.2 [concrete = constants.%.1da] {
 // CHECK:STDOUT:       %i32: type = type_literal constants.%i32 [concrete = constants.%i32]
 // CHECK:STDOUT:       %.loc4_15.2: Core.Form = ref_form %i32 [concrete = constants.%.1da]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %x: ref %i32 = form_binding x, %x.param
+// CHECK:STDOUT:     %x: ref %i32 = ref_binding x, %x.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -297,15 +288,16 @@ fn F(Form:! Core.Form()) ->? Form;
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
-// CHECK:STDOUT:     %.loc4_7: %pattern_type.7ce = form_param_pattern [concrete]
-// CHECK:STDOUT:     %x.patt: %pattern_type.7ce = at_binding_pattern x, %.loc4_7 [concrete]
+// CHECK:STDOUT:     %x.param_patt: %pattern_type.7ce = ref_param_pattern [concrete]
+// CHECK:STDOUT:     %x.var_patt: %pattern_type.7ce = var_pattern %x.param_patt [concrete]
+// CHECK:STDOUT:     %x.patt: %pattern_type.7ce = at_binding_pattern x, %x.var_patt [concrete]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %x.param: ref %i32 = ref_param call_param0
 // CHECK:STDOUT:     %.loc4_15.1: Core.Form = splice_block %.loc4_15.2 [concrete = constants.%.ff5] {
 // CHECK:STDOUT:       %i32: type = type_literal constants.%i32 [concrete = constants.%i32]
 // CHECK:STDOUT:       %.loc4_15.2: Core.Form = init_form %i32 [concrete = constants.%.ff5]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %x: ref %i32 = form_binding x, %x.param
+// CHECK:STDOUT:     %x: ref %i32 = ref_binding x, %x.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -321,7 +313,7 @@ fn F(Form:! Core.Form()) ->? Form;
 // CHECK:STDOUT:   %bound_method.loc4_7.2: <bound method> = bound_method %int_0, %specific_fn [concrete = constants.%bound_method]
 // CHECK:STDOUT:   %Core.IntLiteral.as.ImplicitAs.impl.Convert.call: init %i32 = call %bound_method.loc4_7.2(%int_0) [concrete = constants.%int_0.6a9]
 // CHECK:STDOUT:   %.loc4: init %i32 = converted %int_0, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_0.6a9]
-// CHECK:STDOUT:   %x.var: ref %i32 = var @F.%.loc4_7
+// CHECK:STDOUT:   %x.var: ref %i32 = var @F.%x.var_patt
 // CHECK:STDOUT:   assign %x.var, %.loc4
 // CHECK:STDOUT:   %F.call: init %empty_tuple.type = call %F.ref(%x.var)
 // CHECK:STDOUT:   %Destroy.Op.bound: <bound method> = bound_method %x.var, constants.%Destroy.Op.651ba6.2
@@ -370,15 +362,15 @@ fn F(Form:! Core.Form()) ->? Form;
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
-// CHECK:STDOUT:     %.loc4_7: %pattern_type.7ce = form_param_pattern [concrete]
-// CHECK:STDOUT:     %x.patt: %pattern_type.7ce = at_binding_pattern x, %.loc4_7 [concrete]
+// CHECK:STDOUT:     %x.param_patt: %pattern_type.7ce = value_param_pattern [concrete]
+// CHECK:STDOUT:     %x.patt: %pattern_type.7ce = at_binding_pattern x, %x.param_patt [concrete]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %x.param: %i32 = value_param call_param0
 // CHECK:STDOUT:     %.loc4_15.1: Core.Form = splice_block %.loc4_15.2 [concrete = constants.%.754] {
 // CHECK:STDOUT:       %i32: type = type_literal constants.%i32 [concrete = constants.%i32]
 // CHECK:STDOUT:       %.loc4_15.2: Core.Form = value_form %i32 [concrete = constants.%.754]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %x: %i32 = form_binding x, %x.param
+// CHECK:STDOUT:     %x: %i32 = value_binding x, %x.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -412,8 +404,8 @@ fn F(Form:! Core.Form()) ->? Form;
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
-// CHECK:STDOUT:     %.loc4_7: %pattern_type = form_param_pattern [concrete]
-// CHECK:STDOUT:     %x.patt: %pattern_type = at_binding_pattern x, %.loc4_7 [concrete]
+// CHECK:STDOUT:     %x.param_patt: %pattern_type = ref_param_pattern [concrete]
+// CHECK:STDOUT:     %x.patt: %pattern_type = at_binding_pattern x, %x.param_patt [concrete]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %x.param: ref %empty_tuple.type = ref_param call_param0
 // CHECK:STDOUT:     %.loc4_15.1: Core.Form = splice_block %.loc4_15.2 [concrete = constants.%.9f9] {
@@ -421,7 +413,7 @@ fn F(Form:! Core.Form()) ->? Form;
 // CHECK:STDOUT:       %.loc4_20.2: type = converted %.loc4_20.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
 // CHECK:STDOUT:       %.loc4_15.2: Core.Form = ref_form %.loc4_20.2 [concrete = constants.%.9f9]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %x: ref %empty_tuple.type = form_binding x, %x.param
+// CHECK:STDOUT:     %x: ref %empty_tuple.type = ref_binding x, %x.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -440,13 +432,13 @@ fn F(Form:! Core.Form()) ->? Form;
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
-// CHECK:STDOUT:     %.loc4_8.1: %pattern_type.7ce = ref_return_pattern [concrete]
-// CHECK:STDOUT:     %return.patt: %pattern_type.7ce = return_slot_pattern %.loc4_8.1, constants.%i32 [concrete]
+// CHECK:STDOUT:     %.loc4_17.1: %pattern_type.7ce = ref_return_pattern [concrete]
+// CHECK:STDOUT:     %return.patt: %pattern_type.7ce = return_slot_pattern %.loc4_17.1, constants.%i32 [concrete]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %i32: type = type_literal constants.%i32 [concrete = constants.%i32]
-// CHECK:STDOUT:     %.loc4_17: Core.Form = ref_form %i32 [concrete = constants.%.1da]
-// CHECK:STDOUT:     %.loc4_8.2: ref %i32 = ref_return
-// CHECK:STDOUT:     %return: ref %i32 = return_slot %.loc4_8.2
+// CHECK:STDOUT:     %.loc4_17.2: Core.Form = ref_form %i32 [concrete = constants.%.1da]
+// CHECK:STDOUT:     %.loc4_17.3: ref %i32 = ref_return
+// CHECK:STDOUT:     %return: ref %i32 = return_slot %.loc4_17.3
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -530,13 +522,13 @@ fn F(Form:! Core.Form()) ->? Form;
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
-// CHECK:STDOUT:     %.loc4_8.1: %pattern_type.7ce = value_return_pattern [concrete]
-// CHECK:STDOUT:     %return.patt: %pattern_type.7ce = return_slot_pattern %.loc4_8.1, constants.%i32 [concrete]
+// CHECK:STDOUT:     %.loc4_17.1: %pattern_type.7ce = value_return_pattern [concrete]
+// CHECK:STDOUT:     %return.patt: %pattern_type.7ce = return_slot_pattern %.loc4_17.1, constants.%i32 [concrete]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %i32: type = type_literal constants.%i32 [concrete = constants.%i32]
-// CHECK:STDOUT:     %.loc4_17: Core.Form = value_form %i32 [concrete = constants.%.754]
-// CHECK:STDOUT:     %.loc4_8.2: %i32 = value_return
-// CHECK:STDOUT:     %return: %i32 = return_slot %.loc4_8.2
+// CHECK:STDOUT:     %.loc4_17.2: Core.Form = value_form %i32 [concrete = constants.%.754]
+// CHECK:STDOUT:     %.loc4_17.3: %i32 = value_return
+// CHECK:STDOUT:     %return: %i32 = return_slot %.loc4_17.3
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -554,3 +546,80 @@ fn F(Form:! Core.Form()) ->? Form;
 // CHECK:STDOUT:   <elided>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: --- form_generic_return.carbon
+// CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %Form.type: type = fn_type @Form [concrete]
+// CHECK:STDOUT:   %Form.ea2: %Form.type = struct_value () [concrete]
+// CHECK:STDOUT:   %pattern_type.13f: type = pattern_type Core.Form [concrete]
+// CHECK:STDOUT:   %Form.ac3: Core.Form = symbolic_binding Form, 0 [symbolic]
+// CHECK:STDOUT:   %.344: Core.Form = splice_inst @F.%.loc4_30.1 [template]
+// CHECK:STDOUT:   %.82f: type = type_component_of %.344 [template]
+// CHECK:STDOUT:   %pattern_type.ec7: type = pattern_type %.82f [template]
+// CHECK:STDOUT:   %.f74: %.82f = splice_inst @F.%.loc4_26.2 [template]
+// CHECK:STDOUT:   %.33d: <instruction> = refine_form_action %Form.ac3 [template]
+// CHECK:STDOUT:   %.80a: Core.Form = splice_inst %.33d [template]
+// CHECK:STDOUT:   %.af3: <instruction> = out_form_param_pattern_action %.80a [template]
+// CHECK:STDOUT:   %.465: type = type_component_of %.80a [template]
+// CHECK:STDOUT:   %.e7f: %.465 = splice_inst %.af3 [template]
+// CHECK:STDOUT:   %pattern_type.a51: type = pattern_type %.465 [template]
+// CHECK:STDOUT:   %.cab: <instruction> = callee_pattern_match_action %.e7f, call_param0 [template]
+// CHECK:STDOUT:   %F.type: type = fn_type @F [concrete]
+// CHECK:STDOUT:   %F: %F.type = struct_value () [concrete]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [concrete] {
+// CHECK:STDOUT:     .Form = %Core.Form
+// CHECK:STDOUT:     import Core//prelude
+// CHECK:STDOUT:     import Core//prelude/...
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Core.Form: %Form.type = import_ref Core//prelude/parts/form, Form, loaded [concrete = constants.%Form.ea2]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: file {
+// CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
+// CHECK:STDOUT:     %Form.patt: %pattern_type.13f = symbolic_binding_pattern Form, 0 [concrete]
+// CHECK:STDOUT:     %return.patt: @F.%pattern_type (%pattern_type.ec7) = return_slot_pattern %.loc4_26.6, constants.%.82f [concrete]
+// CHECK:STDOUT:   } {
+// CHECK:STDOUT:     %Form.ref.loc4_30: Core.Form = name_ref Form, %Form.loc4_10.2 [symbolic = %Form.loc4_10.1 (constants.%Form.ac3)]
+// CHECK:STDOUT:     %.loc4_30.3: Core.Form = splice_inst %.loc4_30.1 [template = %.loc4_30.2 (constants.%.344)]
+// CHECK:STDOUT:     %.loc4_26.6: @F.%.loc4_26.3 (%.82f) = splice_inst %.loc4_26.2 [template = %.loc4_26.4 (constants.%.f74)]
+// CHECK:STDOUT:     %.loc4_23.1: type = splice_block %.loc4_23.3 [concrete = Core.Form] {
+// CHECK:STDOUT:       <elided>
+// CHECK:STDOUT:       %Core.ref: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
+// CHECK:STDOUT:       %Form.ref.loc4_17: %Form.type = name_ref Form, imports.%Core.Form [concrete = constants.%Form.ea2]
+// CHECK:STDOUT:       %Form.call: init type = call %Form.ref.loc4_17() [concrete = Core.Form]
+// CHECK:STDOUT:       %.loc4_23.2: type = value_of_initializer %Form.call [concrete = Core.Form]
+// CHECK:STDOUT:       %.loc4_23.3: type = converted %Form.call, %.loc4_23.2 [concrete = Core.Form]
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %Form.loc4_10.2: Core.Form = symbolic_binding Form, 0 [symbolic = %Form.loc4_10.1 (constants.%Form.ac3)]
+// CHECK:STDOUT:     %.loc4_26.1: @F.%.loc4_26.3 (%.82f) = splice_inst %.loc4_26.5
+// CHECK:STDOUT:     %return: @F.%.loc4_26.3 (%.82f) = return_slot %.loc4_26.1
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @F(%Form.loc4_10.2: Core.Form) {
+// CHECK:STDOUT:   %Form.loc4_10.1: Core.Form = symbolic_binding Form, 0 [symbolic = %Form.loc4_10.1 (constants.%Form.ac3)]
+// CHECK:STDOUT:   %.loc4_30.1: <instruction> = refine_form_action %Form.ref.loc4_30 [template]
+// CHECK:STDOUT:   %.loc4_30.2: Core.Form = splice_inst %.loc4_30.1 [template = %.loc4_30.2 (constants.%.344)]
+// CHECK:STDOUT:   %.loc4_26.2: <instruction> = out_form_param_pattern_action %.loc4_30.3 [template]
+// CHECK:STDOUT:   %.loc4_26.3: type = type_component_of %.loc4_30.2 [template = %.loc4_26.3 (constants.%.82f)]
+// CHECK:STDOUT:   %.loc4_26.4: @F.%.loc4_26.3 (%.82f) = splice_inst %.loc4_26.2 [template = %.loc4_26.4 (constants.%.f74)]
+// CHECK:STDOUT:   %pattern_type: type = pattern_type %.loc4_26.3 [template = %pattern_type (constants.%pattern_type.ec7)]
+// CHECK:STDOUT:   %.loc4_26.5: <instruction> = callee_pattern_match_action %.loc4_26.6, call_param0 [template]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn() -> out %.loc4_26.1:? @F.%.loc4_30.1 (@F.%.loc4_30.1);
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @F(constants.%Form.ac3) {
+// CHECK:STDOUT:   %Form.loc4_10.1 => constants.%Form.ac3
+// CHECK:STDOUT:   %.loc4_30.1 => constants.%.33d
+// CHECK:STDOUT:   %.loc4_30.2 => constants.%.80a
+// CHECK:STDOUT:   %.loc4_26.2 => constants.%.af3
+// CHECK:STDOUT:   %.loc4_26.3 => constants.%.465
+// CHECK:STDOUT:   %.loc4_26.4 => constants.%.e7f
+// CHECK:STDOUT:   %pattern_type => constants.%pattern_type.a51
+// CHECK:STDOUT:   %.loc4_26.5 => constants.%.cab
+// CHECK:STDOUT: }
+// CHECK:STDOUT:

+ 8 - 8
toolchain/check/testdata/function/declaration/fail_import_incomplete_return.carbon

@@ -31,9 +31,9 @@ fn Call() {
   // CHECK:STDERR: fail_incomplete_return.carbon:[[@LINE-12]]:1: note: class was forward declared here [ClassForwardDeclaredHere]
   // CHECK:STDERR: class C;
   // CHECK:STDERR: ^~~~~~~~
-  // CHECK:STDERR: fail_incomplete_return.carbon:[[@LINE-11]]:21: note: return type declared here [IncompleteReturnTypeHere]
+  // CHECK:STDERR: fail_incomplete_return.carbon:[[@LINE-11]]:18: note: return type declared here [IncompleteReturnTypeHere]
   // CHECK:STDERR: fn ReturnCUsed() -> C;
-  // CHECK:STDERR:                     ^
+  // CHECK:STDERR:                  ^~~~
   // CHECK:STDERR:
   ReturnCUsed();
   // CHECK:STDERR: fail_incomplete_return.carbon:[[@LINE+10]]:3: error: function returns incomplete type `D` [IncompleteTypeInFunctionReturnType]
@@ -42,9 +42,9 @@ fn Call() {
   // CHECK:STDERR: fail_incomplete_return.carbon:[[@LINE-22]]:1: note: class was forward declared here [ClassForwardDeclaredHere]
   // CHECK:STDERR: class D;
   // CHECK:STDERR: ^~~~~~~~
-  // CHECK:STDERR: fail_incomplete_return.carbon:[[@LINE-20]]:21: note: return type declared here [IncompleteReturnTypeHere]
+  // CHECK:STDERR: fail_incomplete_return.carbon:[[@LINE-20]]:18: note: return type declared here [IncompleteReturnTypeHere]
   // CHECK:STDERR: fn ReturnDUsed() -> D;
-  // CHECK:STDERR:                     ^
+  // CHECK:STDERR:                  ^~~~
   // CHECK:STDERR:
   ReturnDUsed();
 }
@@ -66,9 +66,9 @@ fn CallFAndGIncomplete() {
   // CHECK:STDERR: class C;
   // CHECK:STDERR: ^~~~~~~~
   // CHECK:STDERR: fail_use_imported.carbon:[[@LINE-10]]:1: in import [InImport]
-  // CHECK:STDERR: fail_incomplete_return.carbon:7:23: note: return type declared here [IncompleteReturnTypeHere]
+  // CHECK:STDERR: fail_incomplete_return.carbon:7:20: note: return type declared here [IncompleteReturnTypeHere]
   // CHECK:STDERR: fn ReturnCUnused() -> C;
-  // CHECK:STDERR:                       ^
+  // CHECK:STDERR:                    ^~~~
   // CHECK:STDERR:
   ReturnCUnused();
   // CHECK:STDERR: fail_use_imported.carbon:[[@LINE+12]]:3: error: function returns incomplete type `C` [IncompleteTypeInFunctionReturnType]
@@ -79,9 +79,9 @@ fn CallFAndGIncomplete() {
   // CHECK:STDERR: class C;
   // CHECK:STDERR: ^~~~~~~~
   // CHECK:STDERR: fail_use_imported.carbon:[[@LINE-23]]:1: in import [InImport]
-  // CHECK:STDERR: fail_incomplete_return.carbon:8:21: note: return type declared here [IncompleteReturnTypeHere]
+  // CHECK:STDERR: fail_incomplete_return.carbon:8:18: note: return type declared here [IncompleteReturnTypeHere]
   // CHECK:STDERR: fn ReturnCUsed() -> C;
-  // CHECK:STDERR:                     ^
+  // CHECK:STDERR:                  ^~~~
   // CHECK:STDERR:
   ReturnCUsed();
   ReturnDUnused();

+ 6 - 6
toolchain/check/testdata/function/declaration/ref.carbon

@@ -53,14 +53,14 @@ fn G() {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
-// CHECK:STDOUT:     %.loc4_8.1: %pattern_type.7ce = ref_return_pattern [concrete]
-// CHECK:STDOUT:     %return.patt: %pattern_type.7ce = return_slot_pattern %.loc4_8.1, %i32 [concrete]
+// CHECK:STDOUT:     %.loc4_11.1: %pattern_type.7ce = ref_return_pattern [concrete]
+// CHECK:STDOUT:     %return.patt: %pattern_type.7ce = return_slot_pattern %.loc4_11.1, %i32 [concrete]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %i32: type = type_literal constants.%i32 [concrete = constants.%i32]
-// CHECK:STDOUT:     %.loc4_11.1: type = ref_tag %i32
-// CHECK:STDOUT:     %.loc4_11.2: Core.Form = ref_form %i32 [concrete = constants.%.1da]
-// CHECK:STDOUT:     %.loc4_8.2: ref %i32 = ref_return
-// CHECK:STDOUT:     %return: ref %i32 = return_slot %.loc4_8.2
+// CHECK:STDOUT:     %.loc4_11.2: type = ref_tag %i32
+// CHECK:STDOUT:     %.loc4_11.3: Core.Form = ref_form %i32 [concrete = constants.%.1da]
+// CHECK:STDOUT:     %.loc4_11.4: ref %i32 = ref_return
+// CHECK:STDOUT:     %return: ref %i32 = return_slot %.loc4_11.4
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {}
 // CHECK:STDOUT: }

+ 6 - 6
toolchain/check/testdata/function/generic/deduce.carbon

@@ -636,7 +636,7 @@ fn F() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc6_38: <witness> = require_complete_type %T.loc6_28.1 [symbolic = %require_complete.loc6_38 (constants.%require_complete.944)]
-// CHECK:STDOUT:   %require_complete.loc6_47: <witness> = require_complete_type %ptr.loc6_47.1 [symbolic = %require_complete.loc6_47 (constants.%require_complete.ef1)]
+// CHECK:STDOUT:   %require_complete.loc6_43: <witness> = require_complete_type %ptr.loc6_47.1 [symbolic = %require_complete.loc6_43 (constants.%require_complete.ef1)]
 // CHECK:STDOUT:   %ExplicitAndAlsoDeduced.specific_fn.loc7_10.2: <specific function> = specific_function constants.%ExplicitAndAlsoDeduced, @ExplicitAndAlsoDeduced(%T.loc6_28.1) [symbolic = %ExplicitAndAlsoDeduced.specific_fn.loc7_10.2 (constants.%ExplicitAndAlsoDeduced.specific_fn.7e7)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%x.param: @ExplicitAndAlsoDeduced.%T.loc6_28.1 (%T)) -> out %return.param: @ExplicitAndAlsoDeduced.%ptr.loc6_47.1 (%ptr.e8f) {
@@ -682,7 +682,7 @@ fn F() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc6_38 => constants.%require_complete.944
-// CHECK:STDOUT:   %require_complete.loc6_47 => constants.%require_complete.ef1
+// CHECK:STDOUT:   %require_complete.loc6_43 => constants.%require_complete.ef1
 // CHECK:STDOUT:   %ExplicitAndAlsoDeduced.specific_fn.loc7_10.2 => constants.%ExplicitAndAlsoDeduced.specific_fn.7e7
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -695,7 +695,7 @@ fn F() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc6_38 => constants.%complete_type.357
-// CHECK:STDOUT:   %require_complete.loc6_47 => constants.%complete_type.8a0
+// CHECK:STDOUT:   %require_complete.loc6_43 => constants.%complete_type.8a0
 // CHECK:STDOUT:   %ExplicitAndAlsoDeduced.specific_fn.loc7_10.2 => constants.%ExplicitAndAlsoDeduced.specific_fn.1f3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -794,7 +794,7 @@ fn F() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc4_36: <witness> = require_complete_type %T.loc4_26.1 [symbolic = %require_complete.loc4_36 (constants.%require_complete.944)]
-// CHECK:STDOUT:   %require_complete.loc4_45: <witness> = require_complete_type %ptr.loc4_45.1 [symbolic = %require_complete.loc4_45 (constants.%require_complete.ef1)]
+// CHECK:STDOUT:   %require_complete.loc4_41: <witness> = require_complete_type %ptr.loc4_45.1 [symbolic = %require_complete.loc4_41 (constants.%require_complete.ef1)]
 // CHECK:STDOUT:   %ImplicitGenericParam.specific_fn.loc4_56.2: <specific function> = specific_function constants.%ImplicitGenericParam, @ImplicitGenericParam(%T.loc4_26.1) [symbolic = %ImplicitGenericParam.specific_fn.loc4_56.2 (constants.%ImplicitGenericParam.specific_fn.7cc)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%x.param: @ImplicitGenericParam.%T.loc4_26.1 (%T)) -> out %return.param: @ImplicitGenericParam.%ptr.loc4_45.1 (%ptr.e8f) {
@@ -825,7 +825,7 @@ fn F() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc4_36 => constants.%require_complete.944
-// CHECK:STDOUT:   %require_complete.loc4_45 => constants.%require_complete.ef1
+// CHECK:STDOUT:   %require_complete.loc4_41 => constants.%require_complete.ef1
 // CHECK:STDOUT:   %ImplicitGenericParam.specific_fn.loc4_56.2 => constants.%ImplicitGenericParam.specific_fn.7cc
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -838,7 +838,7 @@ fn F() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc4_36 => constants.%complete_type.f8a
-// CHECK:STDOUT:   %require_complete.loc4_45 => constants.%complete_type.3d0
+// CHECK:STDOUT:   %require_complete.loc4_41 => constants.%complete_type.3d0
 // CHECK:STDOUT:   %ImplicitGenericParam.specific_fn.loc4_56.2 => constants.%ImplicitGenericParam.specific_fn.be5
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 1
toolchain/check/testdata/function/generic/resolve_used.carbon

@@ -43,12 +43,12 @@ fn CallNegative() {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %type: type = facet_type <type> [concrete]
 // CHECK:STDOUT:   %.Self: %type = symbolic_binding .Self [symbolic_self]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %IntLiteral.type: type = fn_type @IntLiteral [concrete]
 // CHECK:STDOUT:   %IntLiteral: %IntLiteral.type = struct_value () [concrete]
 // CHECK:STDOUT:   %pattern_type.dc0: type = pattern_type Core.IntLiteral [concrete]
 // CHECK:STDOUT:   %N: Core.IntLiteral = symbolic_binding N, 0 [symbolic]
 // CHECK:STDOUT:   %ErrorIfNIsZero.type: type = fn_type @ErrorIfNIsZero [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %ErrorIfNIsZero: %ErrorIfNIsZero.type = struct_value () [concrete]
 // CHECK:STDOUT:   %Int.type: type = generic_class_type @Int [concrete]
 // CHECK:STDOUT:   %Int.generic: %Int.type = struct_value () [concrete]

+ 1 - 1
toolchain/check/testdata/generic/template/unimplemented.carbon

@@ -252,13 +252,13 @@ fn F[template T:! Core.Destroy](x: T) {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %type: type = facet_type <type> [concrete]
 // CHECK:STDOUT:   %.Self: %type = symbolic_binding .Self [symbolic_self]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Destroy.type: type = facet_type <@Destroy> [concrete]
 // CHECK:STDOUT:   %pattern_type.cac: type = pattern_type %Destroy.type [concrete]
 // CHECK:STDOUT:   %T.765: %Destroy.type = symbolic_binding T, 0, template [template]
 // CHECK:STDOUT:   %T.as_type.2e9: type = facet_access_type %T.765 [template]
 // CHECK:STDOUT:   %pattern_type.eca0e4.2: type = pattern_type %T.as_type.2e9 [template]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [concrete]
 // CHECK:STDOUT:   %require_complete.6ff: <witness> = require_complete_type %T.as_type.2e9 [template]
 // CHECK:STDOUT:   %int_0: Core.IntLiteral = int_value 0 [concrete]

+ 1 - 1
toolchain/check/testdata/generic/template_dependence.carbon

@@ -92,7 +92,7 @@ fn F(template T:! type, U:! type) -> (T, U) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc5_26: <witness> = require_complete_type %ptr.loc5_30.1 [template = %require_complete.loc5_26 (constants.%require_complete.fbe)]
-// CHECK:STDOUT:   %require_complete.loc5_37: <witness> = require_complete_type %ptr.loc5_29.1 [template = %require_complete.loc5_37 (constants.%require_complete.ef162c.1)]
+// CHECK:STDOUT:   %require_complete.loc5_33: <witness> = require_complete_type %ptr.loc5_29.1 [template = %require_complete.loc5_33 (constants.%require_complete.ef162c.1)]
 // CHECK:STDOUT:   %.loc6_10.3: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc5_16.1) [template = %.loc6_10.3 (constants.%.2f2)]
 // CHECK:STDOUT:   %Copy.lookup_impl_witness: <witness> = lookup_impl_witness %ptr.loc5_29.1, @Copy [template = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.2e6)]
 // CHECK:STDOUT:   %Copy.facet: %Copy.type = facet_value %ptr.loc5_29.1, (%Copy.lookup_impl_witness) [template = %Copy.facet (constants.%Copy.facet)]

+ 1 - 1
toolchain/check/testdata/impl/assoc_const_self.carbon

@@ -577,12 +577,12 @@ fn CallF() {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %type: type = facet_type <type> [concrete]
 // CHECK:STDOUT:   %.Self.c39: %type = symbolic_binding .Self [symbolic_self]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %IntLiteral.type: type = fn_type @IntLiteral [concrete]
 // CHECK:STDOUT:   %IntLiteral: %IntLiteral.type = struct_value () [concrete]
 // CHECK:STDOUT:   %pattern_type.dc0: type = pattern_type Core.IntLiteral [concrete]
 // CHECK:STDOUT:   %N: Core.IntLiteral = symbolic_binding N, 0 [symbolic]
 // CHECK:STDOUT:   %I.type.609: type = generic_interface_type @I [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %I.generic: %I.type.609 = struct_value () [concrete]
 // CHECK:STDOUT:   %I.type.68b: type = facet_type <@I, @I(%N)> [symbolic]
 // CHECK:STDOUT:   %Self.cad: %I.type.68b = symbolic_binding Self, 1 [symbolic]

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

@@ -2,7 +2,7 @@
 // Exceptions. See /LICENSE for license information.
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
-// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/none.carbon
+// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/form.carbon
 //
 // AUTOUPDATE
 // TIP: To test this file alone, run:
@@ -12,15 +12,16 @@
 
 interface I {
   let T:! type;
-  // CHECK:STDERR: fail_todo_form_thunk.carbon:[[@LINE+4]]:8: error: semantics TODO: `Support for cloning form bindings` [SemanticsTodo]
-  // CHECK:STDERR:   fn F(x:? form(ref ()), y: T);
-  // CHECK:STDERR:        ^~~~~~~~~~~~~~~~
+  let Fm:! Core.Form();
+  // CHECK:STDERR: fail_todo_form_thunk.carbon:[[@LINE+4]]:8: error: semantics TODO: `Support symbolic form bindings` [SemanticsTodo]
+  // CHECK:STDERR:   fn F(x:? Fm, y: T);
+  // CHECK:STDERR:        ^~~~~~
   // CHECK:STDERR:
-  fn F(x:? form(ref ()), y: T);
+  fn F(x:? Fm, y: T);
 }
 
 class C {
-  impl as I where .T = () {
+  impl as I where .T = () and .Fm = form(ref ()) {
     fn F(x:? form(ref ()), ());
   }
 }

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

@@ -653,10 +653,10 @@ interface I {
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
 // CHECK:STDOUT:   %.Self: %I.type = symbolic_binding .Self [symbolic_self]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic_self]
 // CHECK:STDOUT:   %I.lookup_impl_witness: <witness> = lookup_impl_witness %.Self, @I [symbolic_self]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic_self]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
 // CHECK:STDOUT:   %I_where.type: type = facet_type <@I where %impl.elem0 = %empty_tuple.type> [concrete]
 // CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness @C.as.I.impl.%I.impl_witness_table [concrete]
@@ -792,10 +792,10 @@ interface I {
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
 // CHECK:STDOUT:   %.Self: %I.type = symbolic_binding .Self [symbolic_self]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic_self]
 // CHECK:STDOUT:   %I.lookup_impl_witness: <witness> = lookup_impl_witness %.Self, @I [symbolic_self]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic_self]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
 // CHECK:STDOUT:   %I_where.type: type = facet_type <@I where %impl.elem0 = %empty_tuple.type> [concrete]
 // CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness @C.as.I.impl.%I.impl_witness_table [concrete]
@@ -1569,10 +1569,10 @@ interface I {
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
 // CHECK:STDOUT:   %.Self: %I.type = symbolic_binding .Self [symbolic_self]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic_self]
 // CHECK:STDOUT:   %I.lookup_impl_witness: <witness> = lookup_impl_witness %.Self, @I [symbolic_self]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic_self]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
 // CHECK:STDOUT:   %I_where.type: type = facet_type <@I where %impl.elem0 = %empty_tuple.type> [concrete]
 // CHECK:STDOUT:   %I.impl_witness: <witness> = impl_witness @C.as.I.impl.%I.impl_witness_table [concrete]

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

@@ -618,13 +618,13 @@ impl CD as IF where .F = 0 {
 // CHECK:STDOUT:   %I.type: type = facet_type <@I> [concrete]
 // CHECK:STDOUT:   %Self: %I.type = symbolic_binding Self, 0 [symbolic]
 // CHECK:STDOUT:   %.Self: %I.type = symbolic_binding .Self [symbolic_self]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic_self]
 // CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type @I [concrete]
 // CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, imports.%Main.import_ref.9c9 [concrete]
 // CHECK:STDOUT:   %I.lookup_impl_witness: <witness> = lookup_impl_witness %.Self, @I [symbolic_self]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic_self]
 // CHECK:STDOUT:   %empty_struct: %empty_struct_type = struct_value () [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %I_where.type.1c0: type = facet_type <@I where %impl.elem0 = %empty_struct_type> [concrete]
 // CHECK:STDOUT:   %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
 // CHECK:STDOUT:   %I_where.type.0f9: type = facet_type <@I where %impl.elem0 = %empty_tuple.type> [concrete]
@@ -989,13 +989,13 @@ impl CD as IF where .F = 0 {
 // CHECK:STDOUT:   %I.type: type = facet_type <@I> [concrete]
 // CHECK:STDOUT:   %Self: %I.type = symbolic_binding Self, 0 [symbolic]
 // CHECK:STDOUT:   %.Self: %I.type = symbolic_binding .Self [symbolic_self]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic_self]
 // CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type @I [concrete]
 // CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, imports.%Main.import_ref.9c9 [concrete]
 // CHECK:STDOUT:   %I.lookup_impl_witness: <witness> = lookup_impl_witness %.Self, @I [symbolic_self]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic_self]
 // CHECK:STDOUT:   %empty_struct: %empty_struct_type = struct_value () [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -1085,12 +1085,12 @@ impl CD as IF where .F = 0 {
 // CHECK:STDOUT:   %I.type: type = facet_type <@I> [concrete]
 // CHECK:STDOUT:   %Self: %I.type = symbolic_binding Self, 0 [symbolic]
 // CHECK:STDOUT:   %.Self: %I.type = symbolic_binding .Self [symbolic_self]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic_self]
 // CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type @I [concrete]
 // CHECK:STDOUT:   %assoc0: %I.assoc_type = assoc_entity element0, imports.%Main.import_ref.9c9 [concrete]
 // CHECK:STDOUT:   %I.lookup_impl_witness: <witness> = lookup_impl_witness %.Self, @I [symbolic_self]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic_self]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 2 - 2
toolchain/check/testdata/impl/incomplete.carbon

@@ -343,8 +343,8 @@ interface B {
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
 // CHECK:STDOUT:   %.Self: %J.type = symbolic_binding .Self [symbolic_self]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic_self]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -531,9 +531,9 @@ interface B {
 // CHECK:STDOUT:   %Incomplete.type: type = facet_type <@Incomplete> [concrete]
 // CHECK:STDOUT:   %.Self: %J.type = symbolic_binding .Self [symbolic_self]
 // CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic_self]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %J.lookup_impl_witness: <witness> = lookup_impl_witness %.Self, @J [symbolic_self]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %J.lookup_impl_witness, element0 [symbolic_self]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
 // CHECK:STDOUT:   %J_where.type: type = facet_type <@J where .Self impls @Incomplete and %impl.elem0 = %empty_tuple.type> [concrete]
 // CHECK:STDOUT:   %J.impl_witness: <witness> = impl_witness @C.as.J.impl.%J.impl_witness_table [concrete]

+ 2 - 2
toolchain/check/testdata/impl/lookup/impl_forall.carbon

@@ -201,7 +201,7 @@ fn TestSpecific(a: A({})*) -> {}* {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc13_16: <witness> = require_complete_type %A [symbolic = %require_complete.loc13_16 (constants.%require_complete.fd6)]
-// CHECK:STDOUT:   %require_complete.loc13_30: <witness> = require_complete_type %ptr.loc13_30.1 [symbolic = %require_complete.loc13_30 (constants.%require_complete.ef162c.1)]
+// CHECK:STDOUT:   %require_complete.loc13_26: <witness> = require_complete_type %ptr.loc13_30.1 [symbolic = %require_complete.loc13_26 (constants.%require_complete.ef162c.1)]
 // CHECK:STDOUT:   %A.elem: type = unbound_element_type %A, %V [symbolic = %A.elem (constants.%A.elem.8a20fa.2)]
 // CHECK:STDOUT:   %.loc14_12.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%V) [symbolic = %.loc14_12.1 (constants.%.2f2)]
 // CHECK:STDOUT:   %Copy.lookup_impl_witness: <witness> = lookup_impl_witness %ptr.loc13_30.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.2e6)]
@@ -344,7 +344,7 @@ fn TestSpecific(a: A({})*) -> {}* {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc13_16 => constants.%complete_type.0a6
-// CHECK:STDOUT:   %require_complete.loc13_30 => constants.%complete_type.38e
+// CHECK:STDOUT:   %require_complete.loc13_26 => constants.%complete_type.38e
 // CHECK:STDOUT:   %A.elem => constants.%A.elem.599
 // CHECK:STDOUT:   %.loc14_12.1 => constants.%.07c
 // CHECK:STDOUT:   %Copy.lookup_impl_witness => constants.%Copy.impl_witness.3fd

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

@@ -650,12 +650,12 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: --- use_cf.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
 // CHECK:STDOUT:   %pattern_type.8e5: type = pattern_type %C [concrete]
 // CHECK:STDOUT:   %TestCF.type: type = fn_type @TestCF [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %TestCF: %TestCF.type = struct_value () [concrete]
 // CHECK:STDOUT:   %HasF.type: type = facet_type <@HasF> [concrete]
 // CHECK:STDOUT:   %Self: %HasF.type = symbolic_binding Self, 0 [symbolic]
@@ -787,12 +787,12 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: --- use_df.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %D: type = class_type @D [concrete]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
 // CHECK:STDOUT:   %pattern_type.f09: type = pattern_type %D [concrete]
 // CHECK:STDOUT:   %TestDF.type: type = fn_type @TestDF [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %TestDF: %TestDF.type = struct_value () [concrete]
 // CHECK:STDOUT:   %HasF.type: type = facet_type <@HasF> [concrete]
 // CHECK:STDOUT:   %Self: %HasF.type = symbolic_binding Self, 0 [symbolic]
@@ -947,12 +947,12 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: --- use_cg.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
 // CHECK:STDOUT:   %pattern_type.8e5: type = pattern_type %C [concrete]
 // CHECK:STDOUT:   %TestCG.type: type = fn_type @TestCG [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %TestCG: %TestCG.type = struct_value () [concrete]
 // CHECK:STDOUT:   %HasG.type: type = facet_type <@HasG> [concrete]
 // CHECK:STDOUT:   %Self: %HasG.type = symbolic_binding Self, 0 [symbolic]
@@ -1107,12 +1107,12 @@ fn Test(c: HasExtraInterfaces.C(type)) {
 // CHECK:STDOUT: --- use_dg.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %D: type = class_type @D [concrete]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
 // CHECK:STDOUT:   %pattern_type.f09: type = pattern_type %D [concrete]
 // CHECK:STDOUT:   %TestDG.type: type = fn_type @TestDG [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %TestDG: %TestDG.type = struct_value () [concrete]
 // CHECK:STDOUT:   %HasG.type: type = facet_type <@HasG> [concrete]
 // CHECK:STDOUT:   %Self: %HasG.type = symbolic_binding Self, 0 [symbolic]

+ 3 - 3
toolchain/check/testdata/impl/lookup/specialization_with_symbolic_rewrite.carbon

@@ -1038,7 +1038,7 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc9_16: <witness> = require_complete_type %T.loc9_7.1 [symbolic = %require_complete.loc9_16 (constants.%require_complete.944)]
-// CHECK:STDOUT:   %require_complete.loc9_30: <witness> = require_complete_type %ptr [symbolic = %require_complete.loc9_30 (constants.%require_complete.ef1)]
+// CHECK:STDOUT:   %require_complete.loc9_26: <witness> = require_complete_type %ptr [symbolic = %require_complete.loc9_26 (constants.%require_complete.ef1)]
 // CHECK:STDOUT:   %.loc10_10.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc9_7.1) [symbolic = %.loc10_10.1 (constants.%.2f2)]
 // CHECK:STDOUT:   %Copy.lookup_impl_witness: <witness> = lookup_impl_witness %ptr, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.2e6)]
 // CHECK:STDOUT:   %Copy.facet: %Copy.type = facet_value %ptr, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet)]
@@ -1266,7 +1266,7 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc9_15: <witness> = require_complete_type %T.as_type.loc9_22.1 [symbolic = %require_complete.loc9_15 (constants.%require_complete.e7f)]
-// CHECK:STDOUT:   %require_complete.loc9_29: <witness> = require_complete_type %ptr [symbolic = %require_complete.loc9_29 (constants.%require_complete.06a)]
+// CHECK:STDOUT:   %require_complete.loc9_25: <witness> = require_complete_type %ptr [symbolic = %require_complete.loc9_25 (constants.%require_complete.06a)]
 // CHECK:STDOUT:   %.loc10_10.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.as_type.loc9_22.1) [symbolic = %.loc10_10.1 (constants.%.592)]
 // CHECK:STDOUT:   %Copy.lookup_impl_witness: <witness> = lookup_impl_witness %ptr, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.48d)]
 // CHECK:STDOUT:   %Copy.facet: %Copy.type = facet_value %ptr, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet)]
@@ -1492,7 +1492,7 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc9_15: <witness> = require_complete_type %T.as_type.loc9_22.1 [symbolic = %require_complete.loc9_15 (constants.%require_complete.e7f)]
-// CHECK:STDOUT:   %require_complete.loc9_29: <witness> = require_complete_type %ptr [symbolic = %require_complete.loc9_29 (constants.%require_complete.06a)]
+// CHECK:STDOUT:   %require_complete.loc9_25: <witness> = require_complete_type %ptr [symbolic = %require_complete.loc9_25 (constants.%require_complete.06a)]
 // CHECK:STDOUT:   %.loc10_10.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.as_type.loc9_22.1) [symbolic = %.loc10_10.1 (constants.%.592)]
 // CHECK:STDOUT:   %Copy.lookup_impl_witness: <witness> = lookup_impl_witness %ptr, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.48d)]
 // CHECK:STDOUT:   %Copy.facet: %Copy.type = facet_value %ptr, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet)]

+ 2 - 2
toolchain/check/testdata/impl/use_assoc_entity.carbon

@@ -3081,10 +3081,10 @@ fn F() {
 // CHECK:STDOUT:   %assoc0.df0: %J.assoc_type = assoc_entity element0, @J.WithSelf.%X [concrete]
 // CHECK:STDOUT:   %E: type = class_type @E [concrete]
 // CHECK:STDOUT:   %.Self: %J.type = symbolic_binding .Self [symbolic_self]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic_self]
 // CHECK:STDOUT:   %J.lookup_impl_witness: <witness> = lookup_impl_witness %.Self, @J [symbolic_self]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %J.lookup_impl_witness, element0 [symbolic_self]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
 // CHECK:STDOUT:   %J_where.type: type = facet_type <@J where %impl.elem0 = %empty_tuple.type> [concrete]
 // CHECK:STDOUT:   %J.impl_witness: <witness> = impl_witness @E.as.J.impl.%J.impl_witness_table [concrete]
@@ -3205,8 +3205,8 @@ fn F() {
 // CHECK:STDOUT:   %assoc0: %J2.assoc_type = assoc_entity element0, @J2.WithSelf.%U2 [concrete]
 // CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self [symbolic]
 // CHECK:STDOUT:   %pattern_type.307: type = pattern_type %Self.as_type [symbolic]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %J2.WithSelf.F.type.68c: type = fn_type @J2.WithSelf.F, @J2.WithSelf(%Self) [symbolic]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %J2.WithSelf.F.643: %J2.WithSelf.F.type.68c = struct_value () [symbolic]
 // CHECK:STDOUT:   %assoc1: %J2.assoc_type = assoc_entity element1, @J2.WithSelf.%J2.WithSelf.F.decl [concrete]
 // CHECK:STDOUT:   %empty_tuple: %empty_tuple.type = tuple_value () [concrete]

+ 5 - 5
toolchain/check/testdata/interface/generic_method.carbon

@@ -456,7 +456,7 @@ fn CallIndirect() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc16_19: <witness> = require_complete_type %ptr.loc16_22.1 [symbolic = %require_complete.loc16_19 (constants.%require_complete.ef162c.1)]
-// CHECK:STDOUT:   %require_complete.loc16_37: <witness> = require_complete_type %tuple.type.loc16 [symbolic = %require_complete.loc16_37 (constants.%require_complete.034)]
+// CHECK:STDOUT:   %require_complete.loc16_25: <witness> = require_complete_type %tuple.type.loc16 [symbolic = %require_complete.loc16_25 (constants.%require_complete.034)]
 // CHECK:STDOUT:   %tuple.type.loc17: type = tuple_type (constants.%empty_struct_type, constants.%empty_struct_type, %ptr.loc16_22.1) [symbolic = %tuple.type.loc17 (constants.%tuple.type.dd2)]
 // CHECK:STDOUT:   %.loc17_21.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%U.loc16_9.1) [symbolic = %.loc17_21.1 (constants.%.2f2)]
 // CHECK:STDOUT:   %Copy.lookup_impl_witness: <witness> = lookup_impl_witness %ptr.loc16_22.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.2e6)]
@@ -716,7 +716,7 @@ fn CallIndirect() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc16_19 => constants.%complete_type.543
-// CHECK:STDOUT:   %require_complete.loc16_37 => constants.%complete_type.28e
+// CHECK:STDOUT:   %require_complete.loc16_25 => constants.%complete_type.28e
 // CHECK:STDOUT:   %tuple.type.loc17 => constants.%tuple.type.0dd
 // CHECK:STDOUT:   %.loc17_21.1 => constants.%.157
 // CHECK:STDOUT:   %Copy.lookup_impl_witness => constants.%Copy.impl_witness.425
@@ -1208,7 +1208,7 @@ fn CallIndirect() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc17_19: <witness> = require_complete_type %U.loc17_9.1 [symbolic = %require_complete.loc17_19 (constants.%require_complete.5a4)]
-// CHECK:STDOUT:   %require_complete.loc17_42: <witness> = require_complete_type %tuple.type.loc17_42.2 [symbolic = %require_complete.loc17_42 (constants.%require_complete.da0)]
+// CHECK:STDOUT:   %require_complete.loc17_24: <witness> = require_complete_type %tuple.type.loc17_42.2 [symbolic = %require_complete.loc17_24 (constants.%require_complete.da0)]
 // CHECK:STDOUT:   %tuple.type.as.A.impl.F.type: type = fn_type @tuple.type.as.A.impl.F, @tuple.type.as.A.impl(%V1, %V2, %W) [symbolic = %tuple.type.as.A.impl.F.type (constants.%tuple.type.as.A.impl.F.type.ce6)]
 // CHECK:STDOUT:   %tuple.type.as.A.impl.F: @tuple.type.as.A.impl.F.%tuple.type.as.A.impl.F.type (%tuple.type.as.A.impl.F.type.ce6) = struct_value () [symbolic = %tuple.type.as.A.impl.F (constants.%tuple.type.as.A.impl.F.74d)]
 // CHECK:STDOUT:   %tuple.type.as.A.impl.F.specific_fn.loc18_12.2: <specific function> = specific_function %tuple.type.as.A.impl.F, @tuple.type.as.A.impl.F(%V1, %V2, %W, %U.loc17_9.1) [symbolic = %tuple.type.as.A.impl.F.specific_fn.loc18_12.2 (constants.%tuple.type.as.A.impl.F.specific_fn.009)]
@@ -1425,7 +1425,7 @@ fn CallIndirect() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc17_19 => constants.%require_complete.5a4
-// CHECK:STDOUT:   %require_complete.loc17_42 => constants.%require_complete.da0
+// CHECK:STDOUT:   %require_complete.loc17_24 => constants.%require_complete.da0
 // CHECK:STDOUT:   %tuple.type.as.A.impl.F.type => constants.%tuple.type.as.A.impl.F.type.ce6
 // CHECK:STDOUT:   %tuple.type.as.A.impl.F => constants.%tuple.type.as.A.impl.F.74d
 // CHECK:STDOUT:   %tuple.type.as.A.impl.F.specific_fn.loc18_12.2 => constants.%tuple.type.as.A.impl.F.specific_fn.009
@@ -1516,7 +1516,7 @@ fn CallIndirect() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete.loc17_19 => constants.%complete_type.357
-// CHECK:STDOUT:   %require_complete.loc17_42 => constants.%complete_type.cf2
+// CHECK:STDOUT:   %require_complete.loc17_24 => constants.%complete_type.cf2
 // CHECK:STDOUT:   %tuple.type.as.A.impl.F.type => constants.%tuple.type.as.A.impl.F.type.d14
 // CHECK:STDOUT:   %tuple.type.as.A.impl.F => constants.%tuple.type.as.A.impl.F.cc8
 // CHECK:STDOUT:   %tuple.type.as.A.impl.F.specific_fn.loc18_12.2 => constants.%tuple.type.as.A.impl.F.specific_fn.af6

+ 1 - 1
toolchain/check/testdata/interface/require.carbon

@@ -684,10 +684,10 @@ interface Z(T:! type) {
 // CHECK:STDOUT:   %Self.c59: %Z.type = symbolic_binding Self, 0 [symbolic]
 // CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self.c59 [symbolic]
 // CHECK:STDOUT:   %.Self: %Y.type = symbolic_binding .Self [symbolic_self]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic_self]
 // CHECK:STDOUT:   %Y.lookup_impl_witness: <witness> = lookup_impl_witness %.Self, @Y [symbolic_self]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %Y.lookup_impl_witness, element0 [symbolic_self]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
 // CHECK:STDOUT:   %Y_where.type: type = facet_type <@Y where %impl.elem0 = %empty_tuple.type> [concrete]
 // CHECK:STDOUT: }

+ 8 - 8
toolchain/check/testdata/interop/cpp/class/import/access.carbon

@@ -1786,9 +1786,9 @@ fn Call(var instance: Cpp.PublicPrivate) {
 // CHECK:STDOUT: --- import_function_member_public.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S: type = class_type @S [concrete]
 // CHECK:STDOUT:   %ptr.5c7: type = ptr_type %S [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S.instance_fn.cpp_overload_set.type: type = cpp_overload_set_type @S.instance_fn.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %S.instance_fn.cpp_overload_set.value: %S.instance_fn.cpp_overload_set.type = cpp_overload_set_value @S.instance_fn.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %S.instance_fn.type: type = fn_type @S.instance_fn [concrete]
@@ -1865,8 +1865,8 @@ fn Call(var instance: Cpp.PublicPrivate) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Derived: type = class_type @Derived [concrete]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C.static_fn.cpp_overload_set.type: type = cpp_overload_set_type @C.static_fn.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %C.static_fn.cpp_overload_set.value: %C.static_fn.cpp_overload_set.type = cpp_overload_set_value @C.static_fn.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %C.static_fn.type: type = fn_type @C.static_fn [concrete]
@@ -2013,8 +2013,8 @@ fn Call(var instance: Cpp.PublicPrivate) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %D: type = class_type @D [concrete]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %struct_type.base.7c3: type = struct_type {.base: %C} [concrete]
 // CHECK:STDOUT:   %C.C.cpp_overload_set.type: type = cpp_overload_set_type @C.C.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %C.C.cpp_overload_set.value: %C.C.cpp_overload_set.type = cpp_overload_set_value @C.C.cpp_overload_set [concrete]
@@ -2276,8 +2276,8 @@ fn Call(var instance: Cpp.PublicPrivate) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Derived: type = class_type @Derived [concrete]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Public: type = class_type @Public [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Public.Overload.cpp_overload_set.type: type = cpp_overload_set_type @Public.Overload.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %Public.Overload.cpp_overload_set.value: %Public.Overload.cpp_overload_set.type = cpp_overload_set_value @Public.Overload.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %PublicCall: type = class_type @PublicCall [concrete]
@@ -2388,8 +2388,8 @@ fn Call(var instance: Cpp.PublicPrivate) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Derived: type = class_type @Derived [concrete]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Protected: type = class_type @Protected [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Protected.Overload.cpp_overload_set.type: type = cpp_overload_set_type @Protected.Overload.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %Protected.Overload.cpp_overload_set.value: %Protected.Overload.cpp_overload_set.type = cpp_overload_set_value @Protected.Overload.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %PublicCall: type = class_type @PublicCall [concrete]
@@ -2500,9 +2500,9 @@ fn Call(var instance: Cpp.PublicPrivate) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Derived: type = class_type @Derived [concrete]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Public: type = class_type @Public [concrete]
 // CHECK:STDOUT:   %Base: type = class_type @Base [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Public.PublicStatic.cpp_overload_set.type: type = cpp_overload_set_type @Public.PublicStatic.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %Public.PublicStatic.cpp_overload_set.value: %Public.PublicStatic.cpp_overload_set.type = cpp_overload_set_value @Public.PublicStatic.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %Base.PublicStatic.type: type = fn_type @Base.PublicStatic [concrete]
@@ -2651,9 +2651,9 @@ fn Call(var instance: Cpp.PublicPrivate) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Derived: type = class_type @Derived [concrete]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Protected: type = class_type @Protected [concrete]
 // CHECK:STDOUT:   %Base: type = class_type @Base [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Protected.PublicStatic.cpp_overload_set.type: type = cpp_overload_set_type @Protected.PublicStatic.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %Protected.PublicStatic.cpp_overload_set.value: %Protected.PublicStatic.cpp_overload_set.type = cpp_overload_set_value @Protected.PublicStatic.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %Base.PublicStatic.type: type = fn_type @Base.PublicStatic [concrete]
@@ -2750,10 +2750,10 @@ fn Call(var instance: Cpp.PublicPrivate) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Derived: type = class_type @Derived [concrete]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %PublicProtected: type = class_type @PublicProtected [concrete]
 // CHECK:STDOUT:   %Protected: type = class_type @Protected [concrete]
 // CHECK:STDOUT:   %Base: type = class_type @Base [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %PublicProtected.PublicStatic.cpp_overload_set.type: type = cpp_overload_set_type @PublicProtected.PublicStatic.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %PublicProtected.PublicStatic.cpp_overload_set.value: %PublicProtected.PublicStatic.cpp_overload_set.type = cpp_overload_set_value @PublicProtected.PublicStatic.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %Base.PublicStatic.type: type = fn_type @Base.PublicStatic [concrete]

+ 2 - 2
toolchain/check/testdata/interop/cpp/class/import/base.carbon

@@ -469,7 +469,6 @@ class V {
 // CHECK:STDOUT: --- use_derived_to_base_conversion.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Derived: type = class_type @Derived [concrete]
 // CHECK:STDOUT:   %ptr.ddb: type = ptr_type %Derived [concrete]
 // CHECK:STDOUT:   %pattern_type.5c8: type = pattern_type %ptr.ddb [concrete]
@@ -478,6 +477,7 @@ class V {
 // CHECK:STDOUT:   %.c2a: Core.Form = init_form %ptr.fb2 [concrete]
 // CHECK:STDOUT:   %pattern_type.72a: type = pattern_type %ptr.fb2 [concrete]
 // CHECK:STDOUT:   %ConvertPtr.type: type = fn_type @ConvertPtr [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %ConvertPtr: %ConvertPtr.type = struct_value () [concrete]
 // CHECK:STDOUT:   %Copy.type: type = facet_type <@Copy> [concrete]
 // CHECK:STDOUT:   %T.67d: type = symbolic_binding T, 0 [symbolic]
@@ -689,8 +689,8 @@ class V {
 // CHECK:STDOUT: --- use_base_method.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Derived: type = class_type @Derived [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Base: type = class_type @Base [concrete]
 // CHECK:STDOUT:   %Derived.f.cpp_overload_set.type: type = cpp_overload_set_type @Derived.f.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %Derived.f.cpp_overload_set.value: %Derived.f.cpp_overload_set.type = cpp_overload_set_value @Derived.f.cpp_overload_set [concrete]

+ 2 - 2
toolchain/check/testdata/interop/cpp/class/import/class.carbon

@@ -480,11 +480,11 @@ fn GenericUse(p2: Generic(Cpp.Class1)) {
 // CHECK:STDOUT: --- call_dynamic.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Bar: type = class_type @Bar [concrete]
 // CHECK:STDOUT:   %ptr.f68: type = ptr_type %Bar [concrete]
 // CHECK:STDOUT:   %pattern_type.146: type = pattern_type %ptr.f68 [concrete]
 // CHECK:STDOUT:   %MyF.type: type = fn_type @MyF [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %MyF: %MyF.type = struct_value () [concrete]
 // CHECK:STDOUT:   %Bar.f.cpp_overload_set.type: type = cpp_overload_set_type @Bar.f.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %Bar.f.cpp_overload_set.value: %Bar.f.cpp_overload_set.type = cpp_overload_set_value @Bar.f.cpp_overload_set [concrete]
@@ -535,8 +535,8 @@ fn GenericUse(p2: Generic(Cpp.Class1)) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Derived: type = class_type @Derived [concrete]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Bar: type = class_type @Bar [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Derived.elem: type = unbound_element_type %Derived, %Bar [concrete]
 // CHECK:STDOUT:   %struct_type.base.36d: type = struct_type {.base: %Bar} [concrete]
 // CHECK:STDOUT:   %complete_type.fff: <witness> = complete_type_witness %struct_type.base.36d [concrete]

+ 4 - 4
toolchain/check/testdata/interop/cpp/class/import/method.carbon

@@ -269,9 +269,9 @@ fn Call(e: Cpp.ExplicitObjectParam, n: i32, a: Cpp.Another) {
 // CHECK:STDOUT: --- use_object_param_qualifiers.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %HasQualifiers: type = class_type @HasQualifiers [concrete]
 // CHECK:STDOUT:   %Make.type: type = fn_type @Make [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Make: %Make.type = struct_value () [concrete]
 // CHECK:STDOUT:   %ptr.ec3: type = ptr_type %HasQualifiers [concrete]
 // CHECK:STDOUT:   %HasQualifiers.const_this.cpp_overload_set.type: type = cpp_overload_set_type @HasQualifiers.const_this.cpp_overload_set [concrete]
@@ -488,9 +488,9 @@ fn Call(e: Cpp.ExplicitObjectParam, n: i32, a: Cpp.Another) {
 // CHECK:STDOUT: --- use_object_param_qualifiers_overloaded.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %NoRefQualifier: type = class_type @NoRefQualifier [concrete]
 // CHECK:STDOUT:   %ptr.2a2: type = ptr_type %NoRefQualifier [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [concrete]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [concrete]
 // CHECK:STDOUT:   %i32.builtin: type = int_type signed, %int_32 [concrete]
@@ -628,9 +628,9 @@ fn Call(e: Cpp.ExplicitObjectParam, n: i32, a: Cpp.Another) {
 // CHECK:STDOUT: --- call_explicit_object_param.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %ExplicitObjectParam: type = class_type @ExplicitObjectParam [concrete]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [concrete]
 // CHECK:STDOUT:   %Another: type = class_type @Another [concrete]
 // CHECK:STDOUT:   %ExplicitObjectParam.F.cpp_overload_set.type: type = cpp_overload_set_type @ExplicitObjectParam.F.cpp_overload_set [concrete]
@@ -705,9 +705,9 @@ fn Call(e: Cpp.ExplicitObjectParam, n: i32, a: Cpp.Another) {
 // CHECK:STDOUT: --- call_explicit_object_param_overloaded.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %ExplicitObjectParam: type = class_type @ExplicitObjectParam [concrete]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [concrete]
 // CHECK:STDOUT:   %Another: type = class_type @Another [concrete]
 // CHECK:STDOUT:   %ExplicitObjectParam.F.cpp_overload_set.type: type = cpp_overload_set_type @ExplicitObjectParam.F.cpp_overload_set [concrete]

+ 1 - 1
toolchain/check/testdata/interop/cpp/class/import/template.carbon

@@ -83,9 +83,9 @@ var y: Cpp.Xint.r#type = 0;
 // CHECK:STDOUT: --- use_class_template.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %A.0bedf0.1: type = class_type @A.1 [concrete]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %N: Core.IntLiteral = symbolic_binding N, 0 [symbolic]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [concrete]
 // CHECK:STDOUT:   %Base: type = class_type @Base [concrete]

+ 11 - 11
toolchain/check/testdata/interop/cpp/function/import/class.carbon

@@ -495,8 +495,8 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_no_data_members_value_param_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %ptr.d9e: type = ptr_type %C [concrete]
@@ -533,8 +533,8 @@ fn F() {
 // CHECK:STDOUT: --- fail_import_non_copyable_param_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.type: type = fn_type @foo [concrete]
@@ -568,8 +568,8 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_single_data_member_value_param_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %ptr.d9e: type = ptr_type %C [concrete]
@@ -606,8 +606,8 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_multiple_data_members_value_param_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %ptr.d9e: type = ptr_type %C [concrete]
@@ -644,9 +644,9 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_in_namespace_value_param_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
 // CHECK:STDOUT:   %pattern_type.69f: type = pattern_type %C [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %ptr.838: type = ptr_type %C [concrete]
@@ -723,8 +723,8 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_in_relative_namespace_value_param_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %ptr.c0c: type = ptr_type %C [concrete]
@@ -770,8 +770,8 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_in_outer_definition.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %O: type = class_type @O [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
@@ -845,8 +845,8 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_and_static_method_call_before.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C.bar.cpp_overload_set.type: type = cpp_overload_set_type @C.bar.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %C.bar.cpp_overload_set.value: %C.bar.cpp_overload_set.type = cpp_overload_set_value @C.bar.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %C.bar.type: type = fn_type @C.bar [concrete]
@@ -893,8 +893,8 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_and_static_method_call_after.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %ptr.d9e: type = ptr_type %C [concrete]
@@ -941,9 +941,9 @@ fn F() {
 // CHECK:STDOUT: --- import_decl_pointer_param_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
 // CHECK:STDOUT:   %ptr: type = ptr_type %C [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.type: type = fn_type @foo [concrete]
@@ -977,9 +977,9 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_pointer_param_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
 // CHECK:STDOUT:   %ptr: type = ptr_type %C [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.type: type = fn_type @foo [concrete]

+ 1 - 1
toolchain/check/testdata/interop/cpp/function/import/extern_c.carbon

@@ -208,8 +208,8 @@ fn MyF(a: Cpp.X, b: Cpp.X) -> Cpp.X {
 // CHECK:STDOUT: --- extern_c_with_special_name.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %X: type = class_type @X [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %ptr.1f9: type = ptr_type %X [concrete]
 // CHECK:STDOUT:   %operator_Plus__carbon_thunk.type: type = fn_type @operator_Plus__carbon_thunk [concrete]
 // CHECK:STDOUT:   %operator_Plus__carbon_thunk: %operator_Plus__carbon_thunk.type = struct_value () [concrete]

+ 10 - 10
toolchain/check/testdata/interop/cpp/function/import/pointer.carbon

@@ -489,12 +489,12 @@ fn F() {
 // CHECK:STDOUT: --- import_non_nullable_pointer_param_using_const_pointer.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S: type = class_type @S [concrete]
 // CHECK:STDOUT:   %ptr: type = ptr_type %S [concrete]
 // CHECK:STDOUT:   %const: type = const_type %ptr [concrete]
 // CHECK:STDOUT:   %pattern_type.f25: type = pattern_type %const [concrete]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
@@ -657,11 +657,11 @@ fn F() {
 // CHECK:STDOUT: --- import_non_nullable_pointer_to_const_param_using_const.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S: type = class_type @S [concrete]
 // CHECK:STDOUT:   %const: type = const_type %S [concrete]
 // CHECK:STDOUT:   %pattern_type.9be: type = pattern_type %const [concrete]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
@@ -722,10 +722,10 @@ fn F() {
 // CHECK:STDOUT: --- import_non_nullable_pointer_to_const_param_using_non_const.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S: type = class_type @S [concrete]
 // CHECK:STDOUT:   %pattern_type.7da: type = pattern_type %S [concrete]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
@@ -784,12 +784,12 @@ fn F() {
 // CHECK:STDOUT: --- import_const_non_nullable_pointer_param_using_const.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S: type = class_type @S [concrete]
 // CHECK:STDOUT:   %ptr: type = ptr_type %S [concrete]
 // CHECK:STDOUT:   %const: type = const_type %ptr [concrete]
 // CHECK:STDOUT:   %pattern_type.f25: type = pattern_type %const [concrete]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
@@ -853,11 +853,11 @@ fn F() {
 // CHECK:STDOUT: --- import_const_non_nullable_pointer_param_using_non_const.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S: type = class_type @S [concrete]
 // CHECK:STDOUT:   %ptr: type = ptr_type %S [concrete]
 // CHECK:STDOUT:   %pattern_type.259: type = pattern_type %ptr [concrete]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
@@ -913,12 +913,12 @@ fn F() {
 // CHECK:STDOUT: --- import_const_nullable_pointer_param_using_const.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S: type = class_type @S [concrete]
 // CHECK:STDOUT:   %ptr.5c7: type = ptr_type %S [concrete]
 // CHECK:STDOUT:   %const.b9a: type = const_type %ptr.5c7 [concrete]
 // CHECK:STDOUT:   %pattern_type.f25: type = pattern_type %const.b9a [concrete]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
@@ -1060,11 +1060,11 @@ fn F() {
 // CHECK:STDOUT: --- import_const_nullable_pointer_param_using_non_const.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S: type = class_type @S [concrete]
 // CHECK:STDOUT:   %ptr.5c7: type = ptr_type %S [concrete]
 // CHECK:STDOUT:   %pattern_type.259: type = pattern_type %ptr.5c7 [concrete]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
@@ -1190,10 +1190,10 @@ fn F() {
 // CHECK:STDOUT: --- import_non_nullable_pointer_return.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S: type = class_type @S [concrete]
 // CHECK:STDOUT:   %ptr: type = ptr_type %S [concrete]
 // CHECK:STDOUT:   %IngestDoublePointer.type: type = fn_type @IngestDoublePointer [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %IngestDoublePointer: %IngestDoublePointer.type = struct_value () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
@@ -1234,11 +1234,11 @@ fn F() {
 // CHECK:STDOUT: --- import_double_pointer_return.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S: type = class_type @S [concrete]
 // CHECK:STDOUT:   %ptr.5c7: type = ptr_type %S [concrete]
 // CHECK:STDOUT:   %ptr.dfe: type = ptr_type %ptr.5c7 [concrete]
 // CHECK:STDOUT:   %IngestDoublePointer.type: type = fn_type @IngestDoublePointer [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %IngestDoublePointer: %IngestDoublePointer.type = struct_value () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
@@ -1279,11 +1279,11 @@ fn F() {
 // CHECK:STDOUT: --- import_const_non_nullable_pointer_return.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S: type = class_type @S [concrete]
 // CHECK:STDOUT:   %const: type = const_type %S [concrete]
 // CHECK:STDOUT:   %ptr: type = ptr_type %const [concrete]
 // CHECK:STDOUT:   %IngestConstPointer.type: type = fn_type @IngestConstPointer [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %IngestConstPointer: %IngestConstPointer.type = struct_value () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]

+ 11 - 11
toolchain/check/testdata/interop/cpp/function/import/struct.carbon

@@ -494,8 +494,8 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_no_data_members_value_param_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S: type = class_type @S [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %ptr.5c7: type = ptr_type %S [concrete]
@@ -532,8 +532,8 @@ fn F() {
 // CHECK:STDOUT: --- fail_import_non_copyable_param_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S: type = class_type @S [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.type: type = fn_type @foo [concrete]
@@ -567,8 +567,8 @@ fn F() {
 // CHECK:STDOUT: --- definition_single_data_member_value_param_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S: type = class_type @S [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %ptr.5c7: type = ptr_type %S [concrete]
@@ -605,8 +605,8 @@ fn F() {
 // CHECK:STDOUT: --- definition_multiple_data_members_value_param_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S: type = class_type @S [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %ptr.5c7: type = ptr_type %S [concrete]
@@ -643,9 +643,9 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_in_namespace_value_param_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S: type = class_type @S [concrete]
 // CHECK:STDOUT:   %pattern_type.cd8: type = pattern_type %S [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %ptr.edf: type = ptr_type %S [concrete]
@@ -722,8 +722,8 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_in_relative_namespace_value_param_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S: type = class_type @S [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %ptr.887: type = ptr_type %S [concrete]
@@ -769,8 +769,8 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_in_outer_definition.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %O: type = class_type @O [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S: type = class_type @S [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
@@ -844,8 +844,8 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_and_static_method_call_before.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S: type = class_type @S [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S.bar.cpp_overload_set.type: type = cpp_overload_set_type @S.bar.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %S.bar.cpp_overload_set.value: %S.bar.cpp_overload_set.type = cpp_overload_set_value @S.bar.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %S.bar.type: type = fn_type @S.bar [concrete]
@@ -892,8 +892,8 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_and_static_method_call_after.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S: type = class_type @S [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %ptr.5c7: type = ptr_type %S [concrete]
@@ -940,9 +940,9 @@ fn F() {
 // CHECK:STDOUT: --- import_decl_pointer_param_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S: type = class_type @S [concrete]
 // CHECK:STDOUT:   %ptr: type = ptr_type %S [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.type: type = fn_type @foo [concrete]
@@ -976,9 +976,9 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_pointer_param_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %S: type = class_type @S [concrete]
 // CHECK:STDOUT:   %ptr: type = ptr_type %S [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.type: type = fn_type @foo [concrete]

+ 10 - 10
toolchain/check/testdata/interop/cpp/function/import/union.carbon

@@ -454,8 +454,8 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_no_data_members_value_param_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %U: type = class_type @U [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %ptr.86f: type = ptr_type %U [concrete]
@@ -492,8 +492,8 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_single_data_member_value_param_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %U: type = class_type @U [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %ptr.86f: type = ptr_type %U [concrete]
@@ -530,8 +530,8 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_multiple_data_members_value_param_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %U: type = class_type @U [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %ptr.86f: type = ptr_type %U [concrete]
@@ -568,9 +568,9 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_in_namespace_value_param_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %U: type = class_type @U [concrete]
 // CHECK:STDOUT:   %pattern_type.eb9: type = pattern_type %U [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %ptr.87e: type = ptr_type %U [concrete]
@@ -647,8 +647,8 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_in_relative_namespace_value_param_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %U: type = class_type @U [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %ptr.8c1: type = ptr_type %U [concrete]
@@ -694,8 +694,8 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_in_outer_definition.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %O: type = class_type @O [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %U: type = class_type @U [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
@@ -769,8 +769,8 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_and_static_method_call_before.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %U: type = class_type @U [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %U.bar.cpp_overload_set.type: type = cpp_overload_set_type @U.bar.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %U.bar.cpp_overload_set.value: %U.bar.cpp_overload_set.type = cpp_overload_set_value @U.bar.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %U.bar.type: type = fn_type @U.bar [concrete]
@@ -817,8 +817,8 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_and_static_method_call_after.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %U: type = class_type @U [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %ptr.86f: type = ptr_type %U [concrete]
@@ -865,9 +865,9 @@ fn F() {
 // CHECK:STDOUT: --- import_decl_pointer_param_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %U: type = class_type @U [concrete]
 // CHECK:STDOUT:   %ptr: type = ptr_type %U [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.type: type = fn_type @foo [concrete]
@@ -901,9 +901,9 @@ fn F() {
 // CHECK:STDOUT: --- import_definition_pointer_param_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %U: type = class_type @U [concrete]
 // CHECK:STDOUT:   %ptr: type = ptr_type %U [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.type: type = fn_type @foo [concrete]

+ 2 - 2
toolchain/check/testdata/interop/cpp/function/import/void_pointer.carbon

@@ -115,8 +115,8 @@ fn F() {
 // CHECK:STDOUT: --- non_nullable_param.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Cpp.void: type = class_type @VoidBase [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %ptr: type = ptr_type %Cpp.void [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
@@ -195,8 +195,8 @@ fn F() {
 // CHECK:STDOUT: --- nullable_param.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Cpp.void: type = class_type @VoidBase [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %ptr.874: type = ptr_type %Cpp.void [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete]
 // CHECK:STDOUT:   %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]

+ 3 - 3
toolchain/check/testdata/interop/cpp/impls/as.carbon

@@ -132,8 +132,8 @@ fn ConversionExplicit(s: Cpp.ConditionallyExplicitFalse) {
 // CHECK:STDOUT: --- conversions.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Source: type = class_type @Source [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Dest: type = class_type @Dest [concrete]
 // CHECK:STDOUT:   %Source.cpp_operator.type: type = fn_type @Source.cpp_operator [concrete]
 // CHECK:STDOUT:   %Source.cpp_operator: %Source.cpp_operator.type = struct_value () [concrete]
@@ -317,8 +317,8 @@ fn ConversionExplicit(s: Cpp.ConditionallyExplicitFalse) {
 // CHECK:STDOUT: --- conditionally_explicit.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Source: type = class_type @Source [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %ConditionallyExplicit.c52b91.1: type = class_type @ConditionallyExplicit.1 [concrete]
 // CHECK:STDOUT:   %pattern_type.285f84.1: type = pattern_type %ConditionallyExplicit.c52b91.1 [concrete]
 // CHECK:STDOUT:   %ptr.1fc: type = ptr_type %Source [concrete]
@@ -526,8 +526,8 @@ fn ConversionExplicit(s: Cpp.ConditionallyExplicitFalse) {
 // CHECK:STDOUT: --- fail_conditionally_explicit_implicit.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Source: type = class_type @Source [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %ConditionallyExplicit.c52b91.1: type = class_type @ConditionallyExplicit.1 [concrete]
 // CHECK:STDOUT:   %pattern_type.285f84.1: type = pattern_type %ConditionallyExplicit.c52b91.1 [concrete]
 // CHECK:STDOUT:   %ConditionallyExplicit.c52b91.2: type = class_type @ConditionallyExplicit.2 [concrete]

+ 1 - 1
toolchain/check/testdata/interop/cpp/impls/copy.carbon

@@ -195,8 +195,8 @@ fn EqualWitnesses(p: Wrap(Cpp.Copyable)*) -> Wrap(Cpp.Copyable)* {
 // CHECK:STDOUT: --- copy_copyable.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Copyable: type = class_type @Copyable [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Copy.type: type = facet_type <@Copy> [concrete]
 // CHECK:STDOUT:   %Copyable.Copyable.type: type = fn_type @Copyable.Copyable [concrete]
 // CHECK:STDOUT:   %Copyable.Copyable: %Copyable.Copyable.type = struct_value () [concrete]

+ 2 - 2
toolchain/check/testdata/interop/cpp/impls/destroy.carbon

@@ -349,9 +349,9 @@ fn EqualWitnesses(p: Wrap(Cpp.PublicDestructor)*) -> Wrap(Cpp.PublicDestructor)*
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Derived: type = class_type @Derived [concrete]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %ProtectedDestructor: type = class_type @ProtectedDestructor [concrete]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %struct_type.base.e31: type = struct_type {.base: %ProtectedDestructor} [concrete]
 // CHECK:STDOUT:   %pattern_type.9f6: type = pattern_type %Derived [concrete]
 // CHECK:STDOUT:   %empty_struct.a40: %empty_struct_type = struct_value () [concrete]
@@ -402,9 +402,9 @@ fn EqualWitnesses(p: Wrap(Cpp.PublicDestructor)*) -> Wrap(Cpp.PublicDestructor)*
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Derived: type = class_type @Derived [concrete]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %PrivateDestructor: type = class_type @PrivateDestructor [concrete]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %struct_type.base.616: type = struct_type {.base: %PrivateDestructor} [concrete]
 // CHECK:STDOUT:   %pattern_type.9f6: type = pattern_type %Derived [concrete]
 // CHECK:STDOUT:   %empty_struct.a40: %empty_struct_type = struct_value () [concrete]

+ 2 - 2
toolchain/check/testdata/interop/cpp/impls/implicit_as.carbon

@@ -414,8 +414,8 @@ fn InitFromStruct() {
 // CHECK:STDOUT: --- implicit_conversions.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Source: type = class_type @Source [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Dest: type = class_type @Dest [concrete]
 // CHECK:STDOUT:   %pattern_type.69a: type = pattern_type %Dest [concrete]
 // CHECK:STDOUT:   %Source.cpp_operator.type: type = fn_type @Source.cpp_operator [concrete]
@@ -613,8 +613,8 @@ fn InitFromStruct() {
 // CHECK:STDOUT: --- fail_access.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Source: type = class_type @Source [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %InaccessibleConstructor: type = class_type @InaccessibleConstructor [concrete]
 // CHECK:STDOUT:   %pattern_type.b73: type = pattern_type %InaccessibleConstructor [concrete]
 // CHECK:STDOUT:   %ptr.1fc: type = ptr_type %Source [concrete]

+ 1 - 1
toolchain/check/testdata/interop/cpp/operators/arithmetic_operators.carbon

@@ -308,10 +308,10 @@ fn TestUnaryOperators(a: Cpp.Int16, b: Cpp.Int32) {
 // CHECK:STDOUT: --- arithmetic_operators.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Destroy.type: type = facet_type <@Destroy> [concrete]
 // CHECK:STDOUT:   %Result: %Destroy.type = symbolic_binding Result, 0 [symbolic]
 // CHECK:STDOUT:   %U.0bd: %Destroy.type = symbolic_binding U, 1 [symbolic]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Other: type = symbolic_binding Other, 0 [symbolic]
 // CHECK:STDOUT:   %AddWith.type.6d9: type = facet_type <@AddWith.1, @AddWith.1(%Other)> [symbolic]
 // CHECK:STDOUT:   %Self.b7c: %AddWith.type.6d9 = symbolic_binding Self, 1 [symbolic]

+ 1 - 1
toolchain/check/testdata/interop/cpp/template/alias_template.carbon

@@ -34,8 +34,8 @@ var a2: Cpp.Second(Cpp.B, Cpp.A) = Cpp.A.A();
 // CHECK:STDOUT: --- use_alias_template.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %First.type: type = cpp_type_template_type First [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %First.template: %First.type = struct_value () [concrete]
 // CHECK:STDOUT:   %A: type = class_type @A [concrete]
 // CHECK:STDOUT:   %B: type = class_type @B [concrete]

+ 1 - 1
toolchain/check/testdata/interop/cpp/template/class_template.carbon

@@ -33,9 +33,9 @@ var a: Cpp.A = Cpp.X(Cpp.A, Cpp.B).f({} as Cpp.B);
 // CHECK:STDOUT: --- use_class_template.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %A: type = class_type @A [concrete]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %pattern_type.9de: type = pattern_type %A [concrete]
 // CHECK:STDOUT:   %X.type: type = cpp_type_template_type X [concrete]
 // CHECK:STDOUT:   %X.template: %X.type = struct_value () [concrete]

+ 1 - 1
toolchain/check/testdata/interop/cpp/template/non_type_param.carbon

@@ -209,8 +209,8 @@ fn G() -> i32 {
 // CHECK:STDOUT: --- dependent.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %DependentNonType.type: type = cpp_type_template_type DependentNonType [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %DependentNonType.template: %DependentNonType.type = struct_value () [concrete]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [concrete]
 // CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [concrete]

+ 1 - 1
toolchain/check/testdata/interop/cpp/type_alias/import.carbon

@@ -163,8 +163,8 @@ fn H(var c: Cpp.C, var d: Cpp.D) {
 // CHECK:STDOUT: --- use_class_typedef.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %ptr.d9e: type = ptr_type %C [concrete]
 // CHECK:STDOUT:   %pattern_type.a31: type = pattern_type %ptr.d9e [concrete]
 // CHECK:STDOUT:   %Copy.type: type = facet_type <@Copy> [concrete]

+ 6 - 2
toolchain/check/testdata/let/form.carbon

@@ -13,11 +13,15 @@
 // --- fail_todo_form_binding.carbon
 library "[[@TEST_NAME]]";
 
-// CHECK:STDERR: fail_todo_form_binding.carbon:[[@LINE+7]]:9: error: cannot implicitly convert expression of type `()` to `Core.Form` [ConversionFailure]
+// CHECK:STDERR: fail_todo_form_binding.carbon:[[@LINE+11]]:9: error: cannot implicitly convert expression of type `()` to `Core.Form` [ConversionFailure]
 // CHECK:STDERR: let x:? () = ();
 // CHECK:STDERR:         ^~
-// CHECK:STDERR: fail_todo_form_binding.carbon:[[@LINE+4]]:9: note: type `()` does not implement interface `Core.ImplicitAs(Core.Form)` [MissingImplInMemberAccessInContext]
+// CHECK:STDERR: fail_todo_form_binding.carbon:[[@LINE+8]]:9: note: type `()` does not implement interface `Core.ImplicitAs(Core.Form)` [MissingImplInMemberAccessInContext]
 // CHECK:STDERR: let x:? () = ();
 // CHECK:STDERR:         ^~
 // CHECK:STDERR:
+// CHECK:STDERR: fail_todo_form_binding.carbon:[[@LINE+4]]:5: error: semantics TODO: `support local form bindings` [SemanticsTodo]
+// CHECK:STDERR: let x:? () = ();
+// CHECK:STDERR:     ^~~~~~
+// CHECK:STDERR:
 let x:? () = ();

+ 2 - 2
toolchain/check/testdata/named_constraint/incomplete.carbon

@@ -113,9 +113,9 @@ constraint W {
   // CHECK:STDERR: fail_incomplete_self.carbon:[[@LINE-5]]:1: note: constraint is currently being defined [NamedConstraintIncompleteWithinDefinition]
   // CHECK:STDERR: constraint W {
   // CHECK:STDERR: ^~~~~~~~~~~~~~
-  // CHECK:STDERR: fail_incomplete_self.carbon:[[@LINE-15]]:41: note: return type declared here [IncompleteReturnTypeHere]
+  // CHECK:STDERR: fail_incomplete_self.carbon:[[@LINE-15]]:38: note: return type declared here [IncompleteReturnTypeHere]
   // CHECK:STDERR: eval fn ReturnFacet[T:! type](U:! T) -> T;
-  // CHECK:STDERR:                                         ^
+  // CHECK:STDERR:                                      ^~~~
   // CHECK:STDERR:
   // CHECK:STDERR: fail_incomplete_self.carbon:[[@LINE+7]]:31: error: use of undefined generic function [MissingGenericFunctionDefinition]
   // CHECK:STDERR:   require impls X where .XZ = ReturnFacet(Self);

+ 1 - 1
toolchain/check/testdata/named_constraint/require.carbon

@@ -1164,10 +1164,10 @@ fn G(T:! Z) {
 // CHECK:STDOUT:   %Self.550: %Z.type = symbolic_binding Self, 0 [symbolic]
 // CHECK:STDOUT:   %Self.as_type: type = facet_access_type %Self.550 [symbolic]
 // CHECK:STDOUT:   %.Self: %Y.type = symbolic_binding .Self [symbolic_self]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self [symbolic_self]
 // CHECK:STDOUT:   %Y.lookup_impl_witness: <witness> = lookup_impl_witness %.Self, @Y [symbolic_self]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %Y.lookup_impl_witness, element0 [symbolic_self]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
 // CHECK:STDOUT:   %Y_where.type: type = facet_type <@Y where %impl.elem0 = %empty_tuple.type> [concrete]
 // CHECK:STDOUT: }

+ 4 - 4
toolchain/check/testdata/namespace/imported_indirect.carbon

@@ -65,9 +65,9 @@ import library "b";
 // CHECK:STDERR: class A.C;
 // CHECK:STDERR: ^~~~~~~~~~
 // CHECK:STDERR: fail_named_indirectly_same_package.carbon:[[@LINE-10]]:1: in import [InImport]
-// CHECK:STDERR: b.carbon:7:11: note: return type declared here [IncompleteReturnTypeHere]
+// CHECK:STDERR: b.carbon:7:8: note: return type declared here [IncompleteReturnTypeHere]
 // CHECK:STDERR: fn F() -> A.C;
-// CHECK:STDERR:           ^~~
+// CHECK:STDERR:        ^~~~~~
 // CHECK:STDERR:
 fn G() { F(); }
 
@@ -86,9 +86,9 @@ import Same library "b";
 // CHECK:STDERR: class A.C;
 // CHECK:STDERR: ^~~~~~~~~~
 // CHECK:STDERR: fail_named_indirectly_different_package.carbon:[[@LINE-10]]:1: in import [InImport]
-// CHECK:STDERR: b.carbon:7:11: note: return type declared here [IncompleteReturnTypeHere]
+// CHECK:STDERR: b.carbon:7:8: note: return type declared here [IncompleteReturnTypeHere]
 // CHECK:STDERR: fn F() -> A.C;
-// CHECK:STDERR:           ^~~
+// CHECK:STDERR:        ^~~~~~
 // CHECK:STDERR:
 fn G() { Same.F(); }
 

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

@@ -33,10 +33,10 @@ fn TestOp() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Dec.type: type = facet_type <@Dec> [concrete]
 // CHECK:STDOUT:   %Dec.impl_witness: <witness> = impl_witness @C.as.Dec.impl.%Dec.impl_witness_table [concrete]
 // CHECK:STDOUT:   %C.as.Dec.impl.Op.type: type = fn_type @C.as.Dec.impl.Op [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C.as.Dec.impl.Op: %C.as.Dec.impl.Op.type = struct_value () [concrete]
 // CHECK:STDOUT:   %Dec.facet: %Dec.type = facet_value %C, (%Dec.impl_witness) [concrete]
 // CHECK:STDOUT:   %Dec.WithSelf.Op.type.874: type = fn_type @Dec.WithSelf.Op, @Dec.WithSelf(%Dec.facet) [concrete]

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

@@ -51,11 +51,11 @@ fn TestAddAssignNonRef(a: C, b: C) {
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Inc.type: type = facet_type <@Inc> [concrete]
 // CHECK:STDOUT:   %Inc.impl_witness: <witness> = impl_witness @C.as.Inc.impl.%Inc.impl_witness_table [concrete]
 // CHECK:STDOUT:   %pattern_type.476: type = pattern_type %C [concrete]
 // CHECK:STDOUT:   %C.as.Inc.impl.Op.type: type = fn_type @C.as.Inc.impl.Op [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C.as.Inc.impl.Op: %C.as.Inc.impl.Op.type = struct_value () [concrete]
 // CHECK:STDOUT:   %Inc.facet: %Inc.type = facet_value %C, (%Inc.impl_witness) [concrete]
 // CHECK:STDOUT:   %Inc.WithSelf.Op.type.700: type = fn_type @Inc.WithSelf.Op, @Inc.WithSelf(%Inc.facet) [concrete]

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

@@ -33,10 +33,10 @@ fn TestOp() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %Inc.type: type = facet_type <@Inc> [concrete]
 // CHECK:STDOUT:   %Inc.impl_witness: <witness> = impl_witness @C.as.Inc.impl.%Inc.impl_witness_table [concrete]
 // CHECK:STDOUT:   %C.as.Inc.impl.Op.type: type = fn_type @C.as.Inc.impl.Op [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C.as.Inc.impl.Op: %C.as.Inc.impl.Op.type = struct_value () [concrete]
 // CHECK:STDOUT:   %Inc.facet: %Inc.type = facet_value %C, (%Inc.impl_witness) [concrete]
 // CHECK:STDOUT:   %Inc.WithSelf.Op.type.700: type = fn_type @Inc.WithSelf.Op, @Inc.WithSelf(%Inc.facet) [concrete]

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

@@ -313,8 +313,8 @@ fn F() {
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %IndexWith.type.504: type = generic_interface_type @IndexWith [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %IndexWith.generic: %IndexWith.type.504 = struct_value () [concrete]
 // CHECK:STDOUT:   %ElementType: type = symbolic_binding ElementType, 1 [symbolic]
 // CHECK:STDOUT:   %SubscriptType: type = symbolic_binding SubscriptType, 0 [symbolic]

+ 8 - 8
toolchain/check/testdata/packages/cross_package_export.carbon

@@ -383,8 +383,8 @@ alias C = Other.C;
 // CHECK:STDOUT: --- use_export_import.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %struct_type.x: type = struct_type {.x: %empty_tuple.type} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %struct_type.x [concrete]
 // CHECK:STDOUT:   %pattern_type: type = pattern_type %C [concrete]
@@ -449,8 +449,8 @@ alias C = Other.C;
 // CHECK:STDOUT: --- use_export_import_with_copy.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %struct_type.x: type = struct_type {.x: %empty_tuple.type} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %struct_type.x [concrete]
 // CHECK:STDOUT:   %pattern_type: type = pattern_type %C [concrete]
@@ -516,8 +516,8 @@ alias C = Other.C;
 // CHECK:STDOUT: --- use_export_import_indirect.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %struct_type.x: type = struct_type {.x: %empty_tuple.type} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %struct_type.x [concrete]
 // CHECK:STDOUT:   %pattern_type: type = pattern_type %C [concrete]
@@ -583,8 +583,8 @@ alias C = Other.C;
 // CHECK:STDOUT: --- use_export_name.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %struct_type.x: type = struct_type {.x: %empty_tuple.type} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %struct_type.x [concrete]
 // CHECK:STDOUT:   %pattern_type: type = pattern_type %C [concrete]
@@ -648,8 +648,8 @@ alias C = Other.C;
 // CHECK:STDOUT: --- use_export_name_with_copy.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %struct_type.x: type = struct_type {.x: %empty_tuple.type} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %struct_type.x [concrete]
 // CHECK:STDOUT:   %pattern_type: type = pattern_type %C [concrete]
@@ -714,8 +714,8 @@ alias C = Other.C;
 // CHECK:STDOUT: --- use_export_name_indirect.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %struct_type.x: type = struct_type {.x: %empty_tuple.type} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %struct_type.x [concrete]
 // CHECK:STDOUT:   %pattern_type: type = pattern_type %C [concrete]
@@ -779,8 +779,8 @@ alias C = Other.C;
 // CHECK:STDOUT: --- use_export_all.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %struct_type.x: type = struct_type {.x: %empty_tuple.type} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %struct_type.x [concrete]
 // CHECK:STDOUT:   %pattern_type: type = pattern_type %C [concrete]
@@ -913,8 +913,8 @@ alias C = Other.C;
 // CHECK:STDOUT: --- fail_conflict_on_export_name.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %struct_type.x: type = struct_type {.x: %empty_tuple.type} [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %struct_type.x [concrete]
 // CHECK:STDOUT: }

+ 2 - 2
toolchain/check/testdata/where_expr/equal_rewrite.carbon

@@ -282,12 +282,12 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:   %assoc0: %A.assoc_type = assoc_entity element0, @A.WithSelf.%B [concrete]
 // CHECK:STDOUT:   %assoc1: %A.assoc_type = assoc_entity element1, @A.WithSelf.%C [concrete]
 // CHECK:STDOUT:   %.Self.091: %A.type = symbolic_binding .Self [symbolic_self]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self.091 [symbolic_self]
 // CHECK:STDOUT:   %A.lookup_impl_witness: <witness> = lookup_impl_witness %.Self.091, @A [symbolic_self]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %A.lookup_impl_witness, element0 [symbolic_self]
 // CHECK:STDOUT:   %A_where.type.f51: type = facet_type <@A where %impl.elem0 = bool> [concrete]
 // CHECK:STDOUT:   %impl.elem1: type = impl_witness_access %A.lookup_impl_witness, element1 [symbolic_self]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
 // CHECK:STDOUT:   %A_where.type.321: type = facet_type <@A where %impl.elem0 = bool and %impl.elem1 = %empty_tuple.type> [concrete]
 // CHECK:STDOUT:   %pattern_type.725: type = pattern_type %A_where.type.321 [concrete]
@@ -474,10 +474,10 @@ let K: (E where .F = .Self.G) = bool;
 // CHECK:STDOUT:   %assoc0: %J.assoc_type = assoc_entity element0, @J.WithSelf.%K [concrete]
 // CHECK:STDOUT:   %assoc1: %J.assoc_type = assoc_entity element1, @J.WithSelf.%L [concrete]
 // CHECK:STDOUT:   %.Self.2fa: %J.type = symbolic_binding .Self [symbolic_self]
-// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %.Self.as_type: type = facet_access_type %.Self.2fa [symbolic_self]
 // CHECK:STDOUT:   %J.lookup_impl_witness: <witness> = lookup_impl_witness %.Self.2fa, @J [symbolic_self]
 // CHECK:STDOUT:   %impl.elem0: type = impl_witness_access %J.lookup_impl_witness, element0 [symbolic_self]
+// CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
 // CHECK:STDOUT:   %impl.elem1: type = impl_witness_access %J.lookup_impl_witness, element1 [symbolic_self]
 // CHECK:STDOUT:   %J_where.type: type = facet_type <@J where %impl.elem0 = %empty_tuple.type and %impl.elem1 = bool> [concrete]

+ 2 - 3
toolchain/check/thunk.cpp

@@ -63,7 +63,6 @@ static auto CloneBindingPattern(Context& context, SemIR::InstId pattern_id,
   auto entity_name = context.entity_names().Get(pattern.entity_name_id);
   CARBON_CHECK((pattern.kind == SemIR::SymbolicBindingPattern::Kind) ==
                entity_name.bind_index().has_value());
-  CARBON_CHECK(pattern.kind != SemIR::FormBindingPattern::Kind);
   // Get the transformed type of the binding.
   if (new_pattern_type_id == SemIR::ErrorInst::TypeId) {
     return SemIR::ErrorInst::InstId;
@@ -80,8 +79,8 @@ static auto CloneBindingPattern(Context& context, SemIR::InstId pattern_id,
   if (pattern.kind == SemIR::WrapperBindingPattern::Kind) {
     auto subpattern = context.insts().GetAs<SemIR::AnyLeafParamPattern>(
         pattern.subpattern_id);
-    if (subpattern.kind == SemIR::FormParamPattern::Kind) {
-      context.TODO(pattern_id, "Support for cloning form bindings");
+    if (subpattern.kind == SemIR::FormParamPatternAction::Kind) {
+      context.TODO(pattern_id, "Support for cloning generic form bindings");
       return SemIR::ErrorInst::InstId;
     }
     pattern.subpattern_id = RebuildPatternInst<SemIR::AnyLeafParamPattern>(

+ 5 - 0
toolchain/driver/testdata/stdin.carbon

@@ -62,6 +62,11 @@
 // CHECK:STDOUT:       object_layout:
 // CHECK:STDOUT:         size:            0
 // CHECK:STDOUT:         alignment:       1
+// CHECK:STDOUT:     'type(inst(InstType))':
+// CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(InstType))}
+// CHECK:STDOUT:       object_layout:
+// CHECK:STDOUT:         size:            0
+// CHECK:STDOUT:         alignment:       1
 // CHECK:STDOUT:     'type(inst(NamespaceType))':
 // CHECK:STDOUT:       value_repr:      {kind: copy, type: type(inst(NamespaceType))}
 // CHECK:STDOUT:       object_layout:

+ 0 - 5
toolchain/lower/handle.cpp

@@ -119,11 +119,6 @@ auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
   context.SetLocal(inst_id, context.GetValue(inst.value_id));
 }
 
-auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
-                SemIR::FormBinding inst) -> void {
-  context.SetLocal(inst_id, context.GetValue(inst.value_id));
-}
-
 auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
                 SemIR::BlockArg inst) -> void {
   context.SetLocal(

+ 2 - 21
toolchain/lower/type.cpp

@@ -410,7 +410,8 @@ auto FunctionTypeInfoBuilder::TryHandleParameter(
       sem_ir.inst_blocks().Get(sem_ir.functions()
                                    .Get(func_ctx.function_id)
                                    .call_param_patterns_id)[index.index];
-  auto param_pattern = sem_ir.insts().Get(param_pattern_id);
+  auto param_pattern = sem_ir.insts().Get(
+      sem_ir.constant_values().GetConstantInstId(param_pattern_id));
   auto param_type_id = ExtractScrutineeType(
       sem_ir, SemIR::GetTypeOfInstInSpecific(sem_ir, func_ctx.specific_id,
                                              param_pattern_id));
@@ -431,26 +432,6 @@ auto FunctionTypeInfoBuilder::TryHandleParameter(
 
   auto param_kind = param_pattern.kind();
 
-  // Treat a form parameter pattern like the kind of param pattern that
-  // corresponds to its form.
-  if (auto form_param_pattern =
-          param_pattern.TryAs<SemIR::FormParamPattern>()) {
-    auto form_kind = sem_ir.insts().Get(form_param_pattern->form_id).kind();
-    switch (form_kind) {
-      case SemIR::InitForm::Kind:
-        param_kind = SemIR::VarParamPattern::Kind;
-        break;
-      case SemIR::RefForm::Kind:
-        param_kind = SemIR::RefParamPattern::Kind;
-        break;
-      case SemIR::ValueForm::Kind:
-        param_kind = SemIR::ValueParamPattern::Kind;
-        break;
-      default:
-        CARBON_FATAL("Unexpected kind {0} for form inst", form_kind);
-    }
-  }
-
   switch (param_kind) {
     case SemIR::RefParamPattern::Kind:
     case SemIR::VarParamPattern::Kind: {

+ 0 - 15
toolchain/sem_ir/expr_info.cpp

@@ -93,21 +93,6 @@ static auto GetExprCategoryImpl(const File* ir, InstId inst_id)
             return ExprCategory::ReprInitializing;
           }
         }
-      } else if constexpr (std::same_as<TypedInstT, FormBinding>) {
-        auto form_id = ir->entity_names().Get(inst.entity_name_id).form_id;
-        auto form_inst = ir->insts().Get(form_id);
-        CARBON_KIND_SWITCH(form_inst) {
-          case InitForm::Kind:
-            // A `var` binding pattern produces a `ref` binding.
-          case RefForm::Kind:
-            return ExprCategory::DurableRef;
-          case ValueForm::Kind:
-            return ExprCategory::Value;
-          case ErrorInst::Kind:
-            return ExprCategory::Error;
-          default:
-            CARBON_FATAL("Unexpected kind for form inst {0}", form_inst);
-        }
       } else {
         static_assert(
             TypedInstT::Kind.expr_category().TryAsComputedCategory() !=

+ 6 - 1
toolchain/sem_ir/file.cpp

@@ -71,7 +71,8 @@ File::File(const Parse::Tree* parse_tree, CheckIRId check_ir_id,
       clang_source_locs_(check_ir_id) {
   // `type`, `form`, and the error type are both complete & concrete types.
   // TODO: This duplicates the code in `check/type_completion.cpp`. Consider
-  // requiring these types to be complete from Check initialization instead.
+  // requiring these types to be complete from Check initialization instead,
+  // and consider doing this automatically for all singleton types.
   types_.SetComplete(
       TypeType::TypeId,
       {.value_repr = {.kind = ValueRepr::Copy, .type_id = TypeType::TypeId},
@@ -84,6 +85,10 @@ File::File(const Parse::Tree* parse_tree, CheckIRId check_ir_id,
       ErrorInst::TypeId,
       {.value_repr = {.kind = ValueRepr::Copy, .type_id = ErrorInst::TypeId},
        .object_layout = SemIR::ObjectLayout::Empty()});
+  types_.SetComplete(
+      InstType::TypeId,
+      {.value_repr = {.kind = ValueRepr::Copy, .type_id = InstType::TypeId},
+       .object_layout = SemIR::ObjectLayout::Empty()});
 
   insts_.Reserve(SingletonInstKinds.size());
   for (auto kind : SingletonInstKinds) {

+ 9 - 0
toolchain/sem_ir/formatter.cpp

@@ -773,6 +773,15 @@ auto Formatter::FormatFunctionSignature(InstBlockId params_id,
         FormatInstAsType(return_form_id);
         break;
       }
+      case CARBON_KIND(SpliceInst splice): {
+        out() << "out ";
+        FormatName(params[i]);
+        out() << ":? ";
+        // A form isn't a type, but it's close enough for formatting purposes.
+        FormatInstAsType(splice.inst_id);
+        ++i;
+        break;
+      }
       default:
         CARBON_FATAL("Unexpected inst kind: {0}", return_form);
     }

+ 25 - 3
toolchain/sem_ir/inst_categories.h

@@ -109,7 +109,6 @@ struct AnyAggregateValue {
 
 // clang-format off
 #define AnyBindingPattern_CARBON_INST_CATEGORY(X, Sep) \
-  X(::Carbon::SemIR::FormBindingPattern) Sep()         \
   X(::Carbon::SemIR::RefBindingPattern) Sep()          \
   X(::Carbon::SemIR::SymbolicBindingPattern) Sep()     \
   X(::Carbon::SemIR::ValueBindingPattern) Sep()        \
@@ -142,7 +141,6 @@ struct AnyBindingPattern {
 // clang-format off
 #define AnyBinding_CARBON_INST_CATEGORY(X, Sep) \
   X(::Carbon::SemIR::AliasBinding) Sep()        \
-  X(::Carbon::SemIR::FormBinding) Sep()         \
   X(::Carbon::SemIR::RefBinding) Sep()          \
   X(::Carbon::SemIR::SymbolicBinding) Sep()     \
   X(::Carbon::SemIR::ValueBinding)
@@ -206,6 +204,31 @@ struct AnyBranch {
   AnyRawId arg1;
 };
 
+// clang-format off
+#define AnyFormParamAction_CARBON_INST_CATEGORY(X, Sep) \
+  X(::Carbon::SemIR::FormParamPatternAction) Sep() \
+  X(::Carbon::SemIR::OutFormParamPatternAction)
+// clang-format on
+
+#define AnyFormParamAction_CARBON_KIND_ANY_EXPAND \
+  CARBON_INST_CATEGORY_ANY_EXPAND(AnyFormParamAction)
+
+// Common representation for various form-parameterized actions.
+struct AnyFormParamAction {
+  using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyFormParamAction);
+
+  InstKind kind;
+
+  // Always InstType.
+  TypeId type_id;
+
+  // The form of the parameter. Note that this is not the form of the pattern;
+  // in particular, its type component is not a pattern type.
+  MetaInstId form_id;
+
+  AnyRawId arg1;
+};
+
 // clang-format off
 #define AnyFoundationDecl_CARBON_INST_CATEGORY(X, Sep) \
   X(::Carbon::SemIR::AdaptDecl) Sep()                  \
@@ -274,7 +297,6 @@ struct AnyParam {
 
 // clang-format off
 #define AnyLeafParamPattern_CARBON_INST_CATEGORY(X, Sep) \
-  X(::Carbon::SemIR::FormParamPattern) Sep()             \
   X(::Carbon::SemIR::OutParamPattern) Sep()              \
   X(::Carbon::SemIR::RefParamPattern) Sep()              \
   X(::Carbon::SemIR::ValueParamPattern)

+ 4 - 3
toolchain/sem_ir/inst_kind.def

@@ -43,6 +43,7 @@ CARBON_SEM_IR_INST_KIND(Branch)
 CARBON_SEM_IR_INST_KIND(BranchIf)
 CARBON_SEM_IR_INST_KIND(BranchWithArg)
 CARBON_SEM_IR_INST_KIND(Call)
+CARBON_SEM_IR_INST_KIND(CalleePatternMatchAction)
 CARBON_SEM_IR_INST_KIND(CharLiteralType)
 CARBON_SEM_IR_INST_KIND(CharLiteralValue)
 CARBON_SEM_IR_INST_KIND(ClassDecl)
@@ -51,6 +52,7 @@ CARBON_SEM_IR_INST_KIND(ClassInit)
 CARBON_SEM_IR_INST_KIND(ClassType)
 CARBON_SEM_IR_INST_KIND(CompleteTypeWitness)
 CARBON_SEM_IR_INST_KIND(ConstType)
+CARBON_SEM_IR_INST_KIND(RefineFormAction)
 CARBON_SEM_IR_INST_KIND(ConvertToValueAction)
 CARBON_SEM_IR_INST_KIND(Converted)
 CARBON_SEM_IR_INST_KIND(CppOverloadSetType)
@@ -70,9 +72,7 @@ CARBON_SEM_IR_INST_KIND(FloatLiteralType)
 CARBON_SEM_IR_INST_KIND(FloatLiteralValue)
 CARBON_SEM_IR_INST_KIND(FloatType)
 CARBON_SEM_IR_INST_KIND(FloatValue)
-CARBON_SEM_IR_INST_KIND(FormBinding)
-CARBON_SEM_IR_INST_KIND(FormBindingPattern)
-CARBON_SEM_IR_INST_KIND(FormParamPattern)
+CARBON_SEM_IR_INST_KIND(FormParamPatternAction)
 CARBON_SEM_IR_INST_KIND(FormType)
 CARBON_SEM_IR_INST_KIND(FunctionDecl)
 CARBON_SEM_IR_INST_KIND(FunctionType)
@@ -109,6 +109,7 @@ CARBON_SEM_IR_INST_KIND(NamedConstraintWithSelfDecl)
 CARBON_SEM_IR_INST_KIND(NameRef)
 CARBON_SEM_IR_INST_KIND(Namespace)
 CARBON_SEM_IR_INST_KIND(NamespaceType)
+CARBON_SEM_IR_INST_KIND(OutFormParamPatternAction)
 CARBON_SEM_IR_INST_KIND(OutParam)
 CARBON_SEM_IR_INST_KIND(OutParamPattern)
 CARBON_SEM_IR_INST_KIND(PartialType)

+ 5 - 2
toolchain/sem_ir/inst_kind.h

@@ -196,10 +196,13 @@ enum class InstConstantKind : int8_t {
   // This instruction is a metaprogramming or template instantiation action that
   // generates an instruction. Like `SymbolicOnly`, it may be a symbolic
   // constant inst depending on its operands, but never a concrete constant
-  // inst. The instruction may have a concrete constant value that is a
-  // generated instruction. Constant evaluation support for types with this
+  // inst. The instruction may or may not have a concrete constant value that is
+  // a generated instruction. Constant evaluation support for types with this
   // constant kind is provided automatically, by calling `PerformDelayedAction`.
   InstAction,
+  // Equivalent to InstAction, but this instruction is guaranteed to have a
+  // constant value.
+  ConstantInstAction,
   // This instruction's operands determine whether it has a constant value,
   // whether it is a constant inst, and/or whether it results in a compile-time
   // error, in ways not expressed by the other InstConstantKinds. For example,

+ 1 - 1
toolchain/sem_ir/pattern.cpp

@@ -55,7 +55,7 @@ auto GetFirstBindingNameFromPatternId(const File& sem_ir, InstId pattern_id)
 
     // TODO: Look through struct patterns.
 
-    if (auto form_pattern = inst.TryAs<FormParamPattern>()) {
+    if (auto ref_pattern = inst.TryAs<RefParamPattern>()) {
       // TODO: This introduces a name, but we don't model it as a binding.
       return EntityNameId::None;
     }

+ 88 - 49
toolchain/sem_ir/typed_insts.h

@@ -388,6 +388,19 @@ struct Call {
   InstBlockId args_id;
 };
 
+struct CalleePatternMatchAction {
+  static constexpr auto Kind =
+      InstKind::CalleePatternMatchAction.Define<Parse::NodeId>(
+          {.ir_name = "callee_pattern_match_action",
+           .expr_category = ExprCategory::Value,
+           .constant_kind = InstConstantKind::InstAction,
+           .is_lowered = false});
+
+  TypeId type_id;
+  MetaInstId pattern_id;
+  CallParamIndex parent_index;
+};
+
 // A unicode code point character literal. This type only provides compile-time
 // operations, and is represented as an empty type at runtime.
 //
@@ -758,49 +771,23 @@ struct FloatValue {
   FloatId float_id;
 };
 
-// A form binding, such as the `x` declared by `x:? F`. See `AnyBinding` for
-// member documentation.
-struct FormBinding {
+// An action that creates an input parameter pattern with the form specified by
+// `form_id`. See `AnyFormParamAction` for member documentation.
+struct FormParamPatternAction {
   static constexpr auto Kind =
-      InstKind::FormBinding.Define<Parse::FormBindingPatternId>(
-          {.ir_name = "form_binding",
-           .expr_category = ComputedExprCategory::DependsOnOperands,
-           .constant_kind = InstConstantKind::Never});
-
-  TypeId type_id;
-  EntityNameId entity_name_id;
-  InstId value_id;
-};
-
-// A form binding pattern, such as `x:? F`, that is not a parameter. See
-// `AnyBindingPattern` for member documentation.
-struct FormBindingPattern {
-  static constexpr auto Kind =
-      InstKind::FormBindingPattern.Define<Parse::FormBindingPatternId>(
-          {.ir_name = "form_binding_pattern",
-           .expr_category = ExprCategory::Pattern,
-           .constant_kind = InstConstantKind::AlwaysUnique,
+      InstKind::FormParamPatternAction.Define<Parse::FormBindingPatternId>(
+          {.ir_name = "form_param_pattern_action",
+           .expr_category = ExprCategory::Value,
+           .constant_kind = InstConstantKind::ConstantInstAction,
            .is_lowered = false});
 
   TypeId type_id;
-  // Note that the EntityName's `form_id` represents the scrutinee form, so it
-  // doesn't directly correspond to `type_id` (which is a pattern type).
-  EntityNameId entity_name_id;
-};
-
-// A pattern that represents a form-parameterized parameter, such as `x:? F`.
-// See `AnyParamPattern` for member documentation.
-struct FormParamPattern {
-  // TODO: Replace `Parse::NodeId` with `Parse::FormBindingPattern`.
-  static constexpr auto Kind = InstKind::FormParamPattern.Define<Parse::NodeId>(
-      {.ir_name = "form_param_pattern",
-       .expr_category = ExprCategory::Pattern,
-       .constant_kind = InstConstantKind::AlwaysUnique,
-       .is_lowered = false});
+  MetaInstId form_id;
 
-  TypeId type_id;
+  // A name to associate with this Param in pretty-printed IR. This is not
+  // necessarily unique, and can even be `None`; it has no semantic
+  // significance.
   NameId pretty_name_id;
-  InstId form_id;
 };
 
 // The type `Core.Form`.
@@ -1128,7 +1115,12 @@ struct InPlaceInit {
 };
 
 // Used as the type of template actions that produce instructions.
-using InstType = SingletonTypeInst<InstKind::InstType, "<instruction>">;
+struct InstType
+    : public SingletonTypeInst<InstKind::InstType, "<instruction>"> {
+  // `InstType` is always set complete in file.cpp.
+  static constexpr auto TypeId =
+      TypeId::ForTypeConstant(ConstantId::ForConcreteConstant(TypeInstId));
+};
 
 // A value of type `InstType` that refers to an instruction. This is used to
 // represent an instruction as a value for use as a result of a template action.
@@ -1341,6 +1333,23 @@ struct Namespace {
 // standard type and be removed.
 using NamespaceType = SingletonTypeInst<InstKind::NamespaceType, "<namespace>">;
 
+// An action that creates an output parameter pattern with the form specified by
+// `form_id`. See `AnyFormParamAction` for member documentation.
+struct OutFormParamPatternAction {
+  static constexpr auto Kind =
+      // TODO: Use Parse::AnyReturnDeclId once we support passing node
+      // categories to Define.
+      InstKind::OutFormParamPatternAction
+          .Define<Parse::NodeIdOneOf<Parse::ReturnFormId, Parse::ReturnTypeId>>(
+              {.ir_name = "out_form_param_pattern_action",
+               .expr_category = ExprCategory::Value,
+               .constant_kind = InstConstantKind::ConstantInstAction,
+               .is_lowered = false});
+
+  TypeId type_id;
+  MetaInstId form_id;
+};
+
 // An output `Call` parameter. See AnyParam for member documentation.
 struct OutParam {
   // TODO: Make Parse::NodeId more specific.
@@ -1423,6 +1432,35 @@ struct RefBinding {
   InstId value_id;
 };
 
+// An action that performs form refinement of the form expression `form_id`:
+// for each operand of `form_id` in a position where a form is expected, if the
+// operand is not a concrete constant, it is wrapped in a `RefineFormAction`.
+// A `RefineFormAction` can be performed (i.e. is non-template-dependent) if we
+// can identify the form operands of `form_id`, which is typically possible only
+// if it will not be rewritten by constant evaluation except to substitute
+// values for its operands. As usual when creating Actions, if possible the
+// nested `RefineFormActions` are performed immediately, and not added to the
+// SemIR.
+//
+// This ensures that a form expression is template-dependent if it depends on
+// any non-concrete constants in form positions, even if those constants are not
+// themselves template-dependent. Unlike type refinement, form refinement does
+// not necessarily produce a concrete result, but it moves as far as possible
+// toward a state where non-concrete constants occur only in type positions, and
+// so the structure of the form is concretely known even if its type component
+// remains symbolic.
+struct RefineFormAction {
+  static constexpr auto Kind = InstKind::RefineFormAction.Define<Parse::NodeId>(
+      {.ir_name = "refine_form_action",
+       .constant_kind = InstConstantKind::ConstantInstAction,
+       .is_lowered = false});
+
+  // Always `Core.Form`.
+  TypeId type_id;
+
+  MetaInstId form_id;
+};
+
 // An action that performs type refinement for an instruction, by creating an
 // instruction that converts from a template symbolic type to a concrete type.
 struct RefineTypeAction {
@@ -1810,9 +1848,8 @@ struct SpliceBlock {
 struct SpliceInst {
   static constexpr auto Kind = InstKind::SpliceInst.Define<Parse::NodeId>(
       {.ir_name = "splice_inst",
-       // TODO: The expression category is in general dependent on
-       // instantiation. Use ExprCategory::Dependent to model this.
-       .expr_category = ExprCategory::Value});
+       .expr_category = ExprCategory::Dependent,
+       .constant_kind = InstConstantKind::Indirect});
 
   TypeId type_id;
   // The instruction that computes the instruction to splice. The type of this
@@ -2249,8 +2286,10 @@ struct ValueReturnPattern {
 };
 
 // A `var` pattern that is a `Call` parameter. See `AnyVarPattern` for member
-// documentation. Note that there is no `VarParam` -- a `VarParamPattern`
-// corresponds to a `RefParam`.
+// documentation. This is functionally equivalent to a `VarPattern` with a
+// `RefParamPattern` subpattern; it is represented as a single inst to reduce
+// SemIR bloat. Note that as a consequence, there is no `VarParam` -- a
+// `VarParamPattern` corresponds to a `RefParam`.
 struct VarParamPattern {
   static constexpr auto Kind =
       InstKind::VarParamPattern.Define<Parse::VariablePatternId>(
@@ -2265,12 +2304,12 @@ struct VarParamPattern {
 
 // A `var` pattern that is not a `Call` parameter.
 struct VarPattern {
-  static constexpr auto Kind =
-      InstKind::VarPattern.Define<Parse::VariablePatternId>(
-          {.ir_name = "var_pattern",
-           .expr_category = ExprCategory::Pattern,
-           .constant_kind = InstConstantKind::AlwaysUnique,
-           .is_lowered = false});
+  static constexpr auto Kind = InstKind::VarPattern.Define<Parse::NodeIdOneOf<
+      Parse::VariablePatternId, Parse::FormBindingPatternId>>(
+      {.ir_name = "var_pattern",
+       .expr_category = ExprCategory::Pattern,
+       .constant_kind = InstConstantKind::AlwaysUnique,
+       .is_lowered = false});
 
   // Always a PatternType that represents the same type as the type of
   // `subpattern_id`.

+ 13 - 0
toolchain/testing/testdata/min_prelude/form.carbon

@@ -0,0 +1,13 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// EXTRA-ARGS: --custom-core --exclude-dump-file-prefix=min_prelude/
+// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/parts/form.carbon
+
+// --- min_prelude/form.carbon
+
+// A minimal prelude for testing `Core.Form` usage.
+package Core library "prelude";
+
+export import library "prelude/parts/form";