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

Refactor function return type representation (#6463)

This separates the return type from the return pattern, and replaces the
return pattern with a block of return patterns. This is a step toward
support for `ref` returns (where there's no corresponding return
pattern) and compund-form returns (where there may be multiple return
patterns).
Geoff Romer 4 месяцев назад
Родитель
Сommit
bf45b1cbf5
57 измененных файлов с 900 добавлено и 791 удалено
  1. 1 1
      toolchain/check/call.cpp
  2. 1 0
      toolchain/check/context.cpp
  3. 22 0
      toolchain/check/context.h
  4. 2 2
      toolchain/check/convert.cpp
  5. 48 32
      toolchain/check/cpp/import.cpp
  6. 15 10
      toolchain/check/cpp/thunk.cpp
  7. 2 3
      toolchain/check/function.cpp
  8. 2 1
      toolchain/check/global_init.cpp
  9. 19 13
      toolchain/check/handle_function.cpp
  10. 1 2
      toolchain/check/handle_impl.cpp
  11. 14 10
      toolchain/check/import_ref.cpp
  12. 4 6
      toolchain/check/name_component.cpp
  13. 2 9
      toolchain/check/name_component.h
  14. 2 1
      toolchain/check/node_stack.h
  15. 12 9
      toolchain/check/pattern_match.cpp
  16. 4 4
      toolchain/check/pattern_match.h
  17. 5 11
      toolchain/check/return.cpp
  18. 8 8
      toolchain/check/testdata/alias/preserve_in_type_printing.carbon
  19. 1 1
      toolchain/check/testdata/basics/raw_sem_ir/cpp_interop.carbon
  20. 3 3
      toolchain/check/testdata/basics/raw_sem_ir/multifile.carbon
  21. 3 3
      toolchain/check/testdata/basics/raw_sem_ir/multifile_with_textual_ir.carbon
  22. 532 521
      toolchain/check/testdata/basics/raw_sem_ir/one_file.carbon
  23. 14 12
      toolchain/check/testdata/basics/raw_sem_ir/one_file_with_textual_ir.carbon
  24. 2 2
      toolchain/check/testdata/class/fail_abstract.carbon
  25. 6 6
      toolchain/check/testdata/class/fail_incomplete.carbon
  26. 1 1
      toolchain/check/testdata/class/generic/basic.carbon
  27. 2 2
      toolchain/check/testdata/class/generic/field.carbon
  28. 1 1
      toolchain/check/testdata/class/generic/member_access.carbon
  29. 4 4
      toolchain/check/testdata/class/generic/member_type.carbon
  30. 6 6
      toolchain/check/testdata/deduce/array.carbon
  31. 6 6
      toolchain/check/testdata/deduce/generic_type.carbon
  32. 3 3
      toolchain/check/testdata/deduce/tuple.carbon
  33. 11 11
      toolchain/check/testdata/deduce/type_operator.carbon
  34. 3 3
      toolchain/check/testdata/for/actual.carbon
  35. 4 4
      toolchain/check/testdata/function/builtin/call_from_operator.carbon
  36. 8 8
      toolchain/check/testdata/function/declaration/fail_import_incomplete_return.carbon
  37. 6 6
      toolchain/check/testdata/function/generic/deduce.carbon
  38. 1 1
      toolchain/check/testdata/generic/template_dependence.carbon
  39. 8 0
      toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon
  40. 8 0
      toolchain/check/testdata/impl/impl_thunk.carbon
  41. 2 2
      toolchain/check/testdata/impl/import_builtin_call.carbon
  42. 2 2
      toolchain/check/testdata/impl/lookup/impl_forall.carbon
  43. 3 3
      toolchain/check/testdata/impl/lookup/specialization_with_symbolic_rewrite.carbon
  44. 8 4
      toolchain/check/testdata/impl/use_assoc_entity.carbon
  45. 1 1
      toolchain/check/testdata/interface/fail_todo_define_default_fn_out_of_line.carbon
  46. 5 5
      toolchain/check/testdata/interface/generic_method.carbon
  47. 3 3
      toolchain/check/testdata/interop/cpp/function/class.carbon
  48. 3 3
      toolchain/check/testdata/interop/cpp/function/struct.carbon
  49. 3 3
      toolchain/check/testdata/interop/cpp/function/union.carbon
  50. 4 4
      toolchain/check/testdata/namespace/imported_indirect.carbon
  51. 2 2
      toolchain/check/testdata/return/fail_returned_var_type.carbon
  52. 2 2
      toolchain/check/testdata/return/fail_value_missing.carbon
  53. 21 7
      toolchain/check/thunk.cpp
  54. 16 6
      toolchain/lower/file_context.cpp
  55. 3 3
      toolchain/sem_ir/function.cpp
  56. 25 11
      toolchain/sem_ir/function.h
  57. 0 4
      toolchain/sem_ir/typed_insts.h

+ 1 - 1
toolchain/check/call.cpp

@@ -221,7 +221,7 @@ static auto CheckCalleeFunctionReturnType(Context& context, SemIR::LocId loc_id,
       &context.emitter(), [&](auto& builder) {
         CARBON_DIAGNOSTIC(IncompleteReturnTypeHere, Note,
                           "return type declared here");
-        builder.Note(function.return_slot_pattern_id, IncompleteReturnTypeHere);
+        builder.Note(function.return_type_inst_id, IncompleteReturnTypeHere);
       });
   return CheckFunctionReturnType(context, loc_id, function, callee_specific_id);
 }

+ 1 - 0
toolchain/check/context.cpp

@@ -72,6 +72,7 @@ auto Context::VerifyOnFinish() const -> void {
   vtable_stack_.VerifyOnFinish();
   region_stack_.VerifyOnFinish();
   CARBON_CHECK(impl_lookup_stack_.empty());
+  CARBON_CHECK(return_type_inst_id_ == std::nullopt);
 
 #ifndef NDEBUG
   if (auto verify = sem_ir_->Verify(); !verify.ok()) {

+ 22 - 0
toolchain/check/context.h

@@ -256,6 +256,25 @@ class Context {
     return rewrites_stack_;
   }
 
+  // Pushes inst_id onto the stack of return type declarations for in-progress
+  // function declarations.
+  //
+  // Note: the "stack" currently can only have one element, but that restriction
+  // can be relaxed if it becomes possible to have multiple pending return type
+  // declarations.
+  auto PushReturnTypeInstId(SemIR::TypeInstId inst_id) -> void {
+    CARBON_CHECK(return_type_inst_id_ == std::nullopt,
+                 "TODO: make return_type_inst_id_ a stack if necessary");
+    return_type_inst_id_ = inst_id;
+  }
+
+  // Pops a TypeInstId off the stack of return type declarations for in-progress
+  // function declarations.
+  auto PopReturnTypeInstId() -> SemIR::TypeInstId {
+    CARBON_CHECK(return_type_inst_id_ != std::nullopt);
+    return *std::exchange(return_type_inst_id_, std::nullopt);
+  }
+
   // --------------------------------------------------------------------------
   // Directly expose SemIR::File data accessors for brevity in calls.
   // --------------------------------------------------------------------------
@@ -492,6 +511,9 @@ class Context {
   // value on the RHS. Used during checking of a `where` expression to allow
   // constraints to access values from earlier constraints.
   llvm::SmallVector<Map<SemIR::ConstantId, SemIR::InstId>> rewrites_stack_;
+
+  // Declared return type for the in-progress function declaration, if any.
+  std::optional<SemIR::TypeInstId> return_type_inst_id_;
 };
 
 }  // namespace Carbon::Check

+ 2 - 2
toolchain/check/convert.cpp

@@ -1811,7 +1811,7 @@ auto ConvertCallArgs(Context& context, SemIR::LocId call_loc_id,
     -> SemIR::InstBlockId {
   auto param_patterns =
       context.inst_blocks().GetOrEmpty(callee.param_patterns_id);
-  auto return_slot_pattern_id = callee.return_slot_pattern_id;
+  auto return_patterns_id = callee.return_patterns_id;
 
   // The caller should have ensured this callee has the right arity.
   CARBON_CHECK(arg_refs.size() == param_patterns.size());
@@ -1828,7 +1828,7 @@ auto ConvertCallArgs(Context& context, SemIR::LocId call_loc_id,
   }
 
   return CallerPatternMatch(context, callee_specific_id, callee.self_param_id,
-                            callee.param_patterns_id, return_slot_pattern_id,
+                            callee.param_patterns_id, return_patterns_id,
                             self_id, arg_refs, return_slot_arg_id);
 }
 

+ 48 - 32
toolchain/check/cpp/import.cpp

@@ -1220,6 +1220,9 @@ static auto MapTagType(Context& context, const clang::TagType& type)
   SemIR::TypeInstId record_type_inst_id =
       context.types().GetAsTypeInstId(tag_inst_id);
   return {
+      // TODO: inst_id's location should be the location of the usage, not
+      // the location of the type definition. Possibly we should synthesize a
+      // NameRef inst, to match how this would work in Carbon code.
       .inst_id = record_type_inst_id,
       .type_id = context.types().GetTypeIdForTypeInstId(record_type_inst_id)};
 }
@@ -1559,19 +1562,28 @@ static auto GetReturnTypeExpr(Context& context, SemIR::LocId loc_id,
       .type_id = context.types().GetTypeIdForTypeInstId(record_type_inst_id)};
 }
 
-// Returns the return pattern of the given function declaration. In case of an
-// unsupported return type, it produces a diagnostic and returns
-// `SemIR::ErrorInst::InstId`. Constructors are treated as returning a class
-// instance.
-static auto GetReturnPattern(Context& context, SemIR::LocId loc_id,
-                             clang::FunctionDecl* clang_decl) -> SemIR::InstId {
+// Information about a function's declared return type, corresponding to the
+// fields of SemIR::Function with the same names.
+struct ReturnInfo {
+  SemIR::TypeInstId return_type_inst_id;
+  SemIR::InstBlockId return_patterns_id;
+};
+
+// Returns information about the declared return type of the given function
+// declaration. In case of an unsupported return type, it produces a diagnostic,
+// and the returned return_type_inst_id will be `SemIR::ErrorInst::InstId`.
+// Constructors are treated as returning a class instance.
+static auto GetReturnInfo(Context& context, SemIR::LocId loc_id,
+                          clang::FunctionDecl* clang_decl) -> ReturnInfo {
   auto [type_inst_id, type_id] = GetReturnTypeExpr(context, loc_id, clang_decl);
   if (!type_inst_id.has_value()) {
     // void.
-    return SemIR::InstId::None;
+    return {.return_type_inst_id = type_inst_id,
+            .return_patterns_id = SemIR::InstBlockId::None};
   }
   if (type_inst_id == SemIR::ErrorInst::TypeInstId) {
-    return SemIR::ErrorInst::InstId;
+    return {.return_type_inst_id = type_inst_id,
+            .return_patterns_id = SemIR::InstBlockId::None};
   }
   auto pattern_type_id = GetPatternType(context, type_id);
   clang::SourceLocation return_type_loc =
@@ -1597,33 +1609,34 @@ static auto GetReturnPattern(Context& context, SemIR::LocId loc_id,
           SemIR::OutParamPattern({.type_id = pattern_type_id,
                                   .subpattern_id = return_slot_pattern_id,
                                   .index = SemIR::CallParamIndex::None})));
-  return param_pattern_id;
+  auto return_patterns_id = context.inst_blocks().Add({param_pattern_id});
+  return {.return_type_inst_id = type_inst_id,
+          .return_patterns_id = return_patterns_id};
 }
 
 namespace {
-// Represents the parameter patterns block id, the return slot pattern id and
-// the call parameters block id for a function declaration.
-struct FunctionParamsInsts {
+// Represents the insts and inst blocks associated with the parameters and
+// returns of a function declaration, corresponding to the fields of
+// SemIR::Function with the same names.
+struct FunctionSignatureInsts {
   SemIR::InstBlockId implicit_param_patterns_id;
   SemIR::InstBlockId param_patterns_id;
-  SemIR::InstId return_slot_pattern_id;
+  SemIR::TypeInstId return_type_inst_id;
+  SemIR::InstBlockId return_patterns_id;
   SemIR::InstBlockId call_params_id;
 };
 }  // namespace
 
-// Creates a block containing the parameter pattern instructions for the
-// explicit parameters, a parameter pattern instruction for the return type and
-// a block containing the call parameters of the function. Emits a callee
-// pattern-match for the explicit parameter patterns and the return slot pattern
-// to create the Call parameters instructions block. Currently the implicit
-// parameter patterns are not taken into account. Returns the parameter patterns
-// block id, the return slot pattern id, and the call parameters block id.
-// Produces a diagnostic and returns `std::nullopt` if the function declaration
-// has an unsupported parameter type.
-static auto CreateFunctionParamsInsts(Context& context, SemIR::LocId loc_id,
-                                      clang::FunctionDecl* clang_decl,
-                                      int num_params)
-    -> std::optional<FunctionParamsInsts> {
+// Creates the insts and inst blocks that represent the parameters and returns
+// of the given C++ function's Carbon counterpart, including emitting a callee
+// pattern match to create the `Call` parameters, and returns a
+// FunctionSignatureInsts containing the results. Produces a diagnostic and
+// returns `std::nullopt` if the function declaration has an unsupported
+// parameter type.
+static auto CreateFunctionSignatureInsts(Context& context, SemIR::LocId loc_id,
+                                         clang::FunctionDecl* clang_decl,
+                                         int num_params)
+    -> std::optional<FunctionSignatureInsts> {
   auto implicit_param_patterns_id =
       MakeImplicitParamPatternsBlockId(context, loc_id, *clang_decl);
   if (!implicit_param_patterns_id.has_value()) {
@@ -1634,18 +1647,20 @@ static auto CreateFunctionParamsInsts(Context& context, SemIR::LocId loc_id,
   if (!param_patterns_id.has_value()) {
     return std::nullopt;
   }
-  auto return_slot_pattern_id = GetReturnPattern(context, loc_id, clang_decl);
-  if (SemIR::ErrorInst::InstId == return_slot_pattern_id) {
+  auto [return_type_inst_id, return_patterns_id] =
+      GetReturnInfo(context, loc_id, clang_decl);
+  if (return_type_inst_id == SemIR::ErrorInst::TypeInstId) {
     return std::nullopt;
   }
 
   auto call_params_id =
       CalleePatternMatch(context, implicit_param_patterns_id, param_patterns_id,
-                         return_slot_pattern_id);
+                         return_patterns_id);
 
   return {{.implicit_param_patterns_id = implicit_param_patterns_id,
            .param_patterns_id = param_patterns_id,
-           .return_slot_pattern_id = return_slot_pattern_id,
+           .return_type_inst_id = return_type_inst_id,
+           .return_patterns_id = return_patterns_id,
            .call_params_id = call_params_id}};
 }
 
@@ -1689,7 +1704,7 @@ static auto ImportFunction(Context& context, SemIR::LocId loc_id,
   context.pattern_block_stack().Push();
 
   auto function_params_insts =
-      CreateFunctionParamsInsts(context, loc_id, clang_decl, num_params);
+      CreateFunctionSignatureInsts(context, loc_id, clang_decl, num_params);
 
   auto pattern_block_id = context.pattern_block_stack().Pop();
   auto decl_block_id = context.inst_block_stack().Pop();
@@ -1735,7 +1750,8 @@ static auto ImportFunction(Context& context, SemIR::LocId loc_id,
        .first_owning_decl_id = decl_id,
        .definition_id = SemIR::InstId::None},
       {.call_params_id = function_params_insts->call_params_id,
-       .return_slot_pattern_id = function_params_insts->return_slot_pattern_id,
+       .return_type_inst_id = function_params_insts->return_type_inst_id,
+       .return_patterns_id = function_params_insts->return_patterns_id,
        .virtual_modifier = virtual_modifier,
        .virtual_index = virtual_index,
        .self_param_id = FindSelfPattern(

+ 15 - 10
toolchain/check/cpp/thunk.cpp

@@ -559,19 +559,26 @@ auto PerformCppThunkCall(Context& context, SemIR::LocId loc_id,
   auto& callee_function = context.functions().Get(callee_function_id);
   auto callee_function_params =
       context.inst_blocks().Get(callee_function.call_params_id);
+  auto callee_return_patterns =
+      context.inst_blocks().GetOrEmpty(callee_function.return_patterns_id);
 
   auto thunk_callee = GetCalleeAsFunction(context.sem_ir(), thunk_callee_id);
   auto& thunk_function = context.functions().Get(thunk_callee.function_id);
   auto thunk_function_params =
       context.inst_blocks().Get(thunk_function.call_params_id);
+  auto thunk_return_patterns =
+      context.inst_blocks().GetOrEmpty(thunk_function.return_patterns_id);
+
+  CARBON_CHECK(
+      callee_return_patterns.size() <= 1 && thunk_return_patterns.size() <= 1,
+      "TODO: generalize this logic to support multiple return patterns.");
 
   // Whether we need to pass a return address to the thunk as a final argument.
   bool thunk_takes_return_address =
-      callee_function.return_slot_pattern_id.has_value() &&
-      !thunk_function.return_slot_pattern_id.has_value();
+      !callee_return_patterns.empty() && thunk_return_patterns.empty();
 
   // The number of arguments we should be acquiring in order to call the thunk.
-  // This includes the return address parameter, if any.
+  // This includes the return address parameters, if any.
   unsigned num_thunk_args =
       context.inst_blocks().Get(thunk_function.param_patterns_id).size();
 
@@ -585,15 +592,13 @@ auto PerformCppThunkCall(Context& context, SemIR::LocId loc_id,
     return_slot_id = callee_arg_ids.consume_back();
   }
 
-  // If there's a return slot pattern, drop the corresponding parameter.
+  // If there are return slot patterns, drop the corresponding parameters.
   // TODO: The parameter should probably only be created if the return pattern
   // actually needs a return address to be passed in.
-  if (thunk_function.return_slot_pattern_id.has_value()) {
-    thunk_function_params.consume_back();
-  }
-  if (callee_function.return_slot_pattern_id.has_value()) {
-    callee_function_params.consume_back();
-  }
+  thunk_function_params =
+      thunk_function_params.drop_back(thunk_return_patterns.size());
+  callee_function_params =
+      callee_function_params.drop_back(callee_return_patterns.size());
 
   // We assume that the call parameters exactly match the parameter patterns for
   // both the thunk and the callee. This is currently guaranteed because we only

+ 2 - 3
toolchain/check/function.cpp

@@ -135,9 +135,8 @@ auto CheckFunctionDefinitionSignature(Context& context,
       context.inst_blocks().GetOrEmpty(function.call_params_id);
 
   // Check the return type is complete.
-  if (function.return_slot_pattern_id.has_value()) {
-    CheckFunctionReturnType(context,
-                            SemIR::LocId(function.return_slot_pattern_id),
+  if (function.return_type_inst_id.has_value()) {
+    CheckFunctionReturnType(context, SemIR::LocId(function.return_type_inst_id),
                             function, SemIR::SpecificId::None);
     // Don't re-check the return type below.
     params_to_complete.consume_back();

+ 2 - 1
toolchain/check/global_init.cpp

@@ -49,7 +49,8 @@ auto GlobalInit::Finalize() -> void {
         .non_owning_decl_id = SemIR::InstId::None,
         .first_owning_decl_id = SemIR::InstId::None},
        {.call_params_id = SemIR::InstBlockId::Empty,
-        .return_slot_pattern_id = SemIR::InstId::None,
+        .return_type_inst_id = SemIR::TypeInstId::None,
+        .return_patterns_id = SemIR::InstBlockId::None,
         .body_block_ids = {SemIR::InstBlockId::GlobalInit}}}));
 }
 

+ 19 - 13
toolchain/check/handle_function.cpp

@@ -56,6 +56,7 @@ auto HandleParseNode(Context& context, Parse::ReturnTypeId node_id) -> bool {
   // Propagate the type expression.
   auto [type_node_id, type_inst_id] = context.node_stack().PopExprWithNodeId();
   auto as_type = ExprAsType(context, type_node_id, type_inst_id);
+  context.PushReturnTypeInstId(as_type.inst_id);
 
   // If the previous node was `IdentifierNameBeforeParams`, then it would have
   // caused these entries to be pushed to the pattern stacks. But it's possible
@@ -167,7 +168,8 @@ static auto MergeFunctionRedecl(Context& context,
     // match IDs in the signature.
     prev_function.MergeDefinition(new_function);
     prev_function.call_params_id = new_function.call_params_id;
-    prev_function.return_slot_pattern_id = new_function.return_slot_pattern_id;
+    prev_function.return_type_inst_id = new_function.return_type_inst_id;
+    prev_function.return_patterns_id = new_function.return_patterns_id;
     prev_function.self_param_id = new_function.self_param_id;
   }
   if (prev_import_ir_id.has_value()) {
@@ -383,14 +385,18 @@ static auto BuildFunctionDecl(Context& context,
                               Parse::AnyFunctionDeclId node_id,
                               bool is_definition)
     -> std::pair<SemIR::FunctionId, SemIR::InstId> {
-  auto return_slot_pattern_id = SemIR::InstId::None;
+  llvm::SmallVector<SemIR::InstId> return_patterns;
+  auto return_type_inst_id = SemIR::TypeInstId::None;
   if (auto [return_node, maybe_return_slot_pattern_id] =
           context.node_stack().PopWithNodeIdIf<Parse::NodeKind::ReturnType>();
       maybe_return_slot_pattern_id) {
-    return_slot_pattern_id = *maybe_return_slot_pattern_id;
+    return_patterns.push_back(*maybe_return_slot_pattern_id);
+    return_type_inst_id = context.PopReturnTypeInstId();
+    CARBON_CHECK(return_type_inst_id.has_value());
   }
 
-  auto name = PopNameComponent(context, return_slot_pattern_id);
+  auto return_patterns_id = context.inst_blocks().Add(return_patterns);
+  auto name = PopNameComponent(context, return_patterns_id);
   auto name_context = context.decl_name_stack().FinishName(name);
 
   context.node_stack()
@@ -421,7 +427,8 @@ static auto BuildFunctionDecl(Context& context,
       SemIR::Function{name_context.MakeEntityWithParamsBase(
                           name, decl_id, is_extern, introducer.extern_library),
                       {.call_params_id = name.call_params_id,
-                       .return_slot_pattern_id = name.return_slot_pattern_id,
+                       .return_type_inst_id = return_type_inst_id,
+                       .return_patterns_id = return_patterns_id,
                        .virtual_modifier = virtual_modifier,
                        .self_param_id = self_param_id}};
   if (is_definition) {
@@ -542,9 +549,7 @@ auto HandleParseNode(Context& context, Parse::FunctionDefinitionId node_id)
   // If the `}` of the function is reachable, reject if we need a return value
   // and otherwise add an implicit `return;`.
   if (IsCurrentPositionReachable(context)) {
-    if (context.functions()
-            .Get(function_id)
-            .return_slot_pattern_id.has_value()) {
+    if (context.functions().Get(function_id).return_type_inst_id.has_value()) {
       CARBON_DIAGNOSTIC(
           MissingReturnStatement, Error,
           "missing `return` at end of function with declared return type");
@@ -610,11 +615,12 @@ static auto IsValidBuiltinDeclaration(Context& context,
     return false;
   }
 
-  // Find the list of call parameters other than the implicit return slot.
-  auto call_params = context.inst_blocks().Get(function.call_params_id);
-  if (function.return_slot_pattern_id.has_value()) {
-    call_params.consume_back();
-  }
+  // Find the list of call parameters other than the implicit return slots.
+  auto call_params = context.inst_blocks()
+                         .Get(function.call_params_id)
+                         .drop_back(context.inst_blocks()
+                                        .GetOrEmpty(function.return_patterns_id)
+                                        .size());
 
   // Get the return type. This is `()` if none was specified.
   auto return_type_id = function.GetDeclaredReturnType(context.sem_ir());

+ 1 - 2
toolchain/check/handle_impl.cpp

@@ -156,7 +156,7 @@ static auto PopImplIntroducerAndParamsAsNameComponent(
     // because `impl`s are never actually called at runtime.
     auto call_params_id =
         CalleePatternMatch(context, *implicit_param_patterns_id,
-                           SemIR::InstBlockId::None, SemIR::InstId::None);
+                           SemIR::InstBlockId::None, SemIR::InstBlockId::None);
     CARBON_CHECK(call_params_id == SemIR::InstBlockId::Empty ||
                  llvm::all_of(context.inst_blocks().Get(call_params_id),
                               [](SemIR::InstId inst_id) {
@@ -186,7 +186,6 @@ static auto PopImplIntroducerAndParamsAsNameComponent(
           .params_loc_id = Parse::NodeId::None,
           .param_patterns_id = SemIR::InstBlockId::None,
           .call_params_id = SemIR::InstBlockId::None,
-          .return_slot_pattern_id = SemIR::InstId::None,
           .pattern_block_id = pattern_block_id};
 }
 

+ 14 - 10
toolchain/check/import_ref.cpp

@@ -2155,7 +2155,8 @@ static auto MakeFunctionDecl(ImportContext& context,
   function_decl.function_id = context.local_functions().Add(
       {GetIncompleteLocalEntityBase(context, function_decl_id, import_function),
        {.call_params_id = SemIR::InstBlockId::None,
-        .return_slot_pattern_id = SemIR::InstId::None,
+        .return_type_inst_id = SemIR::TypeInstId::None,
+        .return_patterns_id = SemIR::InstBlockId::None,
         .virtual_modifier = import_function.virtual_modifier,
         .virtual_index = import_function.virtual_index}});
 
@@ -2211,10 +2212,9 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
   }
 
   auto return_type_const_id = SemIR::ConstantId::None;
-  if (import_function.return_slot_pattern_id.has_value()) {
-    return_type_const_id = GetLocalConstantId(
-        resolver, resolver.import_insts().GetAttachedType(
-                      import_function.return_slot_pattern_id));
+  if (import_function.return_type_inst_id.has_value()) {
+    return_type_const_id =
+        GetLocalConstantId(resolver, import_function.return_type_inst_id);
   }
   auto parent_scope_id =
       GetLocalNameScopeId(resolver, import_function.parent_scope_id);
@@ -2225,9 +2225,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
   auto generic_data = GetLocalGenericData(resolver, import_function.generic_id);
   auto self_param_id =
       GetLocalConstantInstId(resolver, import_function.self_param_id);
-  auto return_slot_pattern_id =
-      GetLocalConstantInstId(resolver, import_function.return_slot_pattern_id);
-
+  auto return_patterns =
+      GetLocalInstBlockContents(resolver, import_function.return_patterns_id);
   auto& new_function = resolver.local_functions().Get(function_id);
   if (resolver.HasNewWork()) {
     return ResolveResult::Retry(function_const_id,
@@ -2242,8 +2241,13 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
   new_function.self_param_id = self_param_id;
   new_function.param_patterns_id = GetLocalCanonicalInstBlockId(
       resolver, import_function.param_patterns_id, param_patterns);
-  new_function.return_slot_pattern_id = return_slot_pattern_id;
-
+  new_function.return_type_inst_id = SemIR::TypeInstId::None;
+  if (import_function.return_type_inst_id.has_value()) {
+    new_function.return_type_inst_id = AddLoadedImportRefForType(
+        resolver, import_function.return_type_inst_id, return_type_const_id);
+  }
+  new_function.return_patterns_id = GetLocalCanonicalInstBlockId(
+      resolver, import_function.return_patterns_id, return_patterns);
   if (import_function.definition_id.has_value()) {
     new_function.definition_id = new_function.first_owning_decl_id;
   }

+ 4 - 6
toolchain/check/name_component.cpp

@@ -9,7 +9,7 @@
 
 namespace Carbon::Check {
 
-auto PopNameComponent(Context& context, SemIR::InstId return_slot_pattern_id)
+auto PopNameComponent(Context& context, SemIR::InstBlockId return_patterns_id)
     -> NameComponent {
   Parse::NodeId first_param_node_id = Parse::NoneNodeId();
   Parse::NodeId last_param_node_id = Parse::NoneNodeId();
@@ -48,10 +48,9 @@ auto PopNameComponent(Context& context, SemIR::InstId return_slot_pattern_id)
   auto pattern_block_id = SemIR::InstBlockId::None;
   if (param_patterns_id->has_value() ||
       implicit_param_patterns_id->has_value() ||
-      return_slot_pattern_id.has_value()) {
-    call_params_id =
-        CalleePatternMatch(context, *implicit_param_patterns_id,
-                           *param_patterns_id, return_slot_pattern_id);
+      (!context.inst_blocks().GetOrEmpty(return_patterns_id).empty())) {
+    call_params_id = CalleePatternMatch(context, *implicit_param_patterns_id,
+                                        *param_patterns_id, return_patterns_id);
     pattern_block_id = context.pattern_block_stack().Pop();
     context.full_pattern_stack().PopFullPattern();
   }
@@ -69,7 +68,6 @@ auto PopNameComponent(Context& context, SemIR::InstId return_slot_pattern_id)
       .params_loc_id = params_node_id,
       .param_patterns_id = *param_patterns_id,
       .call_params_id = call_params_id,
-      .return_slot_pattern_id = return_slot_pattern_id,
       .pattern_block_id = pattern_block_id,
   };
 }

+ 2 - 9
toolchain/check/name_component.h

@@ -36,23 +36,16 @@ struct NameComponent {
 
   // The `Call` parameters of the entity, if it's a function (see the
   // corresponding member of SemIR::EntityWithParamsBase).
-  // TODO: This is only used for function declarations. Should it go somewhere
-  // else?
   SemIR::InstBlockId call_params_id;
 
-  // The return slot.
-  // TODO: This is only used for function declarations. Should it go
-  // somewhere else?
-  SemIR::InstId return_slot_pattern_id;
-
   // The pattern block.
   SemIR::InstBlockId pattern_block_id;
 };
 
 // Pops a name component from the node stack (and pattern block stack, if it has
 // parameters).
-auto PopNameComponent(Context& context, SemIR::InstId return_slot_pattern_id =
-                                            SemIR::InstId::None)
+auto PopNameComponent(Context& context, SemIR::InstBlockId return_patterns_id =
+                                            SemIR::InstBlockId::None)
     -> NameComponent;
 
 // Equivalent to PopNameComponent, but also diagnoses if the name component has

+ 2 - 1
toolchain/check/node_stack.h

@@ -415,7 +415,6 @@ class NodeStack {
       case Parse::NodeKind::FieldNameAndType:
       case Parse::NodeKind::IfExprThen:
       case Parse::NodeKind::RequireIntroducer:
-      case Parse::NodeKind::ReturnType:
       case Parse::NodeKind::ShortCircuitOperandAnd:
       case Parse::NodeKind::ShortCircuitOperandOr:
       case Parse::NodeKind::StructLiteralField:
@@ -447,6 +446,8 @@ class NodeStack {
       case Parse::NodeKind::DefaultLibrary:
       case Parse::NodeKind::LibraryName:
         return Id::KindFor<SemIR::LibraryNameId>();
+      case Parse::NodeKind::ReturnType:
+        return Id::KindFor<SemIR::InstId>();
       case Parse::NodeKind::AssociatedConstantInitializer:
       case Parse::NodeKind::AssociatedConstantIntroducer:
       case Parse::NodeKind::BuiltinName:

+ 12 - 9
toolchain/check/pattern_match.cpp

@@ -603,9 +603,9 @@ auto MatchContext::EmitPatternMatch(Context& context,
 auto CalleePatternMatch(Context& context,
                         SemIR::InstBlockId implicit_param_patterns_id,
                         SemIR::InstBlockId param_patterns_id,
-                        SemIR::InstId return_slot_pattern_id)
+                        SemIR::InstBlockId return_patterns_id)
     -> SemIR::InstBlockId {
-  if (!return_slot_pattern_id.has_value() && !param_patterns_id.has_value() &&
+  if (!return_patterns_id.has_value() && !param_patterns_id.has_value() &&
       !implicit_param_patterns_id.has_value()) {
     return SemIR::InstBlockId::None;
   }
@@ -614,9 +614,10 @@ auto CalleePatternMatch(Context& context,
 
   // We add work to the stack in reverse so that the results will be produced
   // in the original order.
-  if (return_slot_pattern_id.has_value()) {
-    match.AddWork({.pattern_id = return_slot_pattern_id,
-                   .scrutinee_id = SemIR::InstId::None});
+  for (auto return_pattern_id :
+       context.inst_blocks().GetOrEmpty(return_patterns_id)) {
+    match.AddWork(
+        {.pattern_id = return_pattern_id, .scrutinee_id = SemIR::InstId::None});
   }
 
   if (param_patterns_id.has_value()) {
@@ -641,18 +642,20 @@ auto CalleePatternMatch(Context& context,
 auto CallerPatternMatch(Context& context, SemIR::SpecificId specific_id,
                         SemIR::InstId self_pattern_id,
                         SemIR::InstBlockId param_patterns_id,
-                        SemIR::InstId return_slot_pattern_id,
+                        SemIR::InstBlockId return_patterns_id,
                         SemIR::InstId self_arg_id,
                         llvm::ArrayRef<SemIR::InstId> arg_refs,
                         SemIR::InstId return_slot_arg_id)
     -> SemIR::InstBlockId {
   MatchContext match(MatchKind::Caller, specific_id);
 
+  auto return_patterns = context.inst_blocks().GetOrEmpty(return_patterns_id);
   // Track the return storage, if present.
   if (return_slot_arg_id.has_value()) {
-    CARBON_CHECK(return_slot_pattern_id.has_value());
-    match.AddWork({.pattern_id = return_slot_pattern_id,
-                   .scrutinee_id = return_slot_arg_id});
+    CARBON_CHECK(return_patterns.size() == 1,
+                 "TODO: implement support for multiple return patterns");
+    match.AddWork(
+        {.pattern_id = return_patterns[0], .scrutinee_id = return_slot_arg_id});
   }
 
   // Check type conversions per-element.

+ 4 - 4
toolchain/check/pattern_match.h

@@ -19,8 +19,8 @@ namespace Carbon::Check {
 // as a descendant are matched by the caller.
 
 // Emits the pattern-match IR for the declaration of a parameterized entity with
-// the given implicit and explicit parameter patterns, and the given return slot
-// pattern (any of which may be `None` if not applicable). This IR performs the
+// the given implicit and explicit parameter patterns, and the given return
+// patterns (any of which may be `None` if not applicable). This IR performs the
 // callee side of pattern matching, starting at the `ParamPattern` insts, and
 // matching them against the corresponding `Call` parameters (see
 // entity_with_params_base.h for the definition of that term).
@@ -29,7 +29,7 @@ namespace Carbon::Check {
 auto CalleePatternMatch(Context& context,
                         SemIR::InstBlockId implicit_param_patterns_id,
                         SemIR::InstBlockId param_patterns_id,
-                        SemIR::InstId return_slot_pattern_id)
+                        SemIR::InstBlockId return_patterns_id)
     -> SemIR::InstBlockId;
 
 // Emits the pattern-match IR for matching the given arguments with the given
@@ -38,7 +38,7 @@ auto CalleePatternMatch(Context& context,
 auto CallerPatternMatch(Context& context, SemIR::SpecificId specific_id,
                         SemIR::InstId self_pattern_id,
                         SemIR::InstBlockId param_patterns_id,
-                        SemIR::InstId return_slot_pattern_id,
+                        SemIR::InstBlockId return_patterns_id,
                         SemIR::InstId self_arg_id,
                         llvm::ArrayRef<SemIR::InstId> arg_refs,
                         SemIR::InstId return_slot_arg_id) -> SemIR::InstBlockId;

+ 5 - 11
toolchain/check/return.cpp

@@ -48,18 +48,12 @@ static auto NoteNoReturnTypeProvided(DiagnosticBuilder& diag,
 
 // Produces a note describing the return type of the given function, which
 // must be a function whose definition is currently being checked.
-static auto NoteReturnType(Context& context, DiagnosticBuilder& diag,
+static auto NoteReturnType(DiagnosticBuilder& diag,
                            const SemIR::Function& function) {
-  auto out_param_pattern = context.insts().GetAs<SemIR::OutParamPattern>(
-      function.return_slot_pattern_id);
-  auto return_type_inst_id =
-      context.insts()
-          .GetAs<SemIR::ReturnSlotPattern>(out_param_pattern.subpattern_id)
-          .type_inst_id;
   CARBON_DIAGNOSTIC(ReturnTypeHereNote, Note, "return type of function is {0}",
                     InstIdAsType);
-  diag.Note(function.return_slot_pattern_id, ReturnTypeHereNote,
-            return_type_inst_id);
+  diag.Note(function.return_type_inst_id, ReturnTypeHereNote,
+            function.return_type_inst_id);
 }
 
 // Produces a note pointing at the currently in scope `returned var`.
@@ -99,7 +93,7 @@ auto RegisterReturnedVar(Context& context, Parse::NodeId returned_node,
                       SemIR::TypeId);
     auto diag =
         context.emitter().Build(type_node, ReturnedVarWrongType, type_id);
-    NoteReturnType(context, diag, function);
+    NoteReturnType(diag, function);
     diag.Emit();
   }
 
@@ -122,7 +116,7 @@ auto BuildReturnWithNoExpr(Context& context, SemIR::LocId loc_id) -> void {
     CARBON_DIAGNOSTIC(ReturnStatementMissingExpr, Error,
                       "missing return value");
     auto diag = context.emitter().Build(loc_id, ReturnStatementMissingExpr);
-    NoteReturnType(context, diag, function);
+    NoteReturnType(diag, function);
     diag.Emit();
   }
 

+ 8 - 8
toolchain/check/testdata/alias/preserve_in_type_printing.carbon

@@ -22,32 +22,32 @@ alias A = C;
 // CHECK:STDERR: fail_alias_nested_in_type.carbon:[[@LINE+7]]:15: error: missing return value [ReturnStatementMissingExpr]
 // CHECK:STDERR: fn F() -> A { return; }
 // CHECK:STDERR:               ^~~~~~~
-// CHECK:STDERR: fail_alias_nested_in_type.carbon:[[@LINE+4]]:8: note: return type of function is `A` [ReturnTypeHereNote]
+// CHECK:STDERR: fail_alias_nested_in_type.carbon:[[@LINE+4]]:11: note: return type of function is `A` [ReturnTypeHereNote]
 // CHECK:STDERR: fn F() -> A { return; }
-// CHECK:STDERR:        ^~~~
+// CHECK:STDERR:           ^
 // CHECK:STDERR:
 fn F() -> A { return; }
 // CHECK:STDERR: fail_alias_nested_in_type.carbon:[[@LINE+7]]:16: error: missing return value [ReturnStatementMissingExpr]
 // CHECK:STDERR: fn G() -> A* { return; }
 // CHECK:STDERR:                ^~~~~~~
-// CHECK:STDERR: fail_alias_nested_in_type.carbon:[[@LINE+4]]:8: note: return type of function is `A*` [ReturnTypeHereNote]
+// CHECK:STDERR: fail_alias_nested_in_type.carbon:[[@LINE+4]]:11: note: return type of function is `A*` [ReturnTypeHereNote]
 // CHECK:STDERR: fn G() -> A* { return; }
-// CHECK:STDERR:        ^~~~~
+// CHECK:STDERR:           ^~
 // CHECK:STDERR:
 fn G() -> A* { return; }
 // CHECK:STDERR: fail_alias_nested_in_type.carbon:[[@LINE+7]]:22: error: missing return value [ReturnStatementMissingExpr]
 // CHECK:STDERR: fn H() -> const A* { return; }
 // CHECK:STDERR:                      ^~~~~~~
-// CHECK:STDERR: fail_alias_nested_in_type.carbon:[[@LINE+4]]:8: note: return type of function is `const A*` [ReturnTypeHereNote]
+// CHECK:STDERR: fail_alias_nested_in_type.carbon:[[@LINE+4]]:11: note: return type of function is `const A*` [ReturnTypeHereNote]
 // CHECK:STDERR: fn H() -> const A* { return; }
-// CHECK:STDERR:        ^~~~~~~~~~~
+// CHECK:STDERR:           ^~~~~~~~
 // CHECK:STDERR:
 fn H() -> const A* { return; }
 // CHECK:STDERR: fail_alias_nested_in_type.carbon:[[@LINE+7]]:26: error: missing return value [ReturnStatementMissingExpr]
 // CHECK:STDERR: fn I() -> array(A, 42) { return; }
 // CHECK:STDERR:                          ^~~~~~~
-// CHECK:STDERR: fail_alias_nested_in_type.carbon:[[@LINE+4]]:8: note: return type of function is `array(A, 42)` [ReturnTypeHereNote]
+// CHECK:STDERR: fail_alias_nested_in_type.carbon:[[@LINE+4]]:11: note: return type of function is `array(A, 42)` [ReturnTypeHereNote]
 // CHECK:STDERR: fn I() -> array(A, 42) { return; }
-// CHECK:STDERR:        ^~~~~~~~~~~~~~~
+// CHECK:STDERR:           ^~~~~~~~~~~~
 // CHECK:STDERR:
 fn I() -> array(A, 42) { return; }

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

@@ -63,7 +63,7 @@ fn G(x: Cpp.X) {
 // CHECK:STDOUT:   cpp_global_vars:
 // CHECK:STDOUT:     cpp_global_var60000000: {key: {entity_name_id: entity_name60000003}, clang_decl_id: clang_decl_id60000007}
 // CHECK:STDOUT:   functions:
-// CHECK:STDOUT:     function60000000: {name: name0, parent_scope: name_scope0, call_params_id: inst_block60000006, body: [inst_block60000009]}
+// CHECK:STDOUT:     function60000000: {name: name0, parent_scope: name_scope0, call_params_id: inst_block60000006, return_patterns_id: inst_block_empty, body: [inst_block60000009]}
 // CHECK:STDOUT:     function60000001: {name: name3, parent_scope: name_scope60000001, call_params_id: inst_block_empty}
 // CHECK:STDOUT:     function60000002: {name: name6, parent_scope: name_scope60000001, call_params_id: inst_block_empty}
 // CHECK:STDOUT:     function60000003: {name: name3, parent_scope: name_scope60000001, call_params_id: inst_block6000000D}

+ 3 - 3
toolchain/check/testdata/basics/raw_sem_ir/multifile.carbon

@@ -40,7 +40,7 @@ fn B() {
 // CHECK:STDOUT:   entity_names:    {}
 // CHECK:STDOUT:   cpp_global_vars: {}
 // CHECK:STDOUT:   functions:
-// CHECK:STDOUT:     function60000000: {name: name0, parent_scope: name_scope0, call_params_id: inst_block_empty, body: [inst_block60000005]}
+// CHECK:STDOUT:     function60000000: {name: name0, parent_scope: name_scope0, call_params_id: inst_block_empty, return_patterns_id: inst_block_empty, body: [inst_block60000005]}
 // CHECK:STDOUT:   classes:         {}
 // CHECK:STDOUT:   generics:        {}
 // CHECK:STDOUT:   specifics:       {}
@@ -103,8 +103,8 @@ fn B() {
 // CHECK:STDOUT:     entity_name50000000: {name: name1, parent_scope: name_scope50000001, index: -1, is_template: 0}
 // CHECK:STDOUT:   cpp_global_vars: {}
 // CHECK:STDOUT:   functions:
-// CHECK:STDOUT:     function50000000: {name: name0, parent_scope: name_scope0, call_params_id: inst_block_empty, body: [inst_block50000005]}
-// CHECK:STDOUT:     function50000001: {name: name1, parent_scope: name_scope50000001}
+// CHECK:STDOUT:     function50000000: {name: name0, parent_scope: name_scope0, call_params_id: inst_block_empty, return_patterns_id: inst_block_empty, body: [inst_block50000005]}
+// CHECK:STDOUT:     function50000001: {name: name1, parent_scope: name_scope50000001, return_patterns_id: inst_block_empty}
 // CHECK:STDOUT:   classes:         {}
 // CHECK:STDOUT:   generics:        {}
 // CHECK:STDOUT:   specifics:       {}

+ 3 - 3
toolchain/check/testdata/basics/raw_sem_ir/multifile_with_textual_ir.carbon

@@ -40,7 +40,7 @@ fn B() {
 // CHECK:STDOUT:   entity_names:    {}
 // CHECK:STDOUT:   cpp_global_vars: {}
 // CHECK:STDOUT:   functions:
-// CHECK:STDOUT:     function60000000: {name: name0, parent_scope: name_scope0, call_params_id: inst_block_empty, body: [inst_block60000005]}
+// CHECK:STDOUT:     function60000000: {name: name0, parent_scope: name_scope0, call_params_id: inst_block_empty, return_patterns_id: inst_block_empty, body: [inst_block60000005]}
 // CHECK:STDOUT:   classes:         {}
 // CHECK:STDOUT:   generics:        {}
 // CHECK:STDOUT:   specifics:       {}
@@ -122,8 +122,8 @@ fn B() {
 // CHECK:STDOUT:     entity_name50000000: {name: name1, parent_scope: name_scope50000001, index: -1, is_template: 0}
 // CHECK:STDOUT:   cpp_global_vars: {}
 // CHECK:STDOUT:   functions:
-// CHECK:STDOUT:     function50000000: {name: name0, parent_scope: name_scope0, call_params_id: inst_block_empty, body: [inst_block50000005]}
-// CHECK:STDOUT:     function50000001: {name: name1, parent_scope: name_scope50000001}
+// CHECK:STDOUT:     function50000000: {name: name0, parent_scope: name_scope0, call_params_id: inst_block_empty, return_patterns_id: inst_block_empty, body: [inst_block50000005]}
+// CHECK:STDOUT:     function50000001: {name: name1, parent_scope: name_scope50000001, return_patterns_id: inst_block_empty}
 // CHECK:STDOUT:   classes:         {}
 // CHECK:STDOUT:   generics:        {}
 // CHECK:STDOUT:   specifics:       {}

Разница между файлами не показана из-за своего большого размера
+ 532 - 521
toolchain/check/testdata/basics/raw_sem_ir/one_file.carbon


+ 14 - 12
toolchain/check/testdata/basics/raw_sem_ir/one_file_with_textual_ir.carbon

@@ -31,7 +31,7 @@ fn Foo(n: ()) -> ((), ()) {
 // CHECK:STDOUT:     entity_name60000000: {name: name1, parent_scope: name_scope<none>, index: -1, is_template: 0}
 // CHECK:STDOUT:   cpp_global_vars: {}
 // CHECK:STDOUT:   functions:
-// CHECK:STDOUT:     function60000000: {name: name0, parent_scope: name_scope0, call_params_id: inst_block6000000A, return_slot_pattern: inst60000022, body: [inst_block6000000D]}
+// CHECK:STDOUT:     function60000000: {name: name0, parent_scope: name_scope0, call_params_id: inst_block6000000B, return_type_inst_id: inst6000001F, return_patterns_id: inst_block6000000A, body: [inst_block6000000E]}
 // CHECK:STDOUT:   classes:         {}
 // CHECK:STDOUT:   generics:        {}
 // CHECK:STDOUT:   specifics:       {}
@@ -78,19 +78,19 @@ fn Foo(n: ()) -> ((), ()) {
 // CHECK:STDOUT:     inst60000024:    {kind: SpliceBlock, arg0: inst_block60000004, arg1: inst60000012, type: type(TypeType)}
 // CHECK:STDOUT:     inst60000025:    {kind: OutParam, arg0: call_param1, arg1: name(ReturnSlot), type: type(inst60000019)}
 // CHECK:STDOUT:     inst60000026:    {kind: ReturnSlot, arg0: inst60000019, arg1: inst60000025, type: type(inst60000019)}
-// CHECK:STDOUT:     inst60000027:    {kind: FunctionDecl, arg0: function60000000, arg1: inst_block6000000C, type: type(inst60000028)}
+// CHECK:STDOUT:     inst60000027:    {kind: FunctionDecl, arg0: function60000000, arg1: inst_block6000000D, type: type(inst60000028)}
 // CHECK:STDOUT:     inst60000028:    {kind: FunctionType, arg0: function60000000, arg1: specific<none>, type: type(TypeType)}
 // CHECK:STDOUT:     inst60000029:    {kind: StructValue, arg0: inst_block_empty, type: type(inst60000028)}
 // CHECK:STDOUT:     inst6000002A:    {kind: NameRef, arg0: name1, arg1: inst60000013, type: type(inst6000000F)}
 // CHECK:STDOUT:     inst6000002B:    {kind: TupleLiteral, arg0: inst_block_empty, type: type(inst6000000F)}
-// CHECK:STDOUT:     inst6000002C:    {kind: TupleLiteral, arg0: inst_block6000000E, type: type(inst60000019)}
+// CHECK:STDOUT:     inst6000002C:    {kind: TupleLiteral, arg0: inst_block6000000F, type: type(inst60000019)}
 // CHECK:STDOUT:     inst6000002D:    {kind: TupleAccess, arg0: inst60000026, arg1: element0, type: type(inst6000000F)}
-// CHECK:STDOUT:     inst6000002E:    {kind: TupleInit, arg0: inst_block6000000F, arg1: inst6000002D, type: type(inst6000000F)}
+// CHECK:STDOUT:     inst6000002E:    {kind: TupleInit, arg0: inst_block60000010, arg1: inst6000002D, type: type(inst6000000F)}
 // CHECK:STDOUT:     inst6000002F:    {kind: Converted, arg0: inst6000002A, arg1: inst6000002E, type: type(inst6000000F)}
 // CHECK:STDOUT:     inst60000030:    {kind: TupleAccess, arg0: inst60000026, arg1: element1, type: type(inst6000000F)}
 // CHECK:STDOUT:     inst60000031:    {kind: TupleInit, arg0: inst_block_empty, arg1: inst60000030, type: type(inst6000000F)}
 // CHECK:STDOUT:     inst60000032:    {kind: Converted, arg0: inst6000002B, arg1: inst60000031, type: type(inst6000000F)}
-// CHECK:STDOUT:     inst60000033:    {kind: TupleInit, arg0: inst_block60000010, arg1: inst60000026, type: type(inst60000019)}
+// CHECK:STDOUT:     inst60000033:    {kind: TupleInit, arg0: inst_block60000011, arg1: inst60000026, type: type(inst60000019)}
 // CHECK:STDOUT:     inst60000034:    {kind: Converted, arg0: inst6000002C, arg1: inst60000033, type: type(inst60000019)}
 // CHECK:STDOUT:     inst60000035:    {kind: ReturnExpr, arg0: inst60000034, arg1: inst60000026}
 // CHECK:STDOUT:   constant_values:
@@ -151,14 +151,16 @@ fn Foo(n: ()) -> ((), ()) {
 // CHECK:STDOUT:       0:               inst6000001D
 // CHECK:STDOUT:       1:               inst6000001E
 // CHECK:STDOUT:     inst_block6000000A:
+// CHECK:STDOUT:       0:               inst60000022
+// CHECK:STDOUT:     inst_block6000000B:
 // CHECK:STDOUT:       0:               inst60000023
 // CHECK:STDOUT:       1:               inst60000025
-// CHECK:STDOUT:     inst_block6000000B:
+// CHECK:STDOUT:     inst_block6000000C:
 // CHECK:STDOUT:       0:               inst60000015
 // CHECK:STDOUT:       1:               inst60000016
 // CHECK:STDOUT:       2:               inst60000021
 // CHECK:STDOUT:       3:               inst60000022
-// CHECK:STDOUT:     inst_block6000000C:
+// CHECK:STDOUT:     inst_block6000000D:
 // CHECK:STDOUT:       0:               inst60000017
 // CHECK:STDOUT:       1:               inst60000018
 // CHECK:STDOUT:       2:               inst6000001A
@@ -170,7 +172,7 @@ fn Foo(n: ()) -> ((), ()) {
 // CHECK:STDOUT:       8:               inst60000013
 // CHECK:STDOUT:       9:               inst60000025
 // CHECK:STDOUT:       10:              inst60000026
-// CHECK:STDOUT:     inst_block6000000D:
+// CHECK:STDOUT:     inst_block6000000E:
 // CHECK:STDOUT:       0:               inst6000002A
 // CHECK:STDOUT:       1:               inst6000002B
 // CHECK:STDOUT:       2:               inst6000002C
@@ -183,14 +185,14 @@ fn Foo(n: ()) -> ((), ()) {
 // CHECK:STDOUT:       9:               inst60000033
 // CHECK:STDOUT:       10:              inst60000034
 // CHECK:STDOUT:       11:              inst60000035
-// CHECK:STDOUT:     inst_block6000000E:
+// CHECK:STDOUT:     inst_block6000000F:
 // CHECK:STDOUT:       0:               inst6000002A
 // CHECK:STDOUT:       1:               inst6000002B
-// CHECK:STDOUT:     inst_block6000000F: {}
-// CHECK:STDOUT:     inst_block60000010:
+// CHECK:STDOUT:     inst_block60000010: {}
+// CHECK:STDOUT:     inst_block60000011:
 // CHECK:STDOUT:       0:               inst6000002F
 // CHECK:STDOUT:       1:               inst60000032
-// CHECK:STDOUT:     inst_block60000011:
+// CHECK:STDOUT:     inst_block60000012:
 // CHECK:STDOUT:       0:               instE
 // CHECK:STDOUT:       1:               inst60000027
 // CHECK:STDOUT: ...

+ 2 - 2
toolchain/check/testdata/class/fail_abstract.carbon

@@ -186,9 +186,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]]:21: note: return type declared here [IncompleteReturnTypeHere]
+  // CHECK:STDERR: fail_call_abstract_return.carbon:[[@LINE-9]]:24: 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]]:24: error: function returns incomplete type `Class` [IncompleteTypeInFunctionReturnType]
+// CHECK:STDERR: fail_forward_decl.carbon:[[@LINE+7]]:27: 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]]:20: error: function returns incomplete type `Class` [IncompleteTypeInFunctionReturnType]
+// CHECK:STDERR: fail_forward_decl.carbon:[[@LINE+7]]:23: 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]]:23: note: return type declared here [IncompleteReturnTypeHere]
+  // CHECK:STDERR: fail_forward_decl.carbon:[[@LINE-35]]:26: 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

@@ -183,7 +183,7 @@ class Declaration(T:! type);
 // CHECK:STDOUT:   %pattern_type.loc6_32: type = pattern_type %ptr.loc6_36.1 [symbolic = %pattern_type.loc6_32 (constants.%pattern_type.95d)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_32: <witness> = require_complete_type %ptr.loc6_36.1 [symbolic = %require_complete.loc6_32 (constants.%require_complete.c97)]
+// CHECK:STDOUT:   %require_complete.loc6_36: <witness> = require_complete_type %ptr.loc6_36.1 [symbolic = %require_complete.loc6_36 (constants.%require_complete.c97)]
 // CHECK:STDOUT:   %require_complete.loc6_22: <witness> = require_complete_type %Class [symbolic = %require_complete.loc6_22 (constants.%require_complete.3be)]
 // CHECK:STDOUT:   %Class.elem: type = unbound_element_type %Class, %T.binding.as_type [symbolic = %Class.elem (constants.%Class.elem)]
 // CHECK:STDOUT:   %.loc7_12.2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.binding.as_type) [symbolic = %.loc7_12.2 (constants.%.892)]

+ 2 - 2
toolchain/check/testdata/class/generic/field.carbon

@@ -246,7 +246,7 @@ fn H(U:! Core.Copy, c: Class(U)) -> U {
 // CHECK:STDOUT:   %pattern_type.loc13_34: type = pattern_type %T.binding.as_type [symbolic = %pattern_type.loc13_34 (constants.%pattern_type.c769df.2)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc13_34: <witness> = require_complete_type %T.binding.as_type [symbolic = %require_complete.loc13_34 (constants.%require_complete.91e646.1)]
+// CHECK:STDOUT:   %require_complete.loc13_37: <witness> = require_complete_type %T.binding.as_type [symbolic = %require_complete.loc13_37 (constants.%require_complete.91e646.1)]
 // CHECK:STDOUT:   %require_complete.loc13_22: <witness> = require_complete_type %Class.loc13_31.1 [symbolic = %require_complete.loc13_22 (constants.%require_complete.a2422b.1)]
 // CHECK:STDOUT:   %Class.elem: type = unbound_element_type %Class.loc13_31.1, %T.binding.as_type [symbolic = %Class.elem (constants.%Class.elem.814ce2.1)]
 // CHECK:STDOUT:   %Copy.lookup_impl_witness: <witness> = lookup_impl_witness %T.loc13_6.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.edd34c.1)]
@@ -278,7 +278,7 @@ fn H(U:! Core.Copy, c: Class(U)) -> U {
 // CHECK:STDOUT:   %pattern_type.loc17_34: type = pattern_type %U.binding.as_type [symbolic = %pattern_type.loc17_34 (constants.%pattern_type.c769df.3)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc17_34: <witness> = require_complete_type %U.binding.as_type [symbolic = %require_complete.loc17_34 (constants.%require_complete.91e646.2)]
+// CHECK:STDOUT:   %require_complete.loc17_37: <witness> = require_complete_type %U.binding.as_type [symbolic = %require_complete.loc17_37 (constants.%require_complete.91e646.2)]
 // CHECK:STDOUT:   %require_complete.loc17_22: <witness> = require_complete_type %Class.loc17_31.1 [symbolic = %require_complete.loc17_22 (constants.%require_complete.a2422b.2)]
 // CHECK:STDOUT:   %Class.elem: type = unbound_element_type %Class.loc17_31.1, %U.binding.as_type [symbolic = %Class.elem (constants.%Class.elem.814ce2.2)]
 // CHECK:STDOUT:   %Copy.lookup_impl_witness: <witness> = lookup_impl_witness %U.loc17_6.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.edd34c.2)]

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

@@ -338,7 +338,7 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) {
 // CHECK:STDOUT:   %pattern_type.loc13_32 => constants.%pattern_type.fe8
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc13_32 => constants.%complete_type.3d0
+// CHECK:STDOUT:   %require_complete.loc13_36 => constants.%complete_type.3d0
 // CHECK:STDOUT:   %require_complete.loc13_22 => constants.%complete_type.1ec
 // CHECK:STDOUT:   %Class.elem => constants.%Class.elem.9ac
 // CHECK:STDOUT:   %.loc15_12.2 => constants.%.ff7

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

@@ -261,7 +261,7 @@ fn Test() -> i32 {
 // CHECK:STDOUT:   %pattern_type.loc9_14: type = pattern_type %Inner [symbolic = %pattern_type.loc9_14 (constants.%pattern_type.098)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc9_14: <witness> = require_complete_type %Inner [symbolic = %require_complete.loc9_14 (constants.%require_complete.872)]
+// CHECK:STDOUT:   %require_complete.loc9_17: <witness> = require_complete_type %Inner [symbolic = %require_complete.loc9_17 (constants.%require_complete.872)]
 // CHECK:STDOUT:   %require_complete.loc9_9: <witness> = require_complete_type %T.binding.as_type [symbolic = %require_complete.loc9_9 (constants.%require_complete.91e)]
 // CHECK:STDOUT:   %struct_type.n: type = struct_type {.n: @Outer.F.%T.binding.as_type (%T.binding.as_type)} [symbolic = %struct_type.n (constants.%struct_type.n.8b0)]
 // CHECK:STDOUT:   %Copy.lookup_impl_witness: <witness> = lookup_impl_witness %T, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.edd)]
@@ -400,7 +400,7 @@ fn Test() -> i32 {
 // CHECK:STDOUT:   %pattern_type.loc9_14 => constants.%pattern_type.415
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc9_14 => constants.%complete_type.54b
+// CHECK:STDOUT:   %require_complete.loc9_17 => constants.%complete_type.54b
 // CHECK:STDOUT:   %require_complete.loc9_9 => constants.%complete_type.f8a
 // CHECK:STDOUT:   %struct_type.n => constants.%struct_type.n.033
 // CHECK:STDOUT:   %Copy.lookup_impl_witness => constants.%Copy.impl_witness.09c
@@ -709,7 +709,7 @@ fn Test() -> i32 {
 // CHECK:STDOUT:   %pattern_type.loc11_23: type = pattern_type %T [symbolic = %pattern_type.loc11_23 (constants.%pattern_type.51d)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc11_23: <witness> = require_complete_type %T [symbolic = %require_complete.loc11_23 (constants.%require_complete.944)]
+// 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_16: <witness> = require_complete_type %C [symbolic = %require_complete.loc11_16 (constants.%require_complete.3bd)]
 // CHECK:STDOUT:   %Inner.type: type = facet_type <@Inner, @Inner(%T)> [symbolic = %Inner.type (constants.%Inner.type.83d)]
 // CHECK:STDOUT:   %require_complete.loc11_48: <witness> = require_complete_type %Inner.type [symbolic = %require_complete.loc11_48 (constants.%require_complete.b33)]
@@ -904,7 +904,7 @@ fn Test() -> i32 {
 // CHECK:STDOUT:   %pattern_type.loc11_23 => constants.%pattern_type.7ce
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc11_23 => constants.%complete_type.f8a
+// CHECK:STDOUT:   %require_complete.loc11_26 => constants.%complete_type.f8a
 // CHECK:STDOUT:   %require_complete.loc11_16 => constants.%complete_type.357
 // CHECK:STDOUT:   %Inner.type => constants.%Inner.type.56c
 // CHECK:STDOUT:   %require_complete.loc11_48 => constants.%complete_type.619

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

@@ -251,7 +251,7 @@ fn G() {
 // CHECK:STDOUT:   %pattern_type.loc6_32: type = pattern_type %T.loc6_6.1 [symbolic = %pattern_type.loc6_32 (constants.%pattern_type.51d)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_32: <witness> = require_complete_type %T.loc6_6.1 [symbolic = %require_complete.loc6_32 (constants.%require_complete.944)]
+// CHECK:STDOUT:   %require_complete.loc6_35: <witness> = require_complete_type %T.loc6_6.1 [symbolic = %require_complete.loc6_35 (constants.%require_complete.944)]
 // CHECK:STDOUT:   %require_complete.loc6_17: <witness> = require_complete_type %array_type.loc6_29.1 [symbolic = %require_complete.loc6_17 (constants.%require_complete.ff3)]
 // CHECK:STDOUT:   %F.specific_fn.loc6_46.2: <specific function> = specific_function constants.%F, @F(%T.loc6_6.1) [symbolic = %F.specific_fn.loc6_46.2 (constants.%F.specific_fn.bb1)]
 // CHECK:STDOUT:
@@ -318,7 +318,7 @@ fn G() {
 // CHECK:STDOUT:   %pattern_type.loc6_32 => constants.%pattern_type.51d
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_32 => constants.%require_complete.944
+// CHECK:STDOUT:   %require_complete.loc6_35 => constants.%require_complete.944
 // CHECK:STDOUT:   %require_complete.loc6_17 => constants.%require_complete.ff3
 // CHECK:STDOUT:   %F.specific_fn.loc6_46.2 => constants.%F.specific_fn.bb1
 // CHECK:STDOUT: }
@@ -330,7 +330,7 @@ fn G() {
 // CHECK:STDOUT:   %pattern_type.loc6_32 => constants.%pattern_type.c48
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_32 => constants.%complete_type.357
+// CHECK:STDOUT:   %require_complete.loc6_35 => constants.%complete_type.357
 // CHECK:STDOUT:   %require_complete.loc6_17 => constants.%complete_type.dd1
 // CHECK:STDOUT:   %F.specific_fn.loc6_46.2 => constants.%F.specific_fn.04a
 // CHECK:STDOUT: }
@@ -846,7 +846,7 @@ fn G() {
 // CHECK:STDOUT:   %pattern_type.loc6_32: type = pattern_type %T.loc6_6.1 [symbolic = %pattern_type.loc6_32 (constants.%pattern_type.51d1c4.1)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_32: <witness> = require_complete_type %T.loc6_6.1 [symbolic = %require_complete.loc6_32 (constants.%require_complete.944)]
+// CHECK:STDOUT:   %require_complete.loc6_35: <witness> = require_complete_type %T.loc6_6.1 [symbolic = %require_complete.loc6_35 (constants.%require_complete.944)]
 // CHECK:STDOUT:   %require_complete.loc6_17: <witness> = require_complete_type %array_type.loc6_29.1 [symbolic = %require_complete.loc6_17 (constants.%require_complete.fc9)]
 // CHECK:STDOUT:   %F.specific_fn.loc6_46.2: <specific function> = specific_function constants.%F, @F(%T.loc6_6.1) [symbolic = %F.specific_fn.loc6_46.2 (constants.%F.specific_fn.bb1)]
 // CHECK:STDOUT:
@@ -913,7 +913,7 @@ fn G() {
 // CHECK:STDOUT:   %pattern_type.loc6_32 => constants.%pattern_type.51d1c4.1
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_32 => constants.%require_complete.944
+// CHECK:STDOUT:   %require_complete.loc6_35 => constants.%require_complete.944
 // CHECK:STDOUT:   %require_complete.loc6_17 => constants.%require_complete.fc9
 // CHECK:STDOUT:   %F.specific_fn.loc6_46.2 => constants.%F.specific_fn.bb1
 // CHECK:STDOUT: }
@@ -925,7 +925,7 @@ fn G() {
 // CHECK:STDOUT:   %pattern_type.loc6_32 => constants.%pattern_type.c48
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_32 => constants.%complete_type.357
+// CHECK:STDOUT:   %require_complete.loc6_35 => constants.%complete_type.357
 // CHECK:STDOUT:   %require_complete.loc6_17 => constants.%complete_type.8eb
 // CHECK:STDOUT:   %F.specific_fn.loc6_46.2 => constants.%F.specific_fn.04a
 // CHECK:STDOUT: }

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

@@ -188,7 +188,7 @@ fn G() -> i32 {
 // CHECK:STDOUT:   %pattern_type.loc7_25: type = pattern_type %T.loc7_6.1 [symbolic = %pattern_type.loc7_25 (constants.%pattern_type.51d)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc7_25: <witness> = require_complete_type %T.loc7_6.1 [symbolic = %require_complete.loc7_25 (constants.%require_complete.944)]
+// CHECK:STDOUT:   %require_complete.loc7_28: <witness> = require_complete_type %T.loc7_6.1 [symbolic = %require_complete.loc7_28 (constants.%require_complete.944)]
 // CHECK:STDOUT:   %require_complete.loc7_17: <witness> = require_complete_type %C.loc7_22.1 [symbolic = %require_complete.loc7_17 (constants.%require_complete.e46)]
 // CHECK:STDOUT:   %F.specific_fn.loc7_39.2: <specific function> = specific_function constants.%F, @F(%T.loc7_6.1) [symbolic = %F.specific_fn.loc7_39.2 (constants.%F.specific_fn.bb1)]
 // CHECK:STDOUT:
@@ -226,7 +226,7 @@ fn G() -> i32 {
 // CHECK:STDOUT:   %pattern_type.loc7_25 => constants.%pattern_type.51d
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc7_25 => constants.%require_complete.944
+// CHECK:STDOUT:   %require_complete.loc7_28 => constants.%require_complete.944
 // CHECK:STDOUT:   %require_complete.loc7_17 => constants.%require_complete.e46
 // CHECK:STDOUT:   %F.specific_fn.loc7_39.2 => constants.%F.specific_fn.bb1
 // CHECK:STDOUT: }
@@ -244,7 +244,7 @@ fn G() -> i32 {
 // CHECK:STDOUT:   %pattern_type.loc7_25 => constants.%pattern_type.510
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc7_25 => constants.%complete_type
+// CHECK:STDOUT:   %require_complete.loc7_28 => constants.%complete_type
 // CHECK:STDOUT:   %require_complete.loc7_17 => constants.%complete_type
 // CHECK:STDOUT:   %F.specific_fn.loc7_39.2 => constants.%F.specific_fn.c4a
 // CHECK:STDOUT: }
@@ -612,7 +612,7 @@ fn G() -> i32 {
 // CHECK:STDOUT:   %pattern_type.loc13_48: type = pattern_type %tuple.type [symbolic = %pattern_type.loc13_48 (constants.%pattern_type.eee)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc13_48: <witness> = require_complete_type %tuple.type [symbolic = %require_complete.loc13_48 (constants.%require_complete.220)]
+// 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_27: <witness> = require_complete_type %Inner.loc13_45.1 [symbolic = %require_complete.loc13_27 (constants.%require_complete.6ae)]
 // CHECK:STDOUT:   %F.specific_fn.loc13_67.2: <specific function> = specific_function constants.%F, @F(%T.loc13_6.1, %U.loc13_16.1) [symbolic = %F.specific_fn.loc13_67.2 (constants.%F.specific_fn.e58)]
 // CHECK:STDOUT:
@@ -665,7 +665,7 @@ fn G() -> i32 {
 // CHECK:STDOUT:   %pattern_type.loc13_48 => constants.%pattern_type.eee
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc13_48 => constants.%require_complete.220
+// CHECK:STDOUT:   %require_complete.loc13_56 => constants.%require_complete.220
 // CHECK:STDOUT:   %require_complete.loc13_27 => constants.%require_complete.6ae
 // CHECK:STDOUT:   %F.specific_fn.loc13_67.2 => constants.%F.specific_fn.e58
 // CHECK:STDOUT: }
@@ -698,7 +698,7 @@ fn G() -> i32 {
 // CHECK:STDOUT:   %pattern_type.loc13_48 => constants.%pattern_type.9ec
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc13_48 => constants.%complete_type.53b
+// CHECK:STDOUT:   %require_complete.loc13_56 => constants.%complete_type.53b
 // CHECK:STDOUT:   %require_complete.loc13_27 => constants.%complete_type.357
 // CHECK:STDOUT:   %F.specific_fn.loc13_67.2 => constants.%F.specific_fn.4a7
 // CHECK:STDOUT: }

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

@@ -176,7 +176,7 @@ fn G(pair: (C, D)) -> D {
 // CHECK:STDOUT:   %pattern_type.loc7_40: type = pattern_type %U.loc7_16.1 [symbolic = %pattern_type.loc7_40 (constants.%pattern_type.946)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc7_40: <witness> = require_complete_type %U.loc7_16.1 [symbolic = %require_complete.loc7_40 (constants.%require_complete.441)]
+// CHECK:STDOUT:   %require_complete.loc7_43: <witness> = require_complete_type %U.loc7_16.1 [symbolic = %require_complete.loc7_43 (constants.%require_complete.441)]
 // CHECK:STDOUT:   %require_complete.loc7_30: <witness> = require_complete_type %tuple.type [symbolic = %require_complete.loc7_30 (constants.%require_complete.220)]
 // CHECK:STDOUT:   %F.specific_fn.loc7_54.2: <specific function> = specific_function constants.%F, @F(%T.loc7_6.1, %U.loc7_16.1) [symbolic = %F.specific_fn.loc7_54.2 (constants.%F.specific_fn.e58)]
 // CHECK:STDOUT:
@@ -210,7 +210,7 @@ fn G(pair: (C, D)) -> D {
 // CHECK:STDOUT:   %pattern_type.loc7_40 => constants.%pattern_type.946
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc7_40 => constants.%require_complete.441
+// CHECK:STDOUT:   %require_complete.loc7_43 => constants.%require_complete.441
 // CHECK:STDOUT:   %require_complete.loc7_30 => constants.%require_complete.220
 // CHECK:STDOUT:   %F.specific_fn.loc7_54.2 => constants.%F.specific_fn.e58
 // CHECK:STDOUT: }
@@ -224,7 +224,7 @@ fn G(pair: (C, D)) -> D {
 // CHECK:STDOUT:   %pattern_type.loc7_40 => constants.%pattern_type.510
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc7_40 => constants.%complete_type.357
+// CHECK:STDOUT:   %require_complete.loc7_43 => constants.%complete_type.357
 // CHECK:STDOUT:   %require_complete.loc7_30 => constants.%complete_type.53b
 // CHECK:STDOUT:   %F.specific_fn.loc7_54.2 => constants.%F.specific_fn.4a7
 // CHECK:STDOUT: }

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

@@ -162,7 +162,7 @@ fn G(p: C*) -> const C {
 // CHECK:STDOUT:   %pattern_type.loc6_23: type = pattern_type %T.loc6_6.1 [symbolic = %pattern_type.loc6_23 (constants.%pattern_type.51d)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_23: <witness> = require_complete_type %T.loc6_6.1 [symbolic = %require_complete.loc6_23 (constants.%require_complete.944)]
+// CHECK:STDOUT:   %require_complete.loc6_26: <witness> = require_complete_type %T.loc6_6.1 [symbolic = %require_complete.loc6_26 (constants.%require_complete.944)]
 // 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:   %F.specific_fn.loc6_37.2: <specific function> = specific_function constants.%F, @F(%T.loc6_6.1) [symbolic = %F.specific_fn.loc6_37.2 (constants.%F.specific_fn.bb1)]
 // CHECK:STDOUT:
@@ -194,7 +194,7 @@ fn G(p: C*) -> const C {
 // CHECK:STDOUT:   %pattern_type.loc6_23 => constants.%pattern_type.51d
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_23 => constants.%require_complete.944
+// CHECK:STDOUT:   %require_complete.loc6_26 => constants.%require_complete.944
 // CHECK:STDOUT:   %require_complete.loc6_17 => constants.%require_complete.ef1
 // CHECK:STDOUT:   %F.specific_fn.loc6_37.2 => constants.%F.specific_fn.bb1
 // CHECK:STDOUT: }
@@ -206,7 +206,7 @@ fn G(p: C*) -> const C {
 // CHECK:STDOUT:   %pattern_type.loc6_23 => constants.%pattern_type.c48
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_23 => constants.%complete_type.357
+// CHECK:STDOUT:   %require_complete.loc6_26 => constants.%complete_type.357
 // CHECK:STDOUT:   %require_complete.loc6_17 => constants.%complete_type.d05
 // CHECK:STDOUT:   %F.specific_fn.loc6_37.2 => constants.%F.specific_fn.04a
 // CHECK:STDOUT: }
@@ -311,7 +311,7 @@ fn G(p: C*) -> const C {
 // CHECK:STDOUT:   %pattern_type.loc6_29: type = pattern_type %T.loc6_6.1 [symbolic = %pattern_type.loc6_29 (constants.%pattern_type.51d)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_29: <witness> = require_complete_type %T.loc6_6.1 [symbolic = %require_complete.loc6_29 (constants.%require_complete.944)]
+// CHECK:STDOUT:   %require_complete.loc6_32: <witness> = require_complete_type %T.loc6_6.1 [symbolic = %require_complete.loc6_32 (constants.%require_complete.944)]
 // 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:   %F.specific_fn.loc6_43.2: <specific function> = specific_function constants.%F, @F(%T.loc6_6.1) [symbolic = %F.specific_fn.loc6_43.2 (constants.%F.specific_fn.bb1)]
 // CHECK:STDOUT:
@@ -344,7 +344,7 @@ fn G(p: C*) -> const C {
 // CHECK:STDOUT:   %pattern_type.loc6_29 => constants.%pattern_type.51d
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_29 => constants.%require_complete.944
+// CHECK:STDOUT:   %require_complete.loc6_32 => constants.%require_complete.944
 // CHECK:STDOUT:   %require_complete.loc6_17 => constants.%require_complete.0c1
 // CHECK:STDOUT:   %F.specific_fn.loc6_43.2 => constants.%F.specific_fn.bb1
 // CHECK:STDOUT: }
@@ -357,7 +357,7 @@ fn G(p: C*) -> const C {
 // CHECK:STDOUT:   %pattern_type.loc6_29 => constants.%pattern_type.c48
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_29 => constants.%complete_type.357
+// CHECK:STDOUT:   %require_complete.loc6_32 => constants.%complete_type.357
 // CHECK:STDOUT:   %require_complete.loc6_17 => constants.%complete_type.247
 // CHECK:STDOUT:   %F.specific_fn.loc6_43.2 => constants.%F.specific_fn.04a
 // CHECK:STDOUT: }
@@ -460,7 +460,7 @@ fn G(p: C*) -> const C {
 // CHECK:STDOUT:   %pattern_type.loc6_23: type = pattern_type %T.loc6_6.1 [symbolic = %pattern_type.loc6_23 (constants.%pattern_type.51d)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_23: <witness> = require_complete_type %T.loc6_6.1 [symbolic = %require_complete.loc6_23 (constants.%require_complete.944)]
+// CHECK:STDOUT:   %require_complete.loc6_26: <witness> = require_complete_type %T.loc6_6.1 [symbolic = %require_complete.loc6_26 (constants.%require_complete.944)]
 // 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:   %F.specific_fn.loc6_37.2: <specific function> = specific_function constants.%F, @F(%T.loc6_6.1) [symbolic = %F.specific_fn.loc6_37.2 (constants.%F.specific_fn.bb1)]
 // CHECK:STDOUT:
@@ -492,7 +492,7 @@ fn G(p: C*) -> const C {
 // CHECK:STDOUT:   %pattern_type.loc6_23 => constants.%pattern_type.51d
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_23 => constants.%require_complete.944
+// CHECK:STDOUT:   %require_complete.loc6_26 => constants.%require_complete.944
 // CHECK:STDOUT:   %require_complete.loc6_17 => constants.%require_complete.ef1
 // CHECK:STDOUT:   %F.specific_fn.loc6_37.2 => constants.%F.specific_fn.bb1
 // CHECK:STDOUT: }
@@ -504,7 +504,7 @@ fn G(p: C*) -> const C {
 // CHECK:STDOUT:   %pattern_type.loc6_23 => constants.%pattern_type.6af
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_23 => constants.%complete_type.357
+// CHECK:STDOUT:   %require_complete.loc6_26 => constants.%complete_type.357
 // CHECK:STDOUT:   %require_complete.loc6_17 => constants.%complete_type.247
 // CHECK:STDOUT:   %F.specific_fn.loc6_37.2 => constants.%F.specific_fn.486
 // CHECK:STDOUT: }
@@ -607,7 +607,7 @@ fn G(p: C*) -> const C {
 // CHECK:STDOUT:   %pattern_type.loc6_29: type = pattern_type %T.loc6_6.1 [symbolic = %pattern_type.loc6_29 (constants.%pattern_type.51d)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_29: <witness> = require_complete_type %T.loc6_6.1 [symbolic = %require_complete.loc6_29 (constants.%require_complete.944)]
+// CHECK:STDOUT:   %require_complete.loc6_32: <witness> = require_complete_type %T.loc6_6.1 [symbolic = %require_complete.loc6_32 (constants.%require_complete.944)]
 // 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:   %F.specific_fn.loc6_43.2: <specific function> = specific_function constants.%F, @F(%T.loc6_6.1) [symbolic = %F.specific_fn.loc6_43.2 (constants.%F.specific_fn)]
 // CHECK:STDOUT:
@@ -637,7 +637,7 @@ fn G(p: C*) -> const C {
 // CHECK:STDOUT:   %pattern_type.loc6_29 => constants.%pattern_type.51d
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_29 => constants.%require_complete.944
+// CHECK:STDOUT:   %require_complete.loc6_32 => constants.%require_complete.944
 // CHECK:STDOUT:   %require_complete.loc6_17 => constants.%require_complete.0c1
 // CHECK:STDOUT:   %F.specific_fn.loc6_43.2 => constants.%F.specific_fn
 // CHECK:STDOUT: }

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

@@ -486,7 +486,7 @@ fn Read(y:! Core.IntLiteral()) {
 // CHECK:STDOUT:   %pattern_type.loc5_49: type = pattern_type %IntRange [symbolic = %pattern_type.loc5_49 (constants.%pattern_type.95e)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc5_49: <witness> = require_complete_type %IntRange [symbolic = %require_complete.loc5_49 (constants.%require_complete.852)]
+// CHECK:STDOUT:   %require_complete.loc5_52: <witness> = require_complete_type %IntRange [symbolic = %require_complete.loc5_52 (constants.%require_complete.852)]
 // 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:   %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.2: require_specific_def_type = require_specific_def @Int.as.Copy.impl(%N) [symbolic = %.loc6_22.2 (constants.%.2e8)]
@@ -570,7 +570,7 @@ fn Read(y:! Core.IntLiteral()) {
 // CHECK:STDOUT:   %pattern_type.loc11_47: type = pattern_type %Optional.loc11_75.1 [symbolic = %pattern_type.loc11_47 (constants.%pattern_type.ca4)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc11_47: <witness> = require_complete_type %Optional.loc11_75.1 [symbolic = %require_complete.loc11_47 (constants.%require_complete.0e6)]
+// CHECK:STDOUT:   %require_complete.loc11_75: <witness> = require_complete_type %Optional.loc11_75.1 [symbolic = %require_complete.loc11_75 (constants.%require_complete.0e6)]
 // CHECK:STDOUT:   %require_complete.loc11_17: <witness> = require_complete_type %IntRange [symbolic = %require_complete.loc11_17 (constants.%require_complete.852)]
 // 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.loc12: <witness> = require_complete_type %Int.loc11_43.1 [symbolic = %require_complete.loc12 (constants.%require_complete.9019d7.1)]
@@ -824,7 +824,7 @@ fn Read(y:! Core.IntLiteral()) {
 // CHECK:STDOUT:   %pattern_type.loc5_49 => constants.%pattern_type.d16
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc5_49 => constants.%complete_type.c45
+// CHECK:STDOUT:   %require_complete.loc5_52 => constants.%complete_type.c45
 // CHECK:STDOUT:   %require_complete.loc5_16 => constants.%complete_type.f8a
 // CHECK:STDOUT:   %struct_type.start.end => constants.%struct_type.start.end.d0a
 // CHECK:STDOUT:   %.loc6_22.2 => constants.%.0d3

+ 4 - 4
toolchain/check/testdata/function/builtin/call_from_operator.carbon

@@ -795,7 +795,7 @@ var arr: array(i32, (1 as i32) + (2 as i32)) = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   %Core.import_ref.966: @AddWith.%AddWith.type (%AddWith.type.552) = import_ref Core//default, loc{{\d+_\d+}}, loaded [symbolic = @AddWith.%Self (constants.%Self.3fe)]
 // CHECK:STDOUT:   %Core.import_ref.928 = import_ref Core//default, loc{{\d+_\d+}}, unloaded
 // CHECK:STDOUT:   %Core.import_ref.8af: <witness> = import_ref Core//default, loc{{\d+_\d+}}, loaded [concrete = constants.%AddWith.impl_witness]
-// CHECK:STDOUT:   %Core.import_ref.c8c7cd.1: type = import_ref Core//default, loc{{\d+_\d+}}, loaded [concrete = constants.%i32.builtin]
+// CHECK:STDOUT:   %Core.import_ref.c8c7cd.2: type = import_ref Core//default, loc{{\d+_\d+}}, loaded [concrete = constants.%i32.builtin]
 // CHECK:STDOUT:   %Core.import_ref.af3: type = import_ref Core//default, loc{{\d+_\d+}}, loaded [concrete = constants.%AddWith.type.2a3]
 // CHECK:STDOUT:   %Core.import_ref.980: %i32.builtin.as.AddWith.impl.Op.type = import_ref Core//default, loc{{\d+_\d+}}, loaded [concrete = constants.%i32.builtin.as.AddWith.impl.Op]
 // CHECK:STDOUT:   %AddWith.impl_witness_table = impl_witness_table (%Core.import_ref.980), @i32.builtin.as.AddWith.impl [concrete]
@@ -813,7 +813,7 @@ var arr: array(i32, (1 as i32) + (2 as i32)) = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   %Core.import_ref.8721d7.2: type = import_ref Core//default, loc{{\d+_\d+}}, loaded [concrete = Core.IntLiteral]
 // CHECK:STDOUT:   %Core.import_ref.64f: type = import_ref Core//default, loc{{\d+_\d+}}, loaded [concrete = constants.%ImplicitAs.type.873]
 // CHECK:STDOUT:   %Core.import_ref.614: <witness> = import_ref Core//default, loc{{\d+_\d+}}, loaded [concrete = constants.%ImplicitAs.impl_witness.fb8]
-// CHECK:STDOUT:   %Core.import_ref.c8c7cd.2: type = import_ref Core//default, loc{{\d+_\d+}}, loaded [concrete = constants.%i32.builtin]
+// CHECK:STDOUT:   %Core.import_ref.c8c7cd.3: type = import_ref Core//default, loc{{\d+_\d+}}, loaded [concrete = constants.%i32.builtin]
 // CHECK:STDOUT:   %Core.import_ref.d7b: type = import_ref Core//default, loc{{\d+_\d+}}, loaded [concrete = constants.%ImplicitAs.type.7a9]
 // CHECK:STDOUT:   %Core.import_ref.4ae: %i32.builtin.as.ImplicitAs.impl.Convert.type = import_ref Core//default, loc{{\d+_\d+}}, loaded [concrete = constants.%i32.builtin.as.ImplicitAs.impl.Convert]
 // CHECK:STDOUT:   %ImplicitAs.impl_witness_table.16d = impl_witness_table (%Core.import_ref.4ae), @i32.builtin.as.ImplicitAs.impl [concrete]
@@ -940,7 +940,7 @@ var arr: array(i32, (1 as i32) + (2 as i32)) = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   witness = imports.%Core.import_ref.931
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: impl @i32.builtin.as.AddWith.impl: imports.%Core.import_ref.c8c7cd.1 as imports.%Core.import_ref.af3 [from "core.carbon"] {
+// CHECK:STDOUT: impl @i32.builtin.as.AddWith.impl: imports.%Core.import_ref.c8c7cd.2 as imports.%Core.import_ref.af3 [from "core.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   witness = imports.%Core.import_ref.8af
 // CHECK:STDOUT: }
@@ -950,7 +950,7 @@ var arr: array(i32, (1 as i32) + (2 as i32)) = (3, 4, (3 as i32) + (4 as i32));
 // CHECK:STDOUT:   witness = imports.%Core.import_ref.8a9
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: impl @i32.builtin.as.ImplicitAs.impl: imports.%Core.import_ref.c8c7cd.2 as imports.%Core.import_ref.d7b [from "core.carbon"] {
+// CHECK:STDOUT: impl @i32.builtin.as.ImplicitAs.impl: imports.%Core.import_ref.c8c7cd.3 as imports.%Core.import_ref.d7b [from "core.carbon"] {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   witness = imports.%Core.import_ref.614
 // 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]]:18: note: return type declared here [IncompleteReturnTypeHere]
+  // CHECK:STDERR: fail_incomplete_return.carbon:[[@LINE-11]]:21: 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]]:18: note: return type declared here [IncompleteReturnTypeHere]
+  // CHECK:STDERR: fail_incomplete_return.carbon:[[@LINE-20]]:21: 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:20: note: return type declared here [IncompleteReturnTypeHere]
+  // CHECK:STDERR: fail_incomplete_return.carbon:7:23: 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:18: note: return type declared here [IncompleteReturnTypeHere]
+  // CHECK:STDERR: fail_incomplete_return.carbon:8:21: 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/generic/deduce.carbon

@@ -602,7 +602,7 @@ fn F() {
 // CHECK:STDOUT:   %pattern_type.loc6_43: type = pattern_type %ptr.loc6_47.1 [symbolic = %pattern_type.loc6_43 (constants.%pattern_type.4f4)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// 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:   %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_38: <witness> = require_complete_type %T.loc6_27.1 [symbolic = %require_complete.loc6_38 (constants.%require_complete.944)]
 // CHECK:STDOUT:   %ExplicitAndAlsoDeduced.specific_fn.loc7_10.2: <specific function> = specific_function constants.%ExplicitAndAlsoDeduced, @ExplicitAndAlsoDeduced(%T.loc6_27.1) [symbolic = %ExplicitAndAlsoDeduced.specific_fn.loc7_10.2 (constants.%ExplicitAndAlsoDeduced.specific_fn.4c1)]
 // CHECK:STDOUT:
@@ -643,7 +643,7 @@ fn F() {
 // CHECK:STDOUT:   %pattern_type.loc6_43 => constants.%pattern_type.4f4
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_43 => constants.%require_complete.ef1
+// CHECK:STDOUT:   %require_complete.loc6_47 => constants.%require_complete.ef1
 // CHECK:STDOUT:   %require_complete.loc6_38 => constants.%require_complete.944
 // CHECK:STDOUT:   %ExplicitAndAlsoDeduced.specific_fn.loc7_10.2 => constants.%ExplicitAndAlsoDeduced.specific_fn.4c1
 // CHECK:STDOUT: }
@@ -655,7 +655,7 @@ fn F() {
 // CHECK:STDOUT:   %pattern_type.loc6_43 => constants.%pattern_type.5f8
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_43 => constants.%complete_type.7ea
+// CHECK:STDOUT:   %require_complete.loc6_47 => constants.%complete_type.7ea
 // CHECK:STDOUT:   %require_complete.loc6_38 => constants.%complete_type.357
 // CHECK:STDOUT:   %ExplicitAndAlsoDeduced.specific_fn.loc7_10.2 => constants.%ExplicitAndAlsoDeduced.specific_fn.720
 // CHECK:STDOUT: }
@@ -750,7 +750,7 @@ fn F() {
 // CHECK:STDOUT:   %pattern_type.loc4_41: type = pattern_type %ptr.loc4_45.1 [symbolic = %pattern_type.loc4_41 (constants.%pattern_type.4f4)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// 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:   %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_36: <witness> = require_complete_type %T.loc4_25.1 [symbolic = %require_complete.loc4_36 (constants.%require_complete.944)]
 // CHECK:STDOUT:   %ImplicitGenericParam.specific_fn.loc4_56.2: <specific function> = specific_function constants.%ImplicitGenericParam, @ImplicitGenericParam(%T.loc4_25.1) [symbolic = %ImplicitGenericParam.specific_fn.loc4_56.2 (constants.%ImplicitGenericParam.specific_fn.47c)]
 // CHECK:STDOUT:
@@ -780,7 +780,7 @@ fn F() {
 // CHECK:STDOUT:   %pattern_type.loc4_41 => constants.%pattern_type.4f4
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc4_41 => constants.%require_complete.ef1
+// CHECK:STDOUT:   %require_complete.loc4_45 => constants.%require_complete.ef1
 // CHECK:STDOUT:   %require_complete.loc4_36 => constants.%require_complete.944
 // CHECK:STDOUT:   %ImplicitGenericParam.specific_fn.loc4_56.2 => constants.%ImplicitGenericParam.specific_fn.47c
 // CHECK:STDOUT: }
@@ -792,7 +792,7 @@ fn F() {
 // CHECK:STDOUT:   %pattern_type.loc4_41 => constants.%pattern_type.fe8
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc4_41 => constants.%complete_type.3d0
+// CHECK:STDOUT:   %require_complete.loc4_45 => constants.%complete_type.3d0
 // CHECK:STDOUT:   %require_complete.loc4_36 => constants.%complete_type.f8a
 // CHECK:STDOUT:   %ImplicitGenericParam.specific_fn.loc4_56.2 => constants.%ImplicitGenericParam.specific_fn.752
 // CHECK:STDOUT: }

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

@@ -88,7 +88,7 @@ fn F(template T:! type, U:! type) -> (T, U) {
 // CHECK:STDOUT:   %pattern_type.loc5_33: type = pattern_type %ptr.loc5_29.1 [template = %pattern_type.loc5_33 (constants.%pattern_type.4f4b84.1)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// 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:   %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_26: <witness> = require_complete_type %ptr.loc5_30.1 [template = %require_complete.loc5_26 (constants.%require_complete.fbe)]
 // CHECK:STDOUT:   %.loc6_10.4: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc5_15.1) [template = %.loc6_10.4 (constants.%.841)]
 // 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)]

+ 8 - 0
toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon

@@ -639,6 +639,7 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT:     %return.param: ref bool = out_param call_param1
 // CHECK:STDOUT:     %return: ref bool = return_slot %return.param
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   %.loc103: type = specific_constant @J.F.%.loc103_44.2, @J.F(constants.%J.facet.b0a) [concrete = bool]
 // CHECK:STDOUT:   %FMissingParam.as.J.impl.F.decl.loc117_31.2: %FMissingParam.as.J.impl.F.type.45f670.2 = fn_decl @FMissingParam.as.J.impl.F.loc117_31.2 [concrete = constants.%FMissingParam.as.J.impl.F.300f33.2] {
 // CHECK:STDOUT:     %self.patt: %pattern_type.831 = value_binding_pattern self [concrete]
 // CHECK:STDOUT:     %self.param_patt: %pattern_type.831 = value_param_pattern %self.patt, call_param0 [concrete]
@@ -680,6 +681,7 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT:     %return.param: ref bool = out_param call_param1
 // CHECK:STDOUT:     %return: ref bool = return_slot %return.param
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   %.loc103: type = specific_constant @J.F.%.loc103_44.2, @J.F(constants.%J.facet.2cb) [concrete = bool]
 // CHECK:STDOUT:   %FMissingImplicitParam.as.J.impl.F.decl.loc130_26.2: %FMissingImplicitParam.as.J.impl.F.type.1eb171.2 = fn_decl @FMissingImplicitParam.as.J.impl.F.loc130_26.2 [concrete = constants.%FMissingImplicitParam.as.J.impl.F.f3d16f.2] {
 // CHECK:STDOUT:     %self.patt: %pattern_type.831 = value_binding_pattern self [concrete]
 // CHECK:STDOUT:     %self.param_patt: %pattern_type.831 = value_param_pattern %self.patt, call_param0 [concrete]
@@ -723,6 +725,7 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %b: bool = value_binding b, %b.param
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   %.loc103: type = specific_constant @J.F.%.loc103_44.2, @J.F(constants.%J.facet.92c) [concrete = bool]
 // CHECK:STDOUT:   %FMissingReturnType.as.J.impl.F.decl.loc152_30.2: %FMissingReturnType.as.J.impl.F.type.2c3eb9.2 = fn_decl @FMissingReturnType.as.J.impl.F.loc152_30.2 [concrete = constants.%FMissingReturnType.as.J.impl.F.405ae3.2] {
 // CHECK:STDOUT:     %self.patt: %pattern_type.831 = value_binding_pattern self [concrete]
 // CHECK:STDOUT:     %self.param_patt: %pattern_type.831 = value_param_pattern %self.patt, call_param0 [concrete]
@@ -769,6 +772,7 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT:     %return.param: ref bool = out_param call_param2
 // CHECK:STDOUT:     %return: ref bool = return_slot %return.param
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   %.loc103: type = specific_constant @J.F.%.loc103_44.2, @J.F(constants.%J.facet.bad) [concrete = bool]
 // CHECK:STDOUT:   %FDifferentParamType.as.J.impl.F.decl.loc171_38.2: %FDifferentParamType.as.J.impl.F.type.30a936.2 = fn_decl @FDifferentParamType.as.J.impl.F.loc171_38.2 [concrete = constants.%FDifferentParamType.as.J.impl.F.0ea197.2] {
 // CHECK:STDOUT:     %self.patt: %pattern_type.831 = value_binding_pattern self [concrete]
 // CHECK:STDOUT:     %self.param_patt: %pattern_type.831 = value_param_pattern %self.patt, call_param0 [concrete]
@@ -815,6 +819,7 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT:     %return.param: ref bool = out_param call_param2
 // CHECK:STDOUT:     %return: ref bool = return_slot %return.param
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   %.loc103: type = specific_constant @J.F.%.loc103_44.2, @J.F(constants.%J.facet.923) [concrete = bool]
 // CHECK:STDOUT:   %FDifferentImplicitParamType.as.J.impl.F.decl.loc184_38.2: %FDifferentImplicitParamType.as.J.impl.F.type.ac79c6.2 = fn_decl @FDifferentImplicitParamType.as.J.impl.F.loc184_38.2 [concrete = constants.%FDifferentImplicitParamType.as.J.impl.F.3caa22.2] {
 // CHECK:STDOUT:     %self.patt: %pattern_type.831 = value_binding_pattern self [concrete]
 // CHECK:STDOUT:     %self.param_patt: %pattern_type.831 = value_param_pattern %self.patt, call_param0 [concrete]
@@ -863,6 +868,7 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT:     %return.param: ref %FDifferentReturnType = out_param call_param2
 // CHECK:STDOUT:     %return: ref %FDifferentReturnType = return_slot %return.param
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   %.loc103: type = specific_constant @J.F.%.loc103_44.2, @J.F(constants.%J.facet.a25) [concrete = bool]
 // CHECK:STDOUT:   %FDifferentReturnType.as.J.impl.F.decl.loc200_38.2: %FDifferentReturnType.as.J.impl.F.type.3243f4.2 = fn_decl @FDifferentReturnType.as.J.impl.F.loc200_38.2 [concrete = constants.%FDifferentReturnType.as.J.impl.F.e4a0b7.2] {
 // CHECK:STDOUT:     %self.patt: %pattern_type.831 = value_binding_pattern self [concrete]
 // CHECK:STDOUT:     %self.param_patt: %pattern_type.831 = value_param_pattern %self.patt, call_param0 [concrete]
@@ -910,6 +916,7 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT:     %return.param: ref %array_type.a41 = out_param call_param1
 // CHECK:STDOUT:     %return: ref %array_type.a41 = return_slot %return.param
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   %.loc211: type = specific_constant @SelfNested.F.%array_type.loc211_57.2, @SelfNested.F(constants.%SelfNested.facet.182) [concrete = constants.%array_type.a41]
 // CHECK:STDOUT:   %SelfNestedBadParam.as.SelfNested.impl.F.decl.loc223_87.2: %SelfNestedBadParam.as.SelfNested.impl.F.type.56b7c1.2 = fn_decl @SelfNestedBadParam.as.SelfNested.impl.F.loc223_87.2 [concrete = constants.%SelfNestedBadParam.as.SelfNested.impl.F.72ff49.2] {
 // CHECK:STDOUT:     %x.patt: %pattern_type.a5c = value_binding_pattern x [concrete]
 // CHECK:STDOUT:     %x.param_patt: %pattern_type.a5c = value_param_pattern %x.patt, call_param0 [concrete]
@@ -953,6 +960,7 @@ class SelfNestedBadReturnType {
 // CHECK:STDOUT:     %return.param: ref %array_type.a41 = out_param call_param1
 // CHECK:STDOUT:     %return: ref %array_type.a41 = return_slot %return.param
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   %.loc211: type = specific_constant @SelfNested.F.%array_type.loc211_57.2, @SelfNested.F(constants.%SelfNested.facet.55d) [concrete = constants.%array_type.126]
 // CHECK:STDOUT:   %SelfNestedBadReturnType.as.SelfNested.impl.F.decl.loc239_112.2: %SelfNestedBadReturnType.as.SelfNested.impl.F.type.054b04.2 = fn_decl @SelfNestedBadReturnType.as.SelfNested.impl.F.loc239_112.2 [concrete = constants.%SelfNestedBadReturnType.as.SelfNested.impl.F.abc7a8.2] {
 // CHECK:STDOUT:     %x.patt: %pattern_type.23f = value_binding_pattern x [concrete]
 // CHECK:STDOUT:     %x.param_patt: %pattern_type.23f = value_param_pattern %x.patt, call_param0 [concrete]

+ 8 - 0
toolchain/check/testdata/impl/impl_thunk.carbon

@@ -374,6 +374,7 @@ impl () as I({}) {
 // CHECK:STDOUT:     %return.param: ref %struct_type.d.c.b36 = out_param call_param1
 // CHECK:STDOUT:     %return: ref %struct_type.d.c.b36 = return_slot %return.param
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   <elided>
 // CHECK:STDOUT:   %empty_tuple.type.as.I.impl.F.decl.loc10_48.2: %empty_tuple.type.as.I.impl.F.type.e6fdf8.2 = fn_decl @empty_tuple.type.as.I.impl.F.loc10_48.2 [concrete = constants.%empty_tuple.type.as.I.impl.F.f1aebb.2] {
 // CHECK:STDOUT:     <elided>
 // CHECK:STDOUT:   } {
@@ -469,6 +470,7 @@ impl () as I({}) {
 // CHECK:STDOUT:     %return.param: ref %ptr.019 = out_param call_param2
 // CHECK:STDOUT:     %return: ref %ptr.019 = return_slot %return.param
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   <elided>
 // CHECK:STDOUT:   %B.as.X.impl.F.decl.loc14_37.2: %B.as.X.impl.F.type.84a1c2.2 = fn_decl @B.as.X.impl.F.loc14_37.2 [concrete = constants.%B.as.X.impl.F.b849c8.2] {
 // CHECK:STDOUT:     <elided>
 // CHECK:STDOUT:   } {
@@ -616,6 +618,7 @@ impl () as I({}) {
 // CHECK:STDOUT:     %return.param: ref %ptr.019 = out_param call_param2
 // CHECK:STDOUT:     %return: ref %ptr.019 = return_slot %return.param
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   <elided>
 // CHECK:STDOUT:   %B.as.X.impl.F.decl.loc14_37.2: %B.as.X.impl.F.type.84a1c2.2 = fn_decl @B.as.X.impl.F.loc14_37.2 [concrete = constants.%B.as.X.impl.F.b849c8.2] {
 // CHECK:STDOUT:     <elided>
 // CHECK:STDOUT:   } {
@@ -709,6 +712,7 @@ impl () as I({}) {
 // CHECK:STDOUT:     %return.param: ref %ptr.019 = out_param call_param2
 // CHECK:STDOUT:     %return: ref %ptr.019 = return_slot %return.param
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   <elided>
 // CHECK:STDOUT:   %B.as.X.impl.F.decl.loc14_37.2: %B.as.X.impl.F.type.84a1c2.2 = fn_decl @B.as.X.impl.F.loc14_37.2 [concrete = constants.%B.as.X.impl.F.b849c8.2] {
 // CHECK:STDOUT:     <elided>
 // CHECK:STDOUT:   } {
@@ -774,6 +778,7 @@ impl () as I({}) {
 // CHECK:STDOUT:     %return.param: ref %B = out_param call_param0
 // CHECK:STDOUT:     %return: ref %B = return_slot %return.param
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   <elided>
 // CHECK:STDOUT:   %A.as.X.impl.F.decl.loc23_14.2: %A.as.X.impl.F.type.dc7bda.2 = fn_decl @A.as.X.impl.F.loc23_14.2 [concrete = constants.%A.as.X.impl.F.0afbb1.2] {
 // CHECK:STDOUT:     <elided>
 // CHECK:STDOUT:   } {
@@ -872,6 +877,7 @@ impl () as I({}) {
 // CHECK:STDOUT:     %return.param: ref @empty_tuple.type.as.I.impl.F.loc10_34.1.%U.binding.as_type (%U.binding.as_type.e5b) = out_param call_param1
 // CHECK:STDOUT:     %return: ref @empty_tuple.type.as.I.impl.F.loc10_34.1.%U.binding.as_type (%U.binding.as_type.e5b) = return_slot %return.param
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   <elided>
 // CHECK:STDOUT:   %empty_tuple.type.as.I.impl.F.decl.loc10_34.2: %empty_tuple.type.as.I.impl.F.type.e6fdf8.2 = fn_decl @empty_tuple.type.as.I.impl.F.loc10_34.2 [concrete = constants.%empty_tuple.type.as.I.impl.F.f1aebb.2] {
 // CHECK:STDOUT:     <elided>
 // CHECK:STDOUT:   } {
@@ -1035,6 +1041,7 @@ impl () as I({}) {
 // CHECK:STDOUT:     %return.param: ref @empty_tuple.type.as.I.impl.F.loc10_44.1.%U.binding.as_type (%U.binding.as_type.e5b) = out_param call_param2
 // CHECK:STDOUT:     %return: ref @empty_tuple.type.as.I.impl.F.loc10_44.1.%U.binding.as_type (%U.binding.as_type.e5b) = return_slot %return.param
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   <elided>
 // CHECK:STDOUT:   %empty_tuple.type.as.I.impl.F.decl.loc10_44.2: %empty_tuple.type.as.I.impl.F.type.e6fdf8.2 = fn_decl @empty_tuple.type.as.I.impl.F.loc10_44.2 [concrete = constants.%empty_tuple.type.as.I.impl.F.f1aebb.2] {
 // CHECK:STDOUT:     <elided>
 // CHECK:STDOUT:   } {
@@ -1158,6 +1165,7 @@ impl () as I({}) {
 // CHECK:STDOUT:     %return.param: ref %struct_type.b.a.1b0 = out_param call_param0
 // CHECK:STDOUT:     %return: ref %struct_type.b.a.1b0 = return_slot %return.param
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   <elided>
 // CHECK:STDOUT:   %empty_tuple.type.as.I.impl.F.decl.loc10_29.2: %empty_tuple.type.as.I.impl.F.type.109800.2 = fn_decl @empty_tuple.type.as.I.impl.F.loc10_29.2 [concrete = constants.%empty_tuple.type.as.I.impl.F.3e8bab.2] {
 // CHECK:STDOUT:     <elided>
 // CHECK:STDOUT:   } {

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

@@ -478,7 +478,7 @@ var n: Int(64) = MakeFromClass(FromLiteral(64) as OtherInt);
 // CHECK:STDOUT:   %Main.import_ref.b31: @MyInt.as.Add.impl.%MyInt.as.Add.impl.Op.type (%MyInt.as.Add.impl.Op.type.72f) = import_ref Main//generic_impl, loc16_42, loaded [symbolic = @MyInt.as.Add.impl.%MyInt.as.Add.impl.Op (constants.%MyInt.as.Add.impl.Op.cfb)]
 // CHECK:STDOUT:   %Add.impl_witness_table = impl_witness_table (%Main.import_ref.b31), @MyInt.as.Add.impl [concrete]
 // CHECK:STDOUT:   %Main.import_ref.6b552a.3: Core.IntLiteral = import_ref Main//generic_impl, loc15_14, loaded [symbolic = @MyInt.as.Add.impl.%N (constants.%N)]
-// CHECK:STDOUT:   %Main.import_ref.99b: type = import_ref Main//generic_impl, loc15_39, loaded [symbolic = @MyInt.as.Add.impl.%MyInt (constants.%MyInt.819)]
+// CHECK:STDOUT:   %Main.import_ref.99b8a4.2: type = import_ref Main//generic_impl, loc15_39, loaded [symbolic = @MyInt.as.Add.impl.%MyInt (constants.%MyInt.819)]
 // CHECK:STDOUT:   %Main.import_ref.bf0: type = import_ref Main//generic_impl, loc15_44, loaded [concrete = constants.%Add.type]
 // CHECK:STDOUT:   %Main.import_ref.6b552a.4: Core.IntLiteral = import_ref Main//generic_impl, loc15_14, loaded [symbolic = @MyInt.as.Add.impl.%N (constants.%N)]
 // CHECK:STDOUT: }
@@ -533,7 +533,7 @@ var n: Int(64) = MakeFromClass(FromLiteral(64) as OtherInt);
 // CHECK:STDOUT:   %MyInt.as.Add.impl.Op: @MyInt.as.Add.impl.%MyInt.as.Add.impl.Op.type (%MyInt.as.Add.impl.Op.type.72f) = struct_value () [symbolic = %MyInt.as.Add.impl.Op (constants.%MyInt.as.Add.impl.Op.cfb)]
 // CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %MyInt [symbolic = %require_complete (constants.%require_complete.855)]
 // CHECK:STDOUT:
-// CHECK:STDOUT:   impl: imports.%Main.import_ref.99b as imports.%Main.import_ref.bf0 {
+// CHECK:STDOUT:   impl: imports.%Main.import_ref.99b8a4.2 as imports.%Main.import_ref.bf0 {
 // CHECK:STDOUT:   !members:
 // CHECK:STDOUT:     witness = imports.%Main.import_ref.42e
 // CHECK:STDOUT:   }

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

@@ -189,7 +189,7 @@ fn TestSpecific(a: A({})*) -> {}* {
 // CHECK:STDOUT:   %pattern_type.loc13_26: type = pattern_type %ptr.loc13_30.1 [symbolic = %pattern_type.loc13_26 (constants.%pattern_type.4f4b84.2)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// 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:   %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_16: <witness> = require_complete_type %A [symbolic = %require_complete.loc13_16 (constants.%require_complete.a096cd.1)]
 // CHECK:STDOUT:   %A.elem: type = unbound_element_type %A, %V [symbolic = %A.elem (constants.%A.elem.b1fb46.2)]
 // CHECK:STDOUT:   %.loc14_12.2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%V) [symbolic = %.loc14_12.2 (constants.%.841)]
@@ -329,7 +329,7 @@ fn TestSpecific(a: A({})*) -> {}* {
 // CHECK:STDOUT:   %pattern_type.loc13_26 => constants.%pattern_type.1cc
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc13_26 => constants.%complete_type.38e
+// CHECK:STDOUT:   %require_complete.loc13_30 => constants.%complete_type.38e
 // CHECK:STDOUT:   %require_complete.loc13_16 => constants.%complete_type.0a6
 // CHECK:STDOUT:   %A.elem => constants.%A.elem.2af
 // CHECK:STDOUT:   %.loc14_12.2 => constants.%.a00

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

@@ -924,7 +924,7 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) {
 // CHECK:STDOUT:   %pattern_type.loc9_26: type = pattern_type %ptr [symbolic = %pattern_type.loc9_26 (constants.%pattern_type.4f4)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc9_26: <witness> = require_complete_type %ptr [symbolic = %require_complete.loc9_26 (constants.%require_complete.ef1)]
+// 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_16: <witness> = require_complete_type %T.loc9_6.1 [symbolic = %require_complete.loc9_16 (constants.%require_complete.944)]
 // CHECK:STDOUT:   %.loc10_10.2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc9_6.1) [symbolic = %.loc10_10.2 (constants.%.841)]
 // CHECK:STDOUT:   %Copy.lookup_impl_witness: <witness> = lookup_impl_witness %ptr, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.2e6)]
@@ -1136,7 +1136,7 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) {
 // CHECK:STDOUT:   %pattern_type.loc9_25: type = pattern_type %ptr [symbolic = %pattern_type.loc9_25 (constants.%pattern_type.cd0)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc9_25: <witness> = require_complete_type %ptr [symbolic = %require_complete.loc9_25 (constants.%require_complete.861)]
+// CHECK:STDOUT:   %require_complete.loc9_29: <witness> = require_complete_type %ptr [symbolic = %require_complete.loc9_29 (constants.%require_complete.861)]
 // CHECK:STDOUT:   %require_complete.loc9_15: <witness> = require_complete_type %T.binding.as_type [symbolic = %require_complete.loc9_15 (constants.%require_complete.46d)]
 // CHECK:STDOUT:   %.loc10_10.2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.binding.as_type) [symbolic = %.loc10_10.2 (constants.%.763)]
 // CHECK:STDOUT:   %Copy.lookup_impl_witness: <witness> = lookup_impl_witness %ptr, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.b92)]
@@ -1347,7 +1347,7 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) {
 // CHECK:STDOUT:   %pattern_type.loc9_25: type = pattern_type %ptr [symbolic = %pattern_type.loc9_25 (constants.%pattern_type.cd0)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc9_25: <witness> = require_complete_type %ptr [symbolic = %require_complete.loc9_25 (constants.%require_complete.861)]
+// CHECK:STDOUT:   %require_complete.loc9_29: <witness> = require_complete_type %ptr [symbolic = %require_complete.loc9_29 (constants.%require_complete.861)]
 // CHECK:STDOUT:   %require_complete.loc9_15: <witness> = require_complete_type %T.binding.as_type [symbolic = %require_complete.loc9_15 (constants.%require_complete.46d)]
 // CHECK:STDOUT:   %.loc10_10.2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.binding.as_type) [symbolic = %.loc10_10.2 (constants.%.763)]
 // CHECK:STDOUT:   %Copy.lookup_impl_witness: <witness> = lookup_impl_witness %ptr, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.b92)]

+ 8 - 4
toolchain/check/testdata/impl/use_assoc_entity.carbon

@@ -1465,7 +1465,7 @@ fn F() {
 // CHECK:STDOUT:   %pattern_type.loc28_30: type = pattern_type %impl.elem0.loc28_34.1 [symbolic = %pattern_type.loc28_30 (constants.%pattern_type.36e)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc28_38: <witness> = require_complete_type %impl.elem0.loc28_34.1 [symbolic = %require_complete.loc28_38 (constants.%require_complete.4ce)]
+// CHECK:STDOUT:   %require_complete.loc28_42: <witness> = require_complete_type %impl.elem0.loc28_34.1 [symbolic = %require_complete.loc28_42 (constants.%require_complete.4ce)]
 // CHECK:STDOUT:   %require_complete.loc28_25: <witness> = require_complete_type %T.binding.as_type [symbolic = %require_complete.loc28_25 (constants.%require_complete.dfc)]
 // CHECK:STDOUT:   %.loc29_11: type = fn_type_with_self_type constants.%J.F.type, %T.loc28_17.1 [symbolic = %.loc29_11 (constants.%.2e3)]
 // CHECK:STDOUT:   %impl.elem1.loc29_11.2: @GenericCallF.%.loc29_11 (%.2e3) = impl_witness_access %J.lookup_impl_witness, element1 [symbolic = %impl.elem1.loc29_11.2 (constants.%impl.elem1)]
@@ -1568,7 +1568,7 @@ fn F() {
 // CHECK:STDOUT:   %pattern_type.loc28_30 => constants.%pattern_type.7ce
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc28_38 => constants.%complete_type.f8a
+// CHECK:STDOUT:   %require_complete.loc28_42 => constants.%complete_type.f8a
 // CHECK:STDOUT:   %require_complete.loc28_25 => constants.%complete_type.357
 // CHECK:STDOUT:   %.loc29_11 => constants.%.4bf
 // CHECK:STDOUT:   %impl.elem1.loc29_11.2 => constants.%E.as.J.impl.F
@@ -1807,7 +1807,7 @@ fn F() {
 // CHECK:STDOUT:   %pattern_type.loc12_31: type = pattern_type %as_type.loc12_35.1 [symbolic = %pattern_type.loc12_31 (constants.%pattern_type.aaa)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc12_39: <witness> = require_complete_type %as_type.loc12_35.1 [symbolic = %require_complete.loc12_39 (constants.%require_complete.cf1)]
+// CHECK:STDOUT:   %require_complete.loc12_43: <witness> = require_complete_type %as_type.loc12_35.1 [symbolic = %require_complete.loc12_43 (constants.%require_complete.cf1)]
 // CHECK:STDOUT:   %require_complete.loc12_26: <witness> = require_complete_type %T.binding.as_type [symbolic = %require_complete.loc12_26 (constants.%require_complete.dfc)]
 // CHECK:STDOUT:   %.loc13_11: type = fn_type_with_self_type constants.%J.F.type, %T.loc12_18.1 [symbolic = %.loc13_11 (constants.%.2e3)]
 // CHECK:STDOUT:   %impl.elem1.loc13_11.2: @GenericResult.%.loc13_11 (%.2e3) = impl_witness_access %J.lookup_impl_witness, element1 [symbolic = %impl.elem1.loc13_11.2 (constants.%impl.elem1)]
@@ -2071,7 +2071,7 @@ fn F() {
 // CHECK:STDOUT:   %pattern_type.loc8_47: type = pattern_type %impl.elem0.loc8_51.1 [symbolic = %pattern_type.loc8_47 (constants.%pattern_type.36e)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc8_55: <witness> = require_complete_type %impl.elem0.loc8_51.1 [symbolic = %require_complete.loc8_55 (constants.%require_complete.4ce)]
+// CHECK:STDOUT:   %require_complete.loc8_59: <witness> = require_complete_type %impl.elem0.loc8_51.1 [symbolic = %require_complete.loc8_59 (constants.%require_complete.4ce)]
 // CHECK:STDOUT:   %require_complete.loc8_42: <witness> = require_complete_type %T.binding.as_type [symbolic = %require_complete.loc8_42 (constants.%require_complete.dfc)]
 // CHECK:STDOUT:   %.loc9_11: type = fn_type_with_self_type constants.%J.G.type, %T.loc8_34.1 [symbolic = %.loc9_11 (constants.%.503)]
 // CHECK:STDOUT:   %impl.elem1.loc9_11.2: @GenericCallInterfaceQualified.%.loc9_11 (%.503) = impl_witness_access %J.lookup_impl_witness, element1 [symbolic = %impl.elem1.loc9_11.2 (constants.%impl.elem1)]
@@ -2454,6 +2454,7 @@ fn F() {
 // CHECK:STDOUT:     %return.param: ref <error> = out_param call_param1
 // CHECK:STDOUT:     %return: ref <error> = return_slot %return.param
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   %.loc5: type = specific_constant @J.F.%U.ref.loc5_17, @J.F(constants.%J.facet) [concrete = constants.%i32]
 // CHECK:STDOUT:   %E.as.J.impl.F.decl.loc27_21.2: %E.as.J.impl.F.type.0cf1cd.2 = fn_decl @E.as.J.impl.F.loc27_21.2 [concrete = constants.%E.as.J.impl.F.67c482.2] {
 // CHECK:STDOUT:     %u.patt: %pattern_type.7ce = value_binding_pattern u [concrete]
 // CHECK:STDOUT:     %u.param_patt: %pattern_type.7ce = value_param_pattern %u.patt, call_param0 [concrete]
@@ -3076,6 +3077,7 @@ fn F() {
 // CHECK:STDOUT:     %return.param: ref %empty_struct_type = out_param call_param2
 // CHECK:STDOUT:     %return: ref %empty_struct_type = return_slot %return.param
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   %.1: type = specific_constant <error>, @J2.F(constants.%J2.facet.360) [concrete = <error>]
 // CHECK:STDOUT:   %empty_tuple.type.as.J2.impl.F.decl.loc23_33.2: %empty_tuple.type.as.J2.impl.F.type.34cc4b.2 = fn_decl @empty_tuple.type.as.J2.impl.F.loc23_33.2 [concrete = constants.%empty_tuple.type.as.J2.impl.F.0c9bf6.2] {
 // CHECK:STDOUT:     %self.patt: %pattern_type.cb1 = value_binding_pattern self [concrete]
 // CHECK:STDOUT:     %self.param_patt: %pattern_type.cb1 = value_param_pattern %self.patt, call_param0 [concrete]
@@ -3114,6 +3116,7 @@ fn F() {
 // CHECK:STDOUT:     %return.param: ref %C2 = out_param call_param2
 // CHECK:STDOUT:     %return: ref %C2 = return_slot %return.param
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   %.1: type = specific_constant <error>, @J2.F(constants.%J2.facet.4cc) [concrete = <error>]
 // CHECK:STDOUT:   %C2.as.J2.impl.F.decl.loc32_33.2: %C2.as.J2.impl.F.type.5a5e13.2 = fn_decl @C2.as.J2.impl.F.loc32_33.2 [concrete = constants.%C2.as.J2.impl.F.b2fe8c.2] {
 // CHECK:STDOUT:     %self.patt: %pattern_type.838 = value_binding_pattern self [concrete]
 // CHECK:STDOUT:     %self.param_patt: %pattern_type.838 = value_param_pattern %self.patt, call_param0 [concrete]
@@ -3368,6 +3371,7 @@ fn F() {
 // CHECK:STDOUT:     %return.param: ref %struct_type.x = out_param call_param2
 // CHECK:STDOUT:     %return: ref %struct_type.x = return_slot %return.param
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   %.loc8: type = specific_constant @K.F.%V.ref.loc8_29, @K.F(constants.%K.facet) [concrete = constants.%struct_type.a]
 // CHECK:STDOUT:   %empty_tuple.type.as.K.impl.F.decl.loc26_45.2: %empty_tuple.type.as.K.impl.F.type.6dc3a4.2 = fn_decl @empty_tuple.type.as.K.impl.F.loc26_45.2 [concrete = constants.%empty_tuple.type.as.K.impl.F.360cfa.2] {
 // CHECK:STDOUT:     %self.patt: %pattern_type.cb1 = value_binding_pattern self [concrete]
 // CHECK:STDOUT:     %self.param_patt: %pattern_type.cb1 = value_param_pattern %self.patt, call_param0 [concrete]

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

@@ -346,7 +346,7 @@ fn Interface.C.F[self: Self](U:! type, u: U*) -> U* { return u; }
 // CHECK:STDOUT:   %pattern_type.loc14_32: type = pattern_type %ptr.loc14_36.1 [symbolic = %pattern_type.loc14_32 (constants.%pattern_type.423)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc20_47: <witness> = require_complete_type %ptr.loc14_36.1 [symbolic = %require_complete.loc20_47 (constants.%require_complete.56d)]
+// CHECK:STDOUT:   %require_complete.loc20_51: <witness> = require_complete_type %ptr.loc14_36.1 [symbolic = %require_complete.loc20_51 (constants.%require_complete.56d)]
 // CHECK:STDOUT:   %require_complete.loc20_22: <witness> = require_complete_type %C [symbolic = %require_complete.loc20_22 (constants.%require_complete.179)]
 // CHECK:STDOUT:   %.loc20_62.2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%U.loc14_22.1) [symbolic = %.loc20_62.2 (constants.%.2bd)]
 // CHECK:STDOUT:   %Copy.lookup_impl_witness: <witness> = lookup_impl_witness %ptr.loc14_36.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.484)]

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

@@ -405,7 +405,7 @@ fn CallIndirect() {
 // CHECK:STDOUT:   %pattern_type.loc16_25: type = pattern_type %tuple.type.loc16 [symbolic = %pattern_type.loc16_25 (constants.%pattern_type.ff2)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc16_25: <witness> = require_complete_type %tuple.type.loc16 [symbolic = %require_complete.loc16_25 (constants.%require_complete.7c8)]
+// CHECK:STDOUT:   %require_complete.loc16_37: <witness> = require_complete_type %tuple.type.loc16 [symbolic = %require_complete.loc16_37 (constants.%require_complete.7c8)]
 // 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:   %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.2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%U.loc16_8.1) [symbolic = %.loc17_21.2 (constants.%.841)]
@@ -606,7 +606,7 @@ fn CallIndirect() {
 // CHECK:STDOUT:   %pattern_type.loc16_25 => constants.%pattern_type.48d
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc16_25 => constants.%complete_type.05d
+// CHECK:STDOUT:   %require_complete.loc16_37 => constants.%complete_type.05d
 // CHECK:STDOUT:   %require_complete.loc16_19 => constants.%complete_type.d3e
 // CHECK:STDOUT:   %tuple.type.loc17 => constants.%tuple.type.953
 // CHECK:STDOUT:   %.loc17_21.2 => constants.%.519
@@ -1023,7 +1023,7 @@ fn CallIndirect() {
 // CHECK:STDOUT:   %pattern_type.loc17_24: type = pattern_type %tuple.type.loc17_42.2 [symbolic = %pattern_type.loc17_24 (constants.%pattern_type.5cc)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// 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:   %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_19: <witness> = require_complete_type %U.loc17_8.1 [symbolic = %require_complete.loc17_19 (constants.%require_complete.5a4)]
 // 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.52a)]
 // 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.52a) = struct_value () [symbolic = %tuple.type.as.A.impl.F (constants.%tuple.type.as.A.impl.F.b6b)]
@@ -1203,7 +1203,7 @@ fn CallIndirect() {
 // CHECK:STDOUT:   %pattern_type.loc17_24 => constants.%pattern_type.5cc
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc17_24 => constants.%require_complete.da0
+// CHECK:STDOUT:   %require_complete.loc17_42 => constants.%require_complete.da0
 // CHECK:STDOUT:   %require_complete.loc17_19 => constants.%require_complete.5a4
 // CHECK:STDOUT:   %tuple.type.as.A.impl.F.type => constants.%tuple.type.as.A.impl.F.type.52a
 // CHECK:STDOUT:   %tuple.type.as.A.impl.F => constants.%tuple.type.as.A.impl.F.b6b
@@ -1263,7 +1263,7 @@ fn CallIndirect() {
 // CHECK:STDOUT:   %pattern_type.loc17_24 => constants.%pattern_type.0b2
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc17_24 => constants.%complete_type.aa8
+// CHECK:STDOUT:   %require_complete.loc17_42 => constants.%complete_type.aa8
 // CHECK:STDOUT:   %require_complete.loc17_19 => constants.%complete_type.357
 // CHECK:STDOUT:   %tuple.type.as.A.impl.F.type => constants.%tuple.type.as.A.impl.F.type.172
 // CHECK:STDOUT:   %tuple.type.as.A.impl.F => constants.%tuple.type.as.A.impl.F.506

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

@@ -452,9 +452,9 @@ fn F() {
   // CHECK:STDERR: class C;
   // CHECK:STDERR:       ^
   // CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE-14]]:10: in file included here [InCppInclude]
-  // CHECK:STDERR: ./decl_value_return_type.h:4:1: note: return type declared here [IncompleteReturnTypeHere]
-  // CHECK:STDERR: auto foo() -> C;
-  // CHECK:STDERR: ^
+  // CHECK:STDERR: ./decl_value_return_type.h:2:7: note: return type declared here [IncompleteReturnTypeHere]
+  // CHECK:STDERR: class C;
+  // CHECK:STDERR:       ^
   // CHECK:STDERR:
   Cpp.foo();
 }

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

@@ -451,9 +451,9 @@ fn F() {
   // CHECK:STDERR: struct S;
   // CHECK:STDERR:        ^
   // CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE-14]]:10: in file included here [InCppInclude]
-  // CHECK:STDERR: ./decl_value_return_type.h:4:1: note: return type declared here [IncompleteReturnTypeHere]
-  // CHECK:STDERR: auto foo() -> S;
-  // CHECK:STDERR: ^
+  // CHECK:STDERR: ./decl_value_return_type.h:2:8: note: return type declared here [IncompleteReturnTypeHere]
+  // CHECK:STDERR: struct S;
+  // CHECK:STDERR:        ^
   // CHECK:STDERR:
   Cpp.foo();
 }

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

@@ -413,9 +413,9 @@ fn F() {
   // CHECK:STDERR: union U;
   // CHECK:STDERR:       ^
   // CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE-14]]:10: in file included here [InCppInclude]
-  // CHECK:STDERR: ./decl_value_return_type.h:4:1: note: return type declared here [IncompleteReturnTypeHere]
-  // CHECK:STDERR: auto foo() -> U;
-  // CHECK:STDERR: ^
+  // CHECK:STDERR: ./decl_value_return_type.h:2:7: note: return type declared here [IncompleteReturnTypeHere]
+  // CHECK:STDERR: union U;
+  // CHECK:STDERR:       ^
   // CHECK:STDERR:
   Cpp.foo();
 }

+ 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:8: note: return type declared here [IncompleteReturnTypeHere]
+// CHECK:STDERR: b.carbon:7:11: 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:8: note: return type declared here [IncompleteReturnTypeHere]
+// CHECK:STDERR: b.carbon:7:11: note: return type declared here [IncompleteReturnTypeHere]
 // CHECK:STDERR: fn F() -> A.C;
-// CHECK:STDERR:        ^~~~~~
+// CHECK:STDERR:           ^~~
 // CHECK:STDERR:
 fn G() { Same.F(); }
 

+ 2 - 2
toolchain/check/testdata/return/fail_returned_var_type.carbon

@@ -16,9 +16,9 @@ fn Mismatch() -> i32 {
   // CHECK:STDERR: fail_returned_var_type.carbon:[[@LINE+7]]:19: error: type `f64` of `returned var` does not match return type of enclosing function [ReturnedVarWrongType]
   // CHECK:STDERR:   returned var v: f64 = 0.0;
   // CHECK:STDERR:                   ^~~
-  // CHECK:STDERR: fail_returned_var_type.carbon:[[@LINE-4]]:15: note: return type of function is `i32` [ReturnTypeHereNote]
+  // CHECK:STDERR: fail_returned_var_type.carbon:[[@LINE-4]]:18: note: return type of function is `i32` [ReturnTypeHereNote]
   // CHECK:STDERR: fn Mismatch() -> i32 {
-  // CHECK:STDERR:               ^~~~~~
+  // CHECK:STDERR:                  ^~~
   // CHECK:STDERR:
   returned var v: f64 = 0.0;
   return var;

+ 2 - 2
toolchain/check/testdata/return/fail_value_missing.carbon

@@ -16,9 +16,9 @@ fn Main() -> i32 {
   // CHECK:STDERR: fail_value_missing.carbon:[[@LINE+7]]:3: error: missing return value [ReturnStatementMissingExpr]
   // CHECK:STDERR:   return;
   // CHECK:STDERR:   ^~~~~~~
-  // CHECK:STDERR: fail_value_missing.carbon:[[@LINE-4]]:11: note: return type of function is `i32` [ReturnTypeHereNote]
+  // CHECK:STDERR: fail_value_missing.carbon:[[@LINE-4]]:14: note: return type of function is `i32` [ReturnTypeHereNote]
   // CHECK:STDERR: fn Main() -> i32 {
-  // CHECK:STDERR:           ^~~~~~
+  // CHECK:STDERR:              ^~~
   // CHECK:STDERR:
   return;
 }

+ 21 - 7
toolchain/check/thunk.cpp

@@ -145,6 +145,19 @@ static auto ClonePatternBlock(Context& context, SemIR::SpecificId specific_id,
       });
 }
 
+static auto CloneTypeInstId(Context& context, SemIR::SpecificId specific_id,
+                            SemIR::TypeInstId inst_id) -> SemIR::TypeInstId {
+  if (!inst_id.has_value()) {
+    return SemIR::TypeInstId::None;
+  }
+
+  return context.types().GetAsTypeInstId(
+      GetOrAddInst<SemIR::SpecificConstant>(context, SemIR::LocId(inst_id),
+                                            {.type_id = SemIR::TypeType::TypeId,
+                                             .inst_id = inst_id,
+                                             .specific_id = specific_id}));
+}
+
 static auto CloneFunctionDecl(Context& context, SemIR::LocId loc_id,
                               SemIR::FunctionId signature_id,
                               SemIR::SpecificId signature_specific_id,
@@ -160,8 +173,10 @@ static auto CloneFunctionDecl(Context& context, SemIR::LocId loc_id,
       context, signature_specific_id, signature.implicit_param_patterns_id);
   auto param_patterns_id = ClonePatternBlock(context, signature_specific_id,
                                              signature.param_patterns_id);
-  auto return_slot_pattern_id = ClonePattern(context, signature_specific_id,
-                                             signature.return_slot_pattern_id);
+  auto return_patterns_id = ClonePatternBlock(context, signature_specific_id,
+                                              signature.return_patterns_id);
+  auto return_type_inst_id = CloneTypeInstId(context, signature_specific_id,
+                                             signature.return_type_inst_id);
   auto self_param_id = FindSelfPattern(context, implicit_param_patterns_id);
   auto pattern_block_id = context.pattern_block_stack().Pop();
 
@@ -169,7 +184,7 @@ static auto CloneFunctionDecl(Context& context, SemIR::LocId loc_id,
   context.inst_block_stack().Push();
   auto call_params_id =
       CalleePatternMatch(context, implicit_param_patterns_id, param_patterns_id,
-                         return_slot_pattern_id);
+                         return_patterns_id);
   auto decl_block_id = context.inst_block_stack().Pop();
 
   // Create the `FunctionDecl` instruction.
@@ -196,7 +211,8 @@ static auto CloneFunctionDecl(Context& context, SemIR::LocId loc_id,
                        .first_owning_decl_id = decl_id,
                        .definition_id = decl_id},
                       {.call_params_id = call_params_id,
-                       .return_slot_pattern_id = return_slot_pattern_id,
+                       .return_type_inst_id = return_type_inst_id,
+                       .return_patterns_id = return_patterns_id,
                        .virtual_modifier = callee.virtual_modifier,
                        .virtual_index = callee.virtual_index,
                        .self_param_id = self_param_id}});
@@ -209,9 +225,7 @@ static auto CloneFunctionDecl(Context& context, SemIR::LocId loc_id,
 
 static auto HasDeclaredReturnType(Context& context,
                                   SemIR::FunctionId function_id) -> bool {
-  return context.functions()
-      .Get(function_id)
-      .return_slot_pattern_id.has_value();
+  return context.functions().Get(function_id).return_type_inst_id.has_value();
 }
 
 // Build an expression that names the value matched by a pattern.

+ 16 - 6
toolchain/lower/file_context.cpp

@@ -333,7 +333,11 @@ auto FileContext::BuildFunctionTypeInfo(const SemIR::Function& function,
   if (return_info.has_return_slot()) {
     param_types.push_back(
         llvm::PointerType::get(llvm_context(), /*AddressSpace=*/0));
-    return_param_id = function.return_slot_pattern_id;
+    auto return_patterns =
+        sem_ir_->inst_blocks().Get(function.return_patterns_id);
+    CARBON_CHECK(return_patterns.size() == 1,
+                 "TODO: implement support for multiple return params");
+    return_param_id = return_patterns[0];
     param_inst_ids.push_back(return_param_id);
   }
   for (auto param_pattern_id : llvm::concat<const SemIR::InstId>(
@@ -676,13 +680,19 @@ auto FileContext::BuildFunctionBody(SemIR::FunctionId function_id,
     function_lowering.SetLocal(param_id, param_value);
   };
 
-  // Lower the return slot parameter.
-  if (declaration_function.return_slot_pattern_id.has_value()) {
+  // Lower to the return slot parameter.
+  auto return_patterns = sem_ir_->inst_blocks().GetOrEmpty(
+      declaration_function.return_patterns_id);
+  if (!return_patterns.empty()) {
+    CARBON_CHECK(sem_ir_->inst_blocks()
+                         .Get(declaration_function.return_patterns_id)
+                         .size() == 1,
+                 "TODO: implement support for multiple return patterns");
     auto call_param_id = call_param_ids.consume_back();
     // The LLVM calling convention has the return slot first rather than last.
     // Note that this queries whether there is a return slot at the LLVM level,
-    // whereas `function.return_slot_pattern_id.has_value()` queries whether
-    // there is a return slot at the SemIR level.
+    // whereas `return_patterns.empty()` queries whether there are any output
+    // parameters at the SemIR level.
     if (SemIR::ReturnTypeInfo::ForFunction(sem_ir(), declaration_function,
                                            specific_id)
             .has_return_slot()) {
@@ -776,7 +786,7 @@ auto FileContext::BuildDISubroutineType(const SemIR::Function& function,
 
   auto return_info =
       SemIR::ReturnTypeInfo::ForFunction(sem_ir(), function, specific_id);
-  if (function.return_slot_pattern_id.has_value()) {
+  if (function.return_type_inst_id.has_value()) {
     // TODO: If int_repr.kind == SemIR::InitRepr::ByCopy - be sure the return
     // type is tagged with indirect calling convention.
   }

+ 3 - 3
toolchain/sem_ir/function.cpp

@@ -128,11 +128,11 @@ auto Function::GetParamPatternInfoFromPatternId(const File& sem_ir,
 
 auto Function::GetDeclaredReturnType(const File& file,
                                      SpecificId specific_id) const -> TypeId {
-  if (!return_slot_pattern_id.has_value()) {
+  if (!return_type_inst_id.has_value()) {
     return TypeId::None;
   }
-  return ExtractScrutineeType(
-      file, GetTypeOfInstInSpecific(file, specific_id, return_slot_pattern_id));
+  return file.types().GetTypeIdForTypeConstantId(
+      GetConstantValueInSpecific(file, specific_id, return_type_inst_id));
 }
 
 }  // namespace Carbon::SemIR

+ 25 - 11
toolchain/sem_ir/function.h

@@ -38,17 +38,28 @@ struct FunctionFields {
   // the return slot.
   //
   // The parameters appear in declaration order: `self` (if present), then the
-  // explicit runtime parameters, then the return slot (which is "declared" by
-  // the function's return type declaration). This is not populated on imported
-  // functions, because it is relevant only for a function definition.
+  // explicit runtime parameters, then the return parameters (which are
+  // "declared" by the function's return type declaration). This is not
+  // populated on imported functions, because it is relevant only for a function
+  // definition.
   InstBlockId call_params_id;
 
-  // A reference to the instruction in the entity's pattern block that depends
-  // on all other pattern insts pertaining to the return slot pattern. This may
-  // or may not be used by the function, depending on whether the return type
-  // needs a return slot, but is always present if the function has a declared
-  // return type.
-  InstId return_slot_pattern_id;
+  // The type inst representing the function's explicitly declared return type,
+  // if any.
+  TypeInstId return_type_inst_id;
+
+  // The call parameter pattern insts that are declared by the function's return
+  // form declaration. They will all be OutParamPatterns, and there will be one
+  // for each primitive initializing form in the return form, but they may or
+  // may not be used, depending on whether the type has an in-place initializing
+  // representation.
+  //
+  // Note: As of this writing we don't support non-initializing return forms,
+  // so this will always be have exactly 1 element if the function has an
+  // explicitly declared return type.
+  //
+  // TODO: replace this with a block of all call parameter patterns.
+  InstBlockId return_patterns_id;
 
   // Which kind of special function this is, if any. This is used in cases where
   // a special function would otherwise be indistinguishable from a normal
@@ -102,8 +113,11 @@ struct Function : public EntityWithParamsBase,
     if (call_params_id.has_value()) {
       out << ", call_params_id: " << call_params_id;
     }
-    if (return_slot_pattern_id.has_value()) {
-      out << ", return_slot_pattern: " << return_slot_pattern_id;
+    if (return_type_inst_id.has_value()) {
+      out << ", return_type_inst_id: " << return_type_inst_id;
+    }
+    if (return_patterns_id.has_value()) {
+      out << ", return_patterns_id: " << return_patterns_id;
     }
     if (!body_block_ids.empty()) {
       out << llvm::formatv(

+ 0 - 4
toolchain/sem_ir/typed_insts.h

@@ -1533,10 +1533,6 @@ struct ReturnSlotPattern {
 // Given an instruction with a constant value that depends on a generic
 // parameter, selects a version of that instruction with the constant value
 // corresponding to a particular specific.
-//
-// TODO: We only form these as the instruction referenced by a `NameRef`.
-// Consider merging an `SpecificConstant` + `NameRef` into a new form of
-// instruction in order to give a more compact representation.
 struct SpecificConstant {
   // TODO: Can we make Parse::NodeId more specific?
   static constexpr auto Kind = InstKind::SpecificConstant.Define<Parse::NodeId>(

Некоторые файлы не были показаны из-за большого количества измененных файлов