diff --git a/toolchain/check/call.cpp b/toolchain/check/call.cpp index 9fed5fa2b757..d41d5bd18e0f 100644 --- a/toolchain/check/call.cpp +++ b/toolchain/check/call.cpp @@ -236,17 +236,16 @@ auto PerformCallToFunction(Context& context, SemIR::LocId loc_id, return_type_id = GetTupleType(context, {}); } - llvm::SmallVector return_arg_ids; - for (auto return_pattern_id : - context.inst_blocks().GetOrEmpty(callee.return_patterns_id)) { + auto return_arg_id = SemIR::InstId::None; + if (callee.return_pattern_id.has_value()) { Diagnostics::AnnotationScope annotate_diagnostics( &context.emitter(), [&](auto& builder) { CARBON_DIAGNOSTIC(IncompleteReturnTypeHere, Note, "return type declared here"); - builder.Note(return_pattern_id, IncompleteReturnTypeHere); + builder.Note(callee.return_pattern_id, IncompleteReturnTypeHere); }); auto arg_type_id = CheckFunctionReturnPatternType( - context, loc_id, return_pattern_id, *callee_specific_id); + context, loc_id, callee.return_pattern_id, *callee_specific_id); if (arg_type_id == SemIR::ErrorInst::TypeId) { return_type_id = SemIR::ErrorInst::TypeId; } @@ -255,20 +254,20 @@ auto PerformCallToFunction(Context& context, SemIR::LocId loc_id, case SemIR::InitRepr::Dependent: // Tentatively use storage for a temporary as the return argument. // This will be replaced if necessary when we perform initialization. - return_arg_ids.push_back(AddInst( - context, loc_id, {.type_id = arg_type_id})); + return_arg_id = AddInst( + context, loc_id, {.type_id = arg_type_id}); break; case SemIR::InitRepr::None: case SemIR::InitRepr::ByCopy: case SemIR::InitRepr::Incomplete: case SemIR::InitRepr::Abstract: - return_arg_ids.push_back(SemIR::InstId::None); + return_arg_id = SemIR::InstId::None; break; } } // Convert the arguments to match the parameters. auto converted_args_id = ConvertCallArgs( - context, loc_id, callee_function.self_id, arg_ids, return_arg_ids, callee, + context, loc_id, callee_function.self_id, arg_ids, return_arg_id, callee, *callee_specific_id, is_operator_syntax); switch (callee.special_function_kind) { case SemIR::Function::SpecialFunctionKind::Thunk: { diff --git a/toolchain/check/convert.cpp b/toolchain/check/convert.cpp index c6869befa66c..30fc3e04c0ae 100644 --- a/toolchain/check/convert.cpp +++ b/toolchain/check/convert.cpp @@ -2130,13 +2130,12 @@ auto ConvertForExplicitAs(Context& context, Parse::NodeId as_node, auto ConvertCallArgs(Context& context, SemIR::LocId call_loc_id, SemIR::InstId self_id, llvm::ArrayRef arg_refs, - llvm::ArrayRef return_arg_ids, - const SemIR::Function& callee, + SemIR::InstId return_arg_id, const SemIR::Function& callee, SemIR::SpecificId callee_specific_id, bool is_operator_syntax) -> SemIR::InstBlockId { auto param_patterns = context.inst_blocks().GetOrEmpty(callee.param_patterns_id); - auto return_patterns_id = callee.return_patterns_id; + auto return_pattern_id = callee.return_pattern_id; // The caller should have ensured this callee has the right arity. CARBON_CHECK(arg_refs.size() == param_patterns.size()); @@ -2153,8 +2152,8 @@ auto ConvertCallArgs(Context& context, SemIR::LocId call_loc_id, } return CallerPatternMatch(context, callee_specific_id, callee.self_param_id, - callee.param_patterns_id, return_patterns_id, - self_id, arg_refs, return_arg_ids, + callee.param_patterns_id, return_pattern_id, + self_id, arg_refs, return_arg_id, is_operator_syntax); } diff --git a/toolchain/check/convert.h b/toolchain/check/convert.h index d4a20f70ff70..2bd3e817f718 100644 --- a/toolchain/check/convert.h +++ b/toolchain/check/convert.h @@ -157,8 +157,7 @@ auto ConvertForExplicitAs(Context& context, Parse::NodeId as_node, auto ConvertCallArgs(Context& context, SemIR::LocId call_loc_id, SemIR::InstId self_id, llvm::ArrayRef arg_refs, - llvm::ArrayRef return_arg_ids, - const SemIR::Function& callee, + SemIR::InstId return_arg_id, const SemIR::Function& callee, SemIR::SpecificId callee_specific_id, bool is_operator_syntax) -> SemIR::InstBlockId; diff --git a/toolchain/check/cpp/import.cpp b/toolchain/check/cpp/import.cpp index 7c29a44adde3..00e626db871b 100644 --- a/toolchain/check/cpp/import.cpp +++ b/toolchain/check/cpp/import.cpp @@ -1294,7 +1294,7 @@ static auto GetReturnTypeExpr(Context& context, SemIR::LocId loc_id, struct ReturnInfo { SemIR::TypeInstId return_type_inst_id; SemIR::InstId return_form_inst_id; - SemIR::InstBlockId return_patterns_id; + SemIR::InstId return_pattern_id; }; // Returns information about the declared return type of the given function @@ -1309,12 +1309,12 @@ static auto GetReturnInfo(Context& context, SemIR::LocId loc_id, // void. return {.return_type_inst_id = SemIR::TypeInstId::None, .return_form_inst_id = SemIR::InstId::None, - .return_patterns_id = SemIR::InstBlockId::None}; + .return_pattern_id = SemIR::InstId::None}; } if (form_inst_id == SemIR::ErrorInst::InstId) { return {.return_type_inst_id = SemIR::ErrorInst::TypeInstId, .return_form_inst_id = SemIR::ErrorInst::InstId, - .return_patterns_id = SemIR::InstBlockId::None}; + .return_pattern_id = SemIR::InstId::None}; } auto pattern_type_id = GetPatternType(context, type_id); clang::SourceLocation return_type_loc = @@ -1328,7 +1328,7 @@ static auto GetReturnInfo(Context& context, SemIR::LocId loc_id, } SemIR::ImportIRInstId return_type_import_ir_inst_id = AddImportIRInst(context.sem_ir(), return_type_loc); - auto return_patterns_id = SemIR::InstBlockId::Empty; + auto return_pattern_id = SemIR::InstId::None; if (auto init_form = context.insts().TryGetAs(form_inst_id)) { auto param_pattern_id = AddInst( @@ -1337,18 +1337,17 @@ static auto GetReturnInfo(Context& context, SemIR::LocId loc_id, SemIR::OutParamPattern( {.type_id = pattern_type_id, .pretty_name_id = SemIR::NameId::ReturnSlot}))); - SemIR::InstId return_slot_pattern_id = + return_pattern_id = AddInst(context, SemIR::LocIdAndInst::RuntimeVerified( context.sem_ir(), return_type_import_ir_inst_id, SemIR::ReturnSlotPattern({.type_id = pattern_type_id, .subpattern_id = param_pattern_id, .type_inst_id = type_inst_id}))); - return_patterns_id = context.inst_blocks().Add({return_slot_pattern_id}); } return {.return_type_inst_id = type_inst_id, .return_form_inst_id = form_inst_id, - .return_patterns_id = return_patterns_id}; + .return_pattern_id = return_pattern_id}; } namespace { @@ -1360,7 +1359,7 @@ struct FunctionSignatureInsts { SemIR::InstBlockId param_patterns_id; SemIR::TypeInstId return_type_inst_id; SemIR::InstId return_form_inst_id; - SemIR::InstBlockId return_patterns_id; + SemIR::InstId return_pattern_id; SemIR::InstBlockId call_param_patterns_id; SemIR::InstBlockId call_params_id; SemIR::Function::CallParamIndexRanges param_ranges; @@ -1392,21 +1391,20 @@ static auto CreateFunctionSignatureInsts( return std::nullopt; } context.full_pattern_stack().EndExplicitParamList(); - auto [return_type_inst_id, return_form_inst_id, return_patterns_id] = + auto [return_type_inst_id, return_form_inst_id, return_pattern_id] = GetReturnInfo(context, loc_id, clang_decl); if (return_type_inst_id == SemIR::ErrorInst::TypeInstId) { return std::nullopt; } - auto match_results = - CalleePatternMatch(context, implicit_param_patterns_id, param_patterns_id, - return_patterns_id); + auto match_results = CalleePatternMatch(context, implicit_param_patterns_id, + param_patterns_id, return_pattern_id); return {{.implicit_param_patterns_id = implicit_param_patterns_id, .param_patterns_id = param_patterns_id, .return_type_inst_id = return_type_inst_id, .return_form_inst_id = return_form_inst_id, - .return_patterns_id = return_patterns_id, + .return_pattern_id = return_pattern_id, .call_param_patterns_id = match_results.call_param_patterns_id, .call_params_id = match_results.call_params_id, .param_ranges = match_results.param_ranges}}; @@ -1518,7 +1516,7 @@ static auto ImportFunction(Context& context, SemIR::LocId loc_id, .call_param_ranges = function_params_insts->param_ranges, .return_type_inst_id = function_params_insts->return_type_inst_id, .return_form_inst_id = function_params_insts->return_form_inst_id, - .return_patterns_id = function_params_insts->return_patterns_id, + .return_pattern_id = function_params_insts->return_pattern_id, .virtual_modifier = virtual_modifier, .virtual_index = virtual_index, .evaluation_mode = evaluation_mode, diff --git a/toolchain/check/cpp/thunk.cpp b/toolchain/check/cpp/thunk.cpp index 25854301ba83..aaf7c1b4bbff 100644 --- a/toolchain/check/cpp/thunk.cpp +++ b/toolchain/check/cpp/thunk.cpp @@ -667,23 +667,22 @@ 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 num_callee_return_params = + callee_function.call_param_ranges.return_size(); 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); + auto num_thunk_return_params = thunk_function.call_param_ranges.return_size(); CARBON_CHECK( - callee_return_patterns.size() <= 1 && thunk_return_patterns.size() <= 1, + num_callee_return_params <= 1 && num_thunk_return_params <= 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_return_patterns.empty() && thunk_return_patterns.empty(); + num_callee_return_params > 0 && num_thunk_return_params == 0; // The number of arguments we should be acquiring in order to call the thunk. // This includes the return address parameters, if any. @@ -704,9 +703,9 @@ auto PerformCppThunkCall(Context& context, SemIR::LocId loc_id, // TODO: The parameter should probably only be created if the return pattern // actually needs a return address to be passed in. thunk_function_params = - thunk_function_params.drop_back(thunk_return_patterns.size()); + thunk_function_params.drop_back(num_thunk_return_params); callee_function_params = - callee_function_params.drop_back(callee_return_patterns.size()); + callee_function_params.drop_back(num_callee_return_params); // We assume that the call parameters exactly match the parameter patterns for // both the thunk and the callee. This is guaranteed even when we generate a diff --git a/toolchain/check/function.cpp b/toolchain/check/function.cpp index 97a07fea53cf..9b57d405c5ee 100644 --- a/toolchain/check/function.cpp +++ b/toolchain/check/function.cpp @@ -32,42 +32,52 @@ auto FindSelfPattern(Context& context, }); } -auto AddReturnPatterns(Context& context, SemIR::LocId loc_id, - Context::FormExpr form_expr) -> SemIR::InstBlockId { - llvm::SmallVector return_patterns; +auto AddReturnPattern(Context& context, SemIR::LocId loc_id, + Context::FormExpr form_expr) -> SemIR::InstId { + auto result_id = SemIR::InstId::None; + auto result_type_id = SemIR::TypeId::None; auto form_inst = context.insts().Get( context.constant_values().GetConstantInstId(form_expr.form_inst_id)); CARBON_KIND_SWITCH(form_inst) { - case SemIR::RefForm::Kind: + case SemIR::RefForm::Kind: { + result_type_id = GetPatternType(context, form_expr.type_component_id); + result_id = AddInst(context, loc_id, + {.type_id = result_type_id}); + break; + } case SemIR::ValueForm::Kind: { + result_type_id = GetPatternType(context, form_expr.type_component_id); + result_id = AddInst( + context, loc_id, {.type_id = result_type_id}); break; } case CARBON_KIND(SemIR::InitForm _): { - auto pattern_type_id = - GetPatternType(context, form_expr.type_component_id); - auto out_param_id = AddInst( + result_type_id = GetPatternType(context, form_expr.type_component_id); + result_id = AddInst( context, SemIR::LocId(form_expr.form_inst_id), - {.type_id = pattern_type_id, + {.type_id = result_type_id, .pretty_name_id = SemIR::NameId::ReturnSlot}); - return_patterns.push_back(AddInst( - context, SemIR::LocId(form_expr.form_inst_id), - {.type_id = pattern_type_id, - .subpattern_id = out_param_id, - .type_inst_id = form_expr.type_component_inst_id})); - break; - } - case SemIR::ErrorInst::Kind: { break; } case SemIR::SymbolicBinding::Kind: CARBON_CHECK( context.constant_values().Get(form_expr.form_inst_id).is_symbolic()); context.TODO(loc_id, "Support symbolic return forms"); + result_type_id = SemIR::ErrorInst::TypeId; + result_id = SemIR::ErrorInst::InstId; + break; + case SemIR::ErrorInst::Kind: + result_type_id = SemIR::ErrorInst::TypeId; + result_id = SemIR::ErrorInst::InstId; break; default: CARBON_FATAL("unexpected inst kind: {0}", form_inst); } - return context.inst_blocks().AddCanonical(return_patterns); + return AddInst( + context, SemIR::LocId(form_expr.form_inst_id), + {.type_id = result_type_id, + .subpattern_id = result_id, + .type_inst_id = form_expr.type_component_inst_id}); } auto IsValidBuiltinDeclaration(Context& context, @@ -108,7 +118,7 @@ struct FunctionSignatureInsts { SemIR::Function::CallParamIndexRanges::Empty; SemIR::TypeInstId return_type_inst_id = SemIR::TypeInstId::None; SemIR::InstId return_form_inst_id = SemIR::InstId::None; - SemIR::InstBlockId return_patterns_id = SemIR::InstBlockId::None; + SemIR::InstId return_pattern_id = SemIR::InstId::None; SemIR::InstId self_param_id = SemIR::InstId::None; }; } // namespace @@ -166,12 +176,12 @@ static auto MakeFunctionSignature(Context& context, SemIR::LocId loc_id, context, loc_id, context.types().GetTypeInstId(args.return_type_id)); insts.return_type_inst_id = return_form.type_component_inst_id; insts.return_form_inst_id = return_form.form_inst_id; - insts.return_patterns_id = AddReturnPatterns(context, loc_id, return_form); + insts.return_pattern_id = AddReturnPattern(context, loc_id, return_form); } auto match_results = CalleePatternMatch(context, insts.implicit_param_patterns_id, - insts.param_patterns_id, insts.return_patterns_id); + insts.param_patterns_id, insts.return_pattern_id); insts.call_param_patterns_id = match_results.call_param_patterns_id; insts.call_params_id = match_results.call_params_id; insts.call_param_ranges = match_results.param_ranges; @@ -215,7 +225,7 @@ auto MakeGeneratedFunctionDecl(Context& context, SemIR::LocId loc_id, .call_param_ranges = insts.call_param_ranges, .return_type_inst_id = insts.return_type_inst_id, .return_form_inst_id = insts.return_form_inst_id, - .return_patterns_id = insts.return_patterns_id, + .return_pattern_id = insts.return_pattern_id, .self_param_id = insts.self_param_id, }}); context.generated().push_back(decl_id); @@ -386,7 +396,7 @@ auto CheckFunctionDefinitionSignature(Context& context, // The return parameter will be diagnosed after and differently from other // parameters. auto return_call_param = SemIR::InstId::None; - if (!params_to_complete.empty() && function.return_patterns_id.has_value()) { + if (!params_to_complete.empty() && function.return_pattern_id.has_value()) { return_call_param = params_to_complete.consume_back(); } @@ -410,13 +420,10 @@ auto CheckFunctionDefinitionSignature(Context& context, } // Check the return type is complete. - if (function.return_patterns_id.has_value()) { - for (auto return_pattern_id : - context.inst_blocks().Get(function.return_patterns_id)) { - CheckFunctionReturnPatternType(context, SemIR::LocId(return_pattern_id), - return_pattern_id, - SemIR::SpecificId::None); - } + if (function.return_pattern_id.has_value()) { + CheckFunctionReturnPatternType( + context, SemIR::LocId(function.return_pattern_id), + function.return_pattern_id, SemIR::SpecificId::None); // `CheckFunctionReturnPatternType` should have diagnosed incomplete types, // so don't `RequireCompleteType` on the return type. diff --git a/toolchain/check/function.h b/toolchain/check/function.h index 4453dab8a99c..e359d7f1531f 100644 --- a/toolchain/check/function.h +++ b/toolchain/check/function.h @@ -22,8 +22,8 @@ auto FindSelfPattern(Context& context, // Creates suitable return patterns for the given return form, and adds them to // the current pattern block. -auto AddReturnPatterns(Context& context, SemIR::LocId loc_id, - Context::FormExpr form_expr) -> SemIR::InstBlockId; +auto AddReturnPattern(Context& context, SemIR::LocId loc_id, + Context::FormExpr form_expr) -> SemIR::InstId; // Returns whether `function` is a valid declaration of `builtin_kind`. auto IsValidBuiltinDeclaration(Context& context, diff --git a/toolchain/check/global_init.cpp b/toolchain/check/global_init.cpp index dfa130cdbdaa..d154e2477c1b 100644 --- a/toolchain/check/global_init.cpp +++ b/toolchain/check/global_init.cpp @@ -53,7 +53,7 @@ auto GlobalInit::Finalize() -> void { .call_param_ranges = SemIR::Function::CallParamIndexRanges::Empty, .return_type_inst_id = SemIR::TypeInstId::None, .return_form_inst_id = SemIR::InstId::None, - .return_patterns_id = SemIR::InstBlockId::None, + .return_pattern_id = SemIR::InstId::None, .body_block_ids = {SemIR::InstBlockId::GlobalInit}}})); } diff --git a/toolchain/check/handle_function.cpp b/toolchain/check/handle_function.cpp index ec1bd32619be..4df82f78042d 100644 --- a/toolchain/check/handle_function.cpp +++ b/toolchain/check/handle_function.cpp @@ -61,8 +61,8 @@ static auto HandleReturnDecl(Context& context, Parse::AnyReturnDeclId node_id) } }(); context.PushReturnForm(form_expr); - auto return_patterns_id = AddReturnPatterns(context, node_id, form_expr); - context.node_stack().Push(node_id, return_patterns_id); + context.node_stack().Push(node_id, + AddReturnPattern(context, node_id, form_expr)); return true; } @@ -173,7 +173,7 @@ static auto MergeFunctionRedecl(Context& context, prev_function.call_params_id = new_function.call_params_id; prev_function.return_type_inst_id = new_function.return_type_inst_id; prev_function.return_form_inst_id = new_function.return_form_inst_id; - prev_function.return_patterns_id = new_function.return_patterns_id; + prev_function.return_pattern_id = new_function.return_pattern_id; prev_function.self_param_id = new_function.self_param_id; } if (prev_import_ir_id.has_value()) { @@ -500,20 +500,20 @@ static auto BuildFunctionDecl(Context& context, Parse::AnyFunctionDeclId node_id, bool is_definition) -> std::pair { - auto return_patterns_id = SemIR::InstBlockId::None; + auto return_pattern_id = SemIR::InstId::None; auto return_type_inst_id = SemIR::TypeInstId::None; auto return_form_inst_id = SemIR::InstId::None; - if (auto [return_node, maybe_return_patterns_id] = + if (auto [return_node, maybe_return_pattern_id] = context.node_stack() .PopWithNodeIdIf(); - maybe_return_patterns_id) { - return_patterns_id = *maybe_return_patterns_id; + maybe_return_pattern_id) { + return_pattern_id = *maybe_return_pattern_id; auto return_form = context.PopReturnForm(); return_type_inst_id = return_form.type_component_inst_id; return_form_inst_id = return_form.form_inst_id; } - auto name = PopNameComponent(context, return_patterns_id); + auto name = PopNameComponent(context, return_pattern_id); auto name_context = context.decl_name_stack().FinishName(name); context.node_stack() @@ -550,7 +550,7 @@ static auto BuildFunctionDecl(Context& context, .call_param_ranges = name.param_ranges, .return_type_inst_id = return_type_inst_id, .return_form_inst_id = return_form_inst_id, - .return_patterns_id = return_patterns_id, + .return_pattern_id = return_pattern_id, .virtual_modifier = virtual_modifier, .evaluation_mode = evaluation_mode, .self_param_id = self_param_id}}; diff --git a/toolchain/check/handle_impl.cpp b/toolchain/check/handle_impl.cpp index 6043eb8bb422..bcce8c49e4d7 100644 --- a/toolchain/check/handle_impl.cpp +++ b/toolchain/check/handle_impl.cpp @@ -158,7 +158,7 @@ static auto PopImplIntroducerAndParamsAsNameComponent( // because `impl`s are never actually called at runtime. auto match_results = CalleePatternMatch(context, *implicit_param_patterns_id, - SemIR::InstBlockId::None, SemIR::InstBlockId::None); + SemIR::InstBlockId::None, SemIR::InstId::None); CARBON_CHECK(match_results.call_params_id == SemIR::InstBlockId::Empty); CARBON_CHECK(match_results.call_param_patterns_id == SemIR::InstBlockId::Empty); diff --git a/toolchain/check/import_ref.cpp b/toolchain/check/import_ref.cpp index 4b440e395ac9..649ad94f0816 100644 --- a/toolchain/check/import_ref.cpp +++ b/toolchain/check/import_ref.cpp @@ -1568,6 +1568,23 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, ParamPatternT inst, .pretty_name_id = name_id}); } +template + requires SemIR::Internal::HasInstCategory +static auto TryResolveTypedInst(ImportRefResolver& resolver, + ReturnPatternT inst, + SemIR::InstId import_inst_id) -> ResolveResult { + auto type_const_id = GetLocalConstantId(resolver, inst.type_id); + if (resolver.HasNewWork()) { + return ResolveResult::Retry(); + } + + return ResolveResult::Unique( + resolver, import_inst_id, + {.type_id = + resolver.local_types().GetTypeIdForTypeConstantId(type_const_id)}); +} + static auto TryResolveTypedInst(ImportRefResolver& resolver, SemIR::ArrayType inst) -> ResolveResult { CARBON_CHECK(inst.type_id == SemIR::TypeType::TypeId); @@ -2227,7 +2244,7 @@ static auto ImportFunctionDecl(ImportContext& context, .call_param_ranges = import_function.call_param_ranges, .return_type_inst_id = SemIR::TypeInstId::None, .return_form_inst_id = SemIR::InstId::None, - .return_patterns_id = SemIR::InstBlockId::None, + .return_pattern_id = SemIR::InstId::None, .virtual_modifier = import_function.virtual_modifier, .virtual_index = import_function.virtual_index, .evaluation_mode = import_function.evaluation_mode}}); @@ -2304,8 +2321,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_patterns = - GetLocalInstBlockContents(resolver, import_function.return_patterns_id); + auto return_pattern_id = + GetLocalConstantInstId(resolver, import_function.return_pattern_id); auto& new_function = resolver.local_functions().Get(function_id); if (resolver.HasNewWork()) { return ResolveResult::Retry(function_const_id, @@ -2333,8 +2350,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, resolver, SemIR::FormType::TypeId, import_function.return_form_inst_id, return_form_const_id); } - new_function.return_patterns_id = GetLocalCanonicalInstBlockId( - resolver, import_function.return_patterns_id, return_patterns); + new_function.return_pattern_id = return_pattern_id; if (import_function.definition_id.has_value()) { new_function.definition_id = new_function.first_owning_decl_id; } @@ -4266,6 +4282,9 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver, case CARBON_KIND(SemIR::RefParamPattern inst): { return TryResolveTypedInst(resolver, inst, constant_inst_id); } + case CARBON_KIND(SemIR::RefReturnPattern inst): { + return TryResolveTypedInst(resolver, inst, constant_inst_id); + } case CARBON_KIND(SemIR::RequireCompleteType inst): { return TryResolveTypedInst(resolver, inst); } @@ -4320,6 +4339,9 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver, case CARBON_KIND(SemIR::ValueParamPattern inst): { return TryResolveTypedInst(resolver, inst, constant_inst_id); } + case CARBON_KIND(SemIR::ValueReturnPattern inst): { + return TryResolveTypedInst(resolver, inst, constant_inst_id); + } case CARBON_KIND(SemIR::VarParamPattern inst): { return TryResolveTypedInst(resolver, inst, constant_inst_id); } diff --git a/toolchain/check/name_component.cpp b/toolchain/check/name_component.cpp index ef57aebc92f4..e2b62c653f16 100644 --- a/toolchain/check/name_component.cpp +++ b/toolchain/check/name_component.cpp @@ -9,7 +9,7 @@ namespace Carbon::Check { -auto PopNameComponent(Context& context, SemIR::InstBlockId return_patterns_id) +auto PopNameComponent(Context& context, SemIR::InstId return_pattern_id) -> NameComponent { Parse::NodeId first_param_node_id = Parse::NoneNodeId(); Parse::NodeId last_param_node_id = Parse::NoneNodeId(); @@ -50,9 +50,9 @@ auto PopNameComponent(Context& context, SemIR::InstBlockId return_patterns_id) auto pattern_block_id = SemIR::InstBlockId::None; if (param_patterns_id->has_value() || implicit_param_patterns_id->has_value() || - (!context.inst_blocks().GetOrEmpty(return_patterns_id).empty())) { + return_pattern_id.has_value()) { auto results = CalleePatternMatch(context, *implicit_param_patterns_id, - *param_patterns_id, return_patterns_id); + *param_patterns_id, return_pattern_id); call_param_patterns_id = results.call_param_patterns_id; call_params_id = results.call_params_id; param_ranges = results.param_ranges; diff --git a/toolchain/check/name_component.h b/toolchain/check/name_component.h index 70b5de56b49b..909fbc9366e9 100644 --- a/toolchain/check/name_component.h +++ b/toolchain/check/name_component.h @@ -48,8 +48,8 @@ struct NameComponent { // Pops a name component from the node stack (and pattern block stack, if it has // parameters). -auto PopNameComponent(Context& context, SemIR::InstBlockId return_patterns_id = - SemIR::InstBlockId::None) +auto PopNameComponent(Context& context, + SemIR::InstId return_pattern_id = SemIR::InstId::None) -> NameComponent; // Equivalent to PopNameComponent, but also diagnoses if the name component has diff --git a/toolchain/check/node_stack.h b/toolchain/check/node_stack.h index e59811e3a91d..c3f41a4db568 100644 --- a/toolchain/check/node_stack.h +++ b/toolchain/check/node_stack.h @@ -404,7 +404,7 @@ class NodeStack { Parse::NodeCategory::Modifier, Id::Kind::None); set_id_if_category_is(Parse::NodeCategory::ReturnDecl, - Id::KindFor()); + Id::KindFor()); return result; } diff --git a/toolchain/check/pattern_match.cpp b/toolchain/check/pattern_match.cpp index 192663002636..a22b536357a6 100644 --- a/toolchain/check/pattern_match.cpp +++ b/toolchain/check/pattern_match.cpp @@ -148,6 +148,8 @@ class MatchContext { SemIR::InstId scrutinee_id, WorkItem entry) -> void; auto DoPreWork(State state, SemIR::AnyParamPattern param_pattern, SemIR::InstId scrutinee_id, WorkItem entry) -> void; + auto DoPreWork(State state, SemIR::AnyReturnPattern return_pattern, + SemIR::InstId scrutinee_id, WorkItem entry) -> void; auto DoPreWork(State state, SemIR::ExprPattern expr_pattern, SemIR::InstId scrutinee_id, WorkItem entry) -> void; auto DoPreWork(State state, SemIR::ReturnSlotPattern return_slot_pattern, @@ -786,6 +788,26 @@ auto MatchContext::DoPostWork(State /*state*/, results_stack_.AppendToTop(tuple_value_id); } +auto MatchContext::DoPreWork(State state, + SemIR::AnyReturnPattern return_pattern, + SemIR::InstId /*scrutinee_id*/, WorkItem entry) + -> void { + CARBON_CHECK(std::holds_alternative(state)); + if (need_subpattern_results()) { + auto type_id = + ExtractScrutineeType(context_.sem_ir(), return_pattern.type_id); + SemIR::InstKind result_kind = + return_pattern.kind == SemIR::RefReturnPattern::Kind + ? SemIR::RefReturn::Kind + : SemIR::ValueReturn::Kind; + results_stack_.AppendToTop(AddInst( + context_, + SemIR::LocIdAndInst::RuntimeVerified( + context_.sem_ir(), SemIR::LocId(entry.pattern_id), + SemIR::AnyReturnPattern{.kind = result_kind, .type_id = type_id}))); + } +} + auto MatchContext::Dispatch(State state, WorkItem entry) -> void { if (entry.pattern_id == SemIR::ErrorInst::InstId) { if (need_subpattern_results()) { @@ -816,6 +838,10 @@ auto MatchContext::Dispatch(State state, WorkItem entry) -> void { DoPreWork(state, any_param_pattern, work.scrutinee_id, entry); break; } + case CARBON_KIND_ANY(SemIR::AnyReturnPattern, return_pattern): { + DoPreWork(state, return_pattern, work.scrutinee_id, entry); + break; + } case CARBON_KIND(SemIR::ExprPattern expr_pattern): { DoPreWork(state, expr_pattern, work.scrutinee_id, entry); break; @@ -876,9 +902,9 @@ auto MatchContext::Dispatch(State state, WorkItem entry) -> void { auto CalleePatternMatch(Context& context, SemIR::InstBlockId implicit_param_patterns_id, SemIR::InstBlockId param_patterns_id, - SemIR::InstBlockId return_patterns_id) + SemIR::InstId return_pattern_id) -> CalleePatternMatchResults { - if (!return_patterns_id.has_value() && !param_patterns_id.has_value() && + if (!return_pattern_id.has_value() && !param_patterns_id.has_value() && !implicit_param_patterns_id.has_value()) { return {.call_param_patterns_id = SemIR::InstBlockId::None, .call_params_id = SemIR::InstBlockId::None, @@ -911,8 +937,7 @@ auto CalleePatternMatch(Context& context, } auto explicit_end = SemIR::CallParamIndex(state.call_params.size()); - for (auto return_pattern_id : - context.inst_blocks().GetOrEmpty(return_patterns_id)) { + if (return_pattern_id.has_value()) { match.Match( &state, {.pattern_id = return_pattern_id, @@ -958,11 +983,11 @@ auto ThunkPatternMatch(Context& context, SemIR::InstId self_pattern_id, auto CallerPatternMatch(Context& context, SemIR::SpecificId specific_id, SemIR::InstId self_pattern_id, SemIR::InstBlockId param_patterns_id, - SemIR::InstBlockId return_patterns_id, + SemIR::InstId return_pattern_id, SemIR::InstId self_arg_id, llvm::ArrayRef arg_refs, - llvm::ArrayRef return_arg_ids, - bool is_operator_syntax) -> SemIR::InstBlockId { + SemIR::InstId return_arg_id, bool is_operator_syntax) + -> SemIR::InstBlockId { CallerState state = {.callee_specific_id = specific_id}; MatchContext match(context); @@ -980,19 +1005,17 @@ auto CallerPatternMatch(Context& context, SemIR::SpecificId specific_id, .allow_unmarked_ref = is_operator_syntax}); } - auto return_patterns = context.inst_blocks().GetOrEmpty(return_patterns_id); // Track the return storage, if present. - for (auto [return_pattern_id, return_arg_id] : - llvm::zip_equal(return_patterns, return_arg_ids)) { + if (return_pattern_id.has_value()) { + // TODO: Do the match even if return_arg_id is None, so that subsequent + // args are at the right index in the arg block. if (return_arg_id.has_value()) { match.Match(&state, {.pattern_id = return_pattern_id, .work = MatchContext::PreWork{.scrutinee_id = return_arg_id}}); - } else { - CARBON_CHECK(return_arg_ids.size() == 1, - "TODO: do the match even if return_arg_id is None, so that " - "subsequent args are at the right index in the arg block"); } + } else { + CARBON_CHECK(!return_arg_id.has_value(), "No pattern to match return arg"); } return context.inst_blocks().Add(state.call_args); diff --git a/toolchain/check/pattern_match.h b/toolchain/check/pattern_match.h index 35d18e1bb859..2fa2c00f8ddd 100644 --- a/toolchain/check/pattern_match.h +++ b/toolchain/check/pattern_match.h @@ -29,7 +29,7 @@ struct CalleePatternMatchResults { // Emits the pattern-match IR for the declaration of a parameterized entity with // 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 +// pattern (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). @@ -39,7 +39,7 @@ struct CalleePatternMatchResults { auto CalleePatternMatch(Context& context, SemIR::InstBlockId implicit_param_patterns_id, SemIR::InstBlockId param_patterns_id, - SemIR::InstBlockId return_patterns_id) + SemIR::InstId return_pattern_id) -> CalleePatternMatchResults; // Return type for ThunkPatternMatch. @@ -70,11 +70,11 @@ auto ThunkPatternMatch(Context& context, SemIR::InstId self_pattern_id, auto CallerPatternMatch(Context& context, SemIR::SpecificId specific_id, SemIR::InstId self_pattern_id, SemIR::InstBlockId param_patterns_id, - SemIR::InstBlockId return_patterns_id, + SemIR::InstId return_pattern_id, SemIR::InstId self_arg_id, llvm::ArrayRef arg_refs, - llvm::ArrayRef return_arg_ids, - bool is_operator_syntax) -> SemIR::InstBlockId; + SemIR::InstId return_arg_id, bool is_operator_syntax) + -> SemIR::InstBlockId; // Emits the pattern-match IR for a local pattern matching operation with the // given pattern and scrutinee. diff --git a/toolchain/check/testdata/basics/raw_sem_ir/one_file.carbon b/toolchain/check/testdata/basics/raw_sem_ir/one_file.carbon index 9f0d047fdf3c..6350cfb82f13 100644 --- a/toolchain/check/testdata/basics/raw_sem_ir/one_file.carbon +++ b/toolchain/check/testdata/basics/raw_sem_ir/one_file.carbon @@ -337,12 +337,12 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: entity_name7800003F: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, is_unused: 0, form: inst} // CHECK:STDOUT: cpp_global_vars: {} // CHECK:STDOUT: functions: -// CHECK:STDOUT: function78000000: {name: name0, parent_scope: name_scope0, call_param_patterns_id: inst_block78000011, call_params_id: inst_block78000012, return_type_inst_id: inst78000030, return_form_inst_id: inst78000032, return_patterns_id: inst_block78000010, body: [inst_block78000019]} -// CHECK:STDOUT: function78000001: {name: name4, parent_scope: name_scope78000003, call_param_patterns_id: inst_block7800001F, return_type_inst_id: inst78000060, return_form_inst_id: inst78000061, return_patterns_id: inst_block78000021} -// CHECK:STDOUT: function78000002: {name: name4, parent_scope: name_scope78000004, call_param_patterns_id: inst_block7800002B, return_type_inst_id: inst78000080, return_form_inst_id: inst78000081, return_patterns_id: inst_block7800002D} -// CHECK:STDOUT: function78000003: {name: name4, parent_scope: name_scope78000009, call_param_patterns_id: inst_block78000042, return_type_inst_id: inst780000C8, return_form_inst_id: inst780000C9, return_patterns_id: inst_block78000044} -// CHECK:STDOUT: function78000004: {name: name4, parent_scope: name_scope7800000C, call_param_patterns_id: inst_block78000050, return_type_inst_id: inst780000ED, return_form_inst_id: inst780000EE, return_patterns_id: inst_block78000052} -// CHECK:STDOUT: function78000005: {name: name4, parent_scope: name_scope7800000D, call_param_patterns_id: inst_block7800006D, return_type_inst_id: inst78000131, return_form_inst_id: inst78000132, return_patterns_id: inst_block7800006F} +// CHECK:STDOUT: function78000000: {name: name0, parent_scope: name_scope0, call_param_patterns_id: inst_block78000010, call_params_id: inst_block78000011, return_type_inst_id: inst78000030, return_form_inst_id: inst78000032, return_pattern_id: inst78000038, body: [inst_block78000018]} +// CHECK:STDOUT: function78000001: {name: name4, parent_scope: name_scope78000003, call_param_patterns_id: inst_block7800001E, return_type_inst_id: inst78000060, return_form_inst_id: inst78000061, return_pattern_id: inst7800005C} +// CHECK:STDOUT: function78000002: {name: name4, parent_scope: name_scope78000004, call_param_patterns_id: inst_block78000029, return_type_inst_id: inst78000080, return_form_inst_id: inst78000081, return_pattern_id: inst7800007C} +// CHECK:STDOUT: function78000003: {name: name4, parent_scope: name_scope78000009, call_param_patterns_id: inst_block7800003F, return_type_inst_id: inst780000C8, return_form_inst_id: inst780000C9, return_pattern_id: inst780000C4} +// CHECK:STDOUT: function78000004: {name: name4, parent_scope: name_scope7800000C, call_param_patterns_id: inst_block7800004C, return_type_inst_id: inst780000ED, return_form_inst_id: inst780000EE, return_pattern_id: inst780000E9} +// CHECK:STDOUT: function78000005: {name: name4, parent_scope: name_scope7800000D, call_param_patterns_id: inst_block78000068, return_type_inst_id: inst78000131, return_form_inst_id: inst78000132, return_pattern_id: inst7800012D} // CHECK:STDOUT: classes: {} // CHECK:STDOUT: interfaces: // CHECK:STDOUT: interface78000000: {name: name3, parent_scope: name_scope78000001, require_impls_block_id: require_block_empty} @@ -359,57 +359,57 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: impl78000008: {self: inst78000111, constraint: inst78000112, witness: inst780000DA} // CHECK:STDOUT: impl78000009: {self: inst7800015F, constraint: inst78000160, witness: inst7800011E} // CHECK:STDOUT: generics: -// CHECK:STDOUT: generic78000000: {decl: inst7800003E, bindings: inst_block78000015, self_specific_id: specific78000000, decl_block_id: inst_block78000017, definition_block_id: inst_block78000091} -// CHECK:STDOUT: generic78000001: {decl: inst78000051, bindings: inst_block7800001C, self_specific_id: specific78000001, decl_block_id: inst_block_empty, definition_block_id: inst_block78000026} -// CHECK:STDOUT: generic78000002: {decl: inst78000056, bindings: inst_block78000022, self_specific_id: specific78000002, decl_block_id: inst_block78000023, definition_block_id: inst_block} -// CHECK:STDOUT: generic78000003: {decl: inst78000070, bindings: inst_block78000037, self_specific_id: specific78000004, decl_block_id: inst_block78000039, definition_block_id: inst_block7800003B} -// CHECK:STDOUT: generic78000004: {decl: inst78000077, bindings: inst_block7800002E, self_specific_id: specific78000007, decl_block_id: inst_block7800002F, definition_block_id: inst_block78000034} -// CHECK:STDOUT: generic78000005: {decl: inst780000B5, bindings: inst_block7800003F, self_specific_id: specific7800000B, decl_block_id: inst_block78000041, definition_block_id: inst_block78000049} -// CHECK:STDOUT: generic78000006: {decl: inst780000C0, bindings: inst_block78000045, self_specific_id: specific7800000D, decl_block_id: inst_block78000046, definition_block_id: inst_block_empty} -// CHECK:STDOUT: generic78000007: {decl: inst780000DB, bindings: inst_block78000060, self_specific_id: specific7800000E, decl_block_id: inst_block78000064, definition_block_id: inst_block78000066} -// CHECK:STDOUT: generic78000008: {decl: inst780000E2, bindings: inst_block78000053, self_specific_id: specific78000011, decl_block_id: inst_block78000055, definition_block_id: inst_block7800005D} -// CHECK:STDOUT: generic78000009: {decl: inst7800011F, bindings: inst_block7800007F, self_specific_id: specific78000017, decl_block_id: inst_block78000083, definition_block_id: inst_block78000085} -// CHECK:STDOUT: generic7800000A: {decl: inst78000126, bindings: inst_block78000070, self_specific_id: specific7800001A, decl_block_id: inst_block78000072, definition_block_id: inst_block7800007C} +// CHECK:STDOUT: generic78000000: {decl: inst7800003E, bindings: inst_block78000014, self_specific_id: specific78000000, decl_block_id: inst_block78000016, definition_block_id: inst_block7800008B} +// CHECK:STDOUT: generic78000001: {decl: inst78000051, bindings: inst_block7800001B, self_specific_id: specific78000001, decl_block_id: inst_block_empty, definition_block_id: inst_block78000024} +// CHECK:STDOUT: generic78000002: {decl: inst78000056, bindings: inst_block78000020, self_specific_id: specific78000002, decl_block_id: inst_block78000021, definition_block_id: inst_block} +// CHECK:STDOUT: generic78000003: {decl: inst78000070, bindings: inst_block78000034, self_specific_id: specific78000004, decl_block_id: inst_block78000036, definition_block_id: inst_block78000038} +// CHECK:STDOUT: generic78000004: {decl: inst78000077, bindings: inst_block7800002B, self_specific_id: specific78000007, decl_block_id: inst_block7800002C, definition_block_id: inst_block78000031} +// CHECK:STDOUT: generic78000005: {decl: inst780000B5, bindings: inst_block7800003C, self_specific_id: specific7800000B, decl_block_id: inst_block7800003E, definition_block_id: inst_block78000045} +// CHECK:STDOUT: generic78000006: {decl: inst780000C0, bindings: inst_block78000041, self_specific_id: specific7800000D, decl_block_id: inst_block78000042, definition_block_id: inst_block_empty} +// CHECK:STDOUT: generic78000007: {decl: inst780000DB, bindings: inst_block7800005B, self_specific_id: specific7800000E, decl_block_id: inst_block7800005F, definition_block_id: inst_block78000061} +// CHECK:STDOUT: generic78000008: {decl: inst780000E2, bindings: inst_block7800004E, self_specific_id: specific78000011, decl_block_id: inst_block78000050, definition_block_id: inst_block78000058} +// CHECK:STDOUT: generic78000009: {decl: inst7800011F, bindings: inst_block78000079, self_specific_id: specific78000017, decl_block_id: inst_block7800007D, definition_block_id: inst_block7800007F} +// CHECK:STDOUT: generic7800000A: {decl: inst78000126, bindings: inst_block7800006A, self_specific_id: specific7800001A, decl_block_id: inst_block7800006C, definition_block_id: inst_block78000076} // CHECK:STDOUT: specifics: -// CHECK:STDOUT: specific78000000: {generic: generic78000000, args: inst_block78000016, decl_block_id: inst_block78000018, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific78000001: {generic: generic78000001, args: inst_block7800001D, decl_block_id: inst_block_empty, decl_has_error: 0, definition_block_id: inst_block7800001E, definition_has_error: 0} -// CHECK:STDOUT: specific78000002: {generic: generic78000002, args: inst_block7800001D, decl_block_id: inst_block78000024, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific78000003: {generic: generic78000001, args: inst_block78000025, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific78000004: {generic: generic78000003, args: inst_block78000028, decl_block_id: inst_block78000029, decl_has_error: 0, definition_block_id: inst_block7800002A, definition_has_error: 0} -// CHECK:STDOUT: specific78000005: {generic: generic78000001, args: inst_block78000028, decl_block_id: inst_block_empty, decl_has_error: 0, definition_block_id: inst_block78000030, definition_has_error: 0} -// CHECK:STDOUT: specific78000006: {generic: generic78000002, args: inst_block78000028, decl_block_id: inst_block78000031, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific78000007: {generic: generic78000004, args: inst_block78000028, decl_block_id: inst_block78000035, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific78000008: {generic: generic78000001, args: inst_block78000032, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific78000009: {generic: generic78000002, args: inst_block78000032, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific7800000A: {generic: generic78000003, args: inst_block78000038, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific7800000B: {generic: generic78000005, args: inst_block78000016, decl_block_id: inst_block7800003D, decl_has_error: 0, definition_block_id: inst_block78000086, definition_has_error: 0} -// CHECK:STDOUT: specific7800000C: {generic: generic78000005, args: inst_block78000040, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific7800000D: {generic: generic78000006, args: inst_block78000016, decl_block_id: inst_block78000047, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific7800000E: {generic: generic78000007, args: inst_block7800004C, decl_block_id: inst_block7800004E, decl_has_error: 0, definition_block_id: inst_block7800004F, definition_has_error: 0} -// CHECK:STDOUT: specific7800000F: {generic: generic78000001, args: inst_block78000056, decl_block_id: inst_block_empty, decl_has_error: 0, definition_block_id: inst_block78000057, definition_has_error: 0} -// CHECK:STDOUT: specific78000010: {generic: generic78000002, args: inst_block78000056, decl_block_id: inst_block78000058, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific78000011: {generic: generic78000008, args: inst_block7800004C, decl_block_id: inst_block7800005E, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific78000012: {generic: generic78000001, args: inst_block78000059, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific78000013: {generic: generic78000002, args: inst_block78000059, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific78000014: {generic: generic78000001, args: inst_block7800005B, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific78000015: {generic: generic78000002, args: inst_block7800005B, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific78000016: {generic: generic78000007, args: inst_block78000061, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific78000017: {generic: generic78000009, args: inst_block78000069, decl_block_id: inst_block7800006B, decl_has_error: 0, definition_block_id: inst_block7800006C, definition_has_error: 0} -// CHECK:STDOUT: specific78000018: {generic: generic78000001, args: inst_block78000073, decl_block_id: inst_block_empty, decl_has_error: 0, definition_block_id: inst_block78000074, definition_has_error: 0} -// CHECK:STDOUT: specific78000019: {generic: generic78000002, args: inst_block78000073, decl_block_id: inst_block78000075, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific7800001A: {generic: generic7800000A, args: inst_block78000069, decl_block_id: inst_block7800007D, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific7800001B: {generic: generic78000001, args: inst_block78000076, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific7800001C: {generic: generic78000002, args: inst_block78000076, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific7800001D: {generic: generic78000001, args: inst_block78000078, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific7800001E: {generic: generic78000002, args: inst_block78000078, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific7800001F: {generic: generic78000001, args: inst_block7800007A, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific78000020: {generic: generic78000002, args: inst_block7800007A, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific78000021: {generic: generic78000009, args: inst_block78000080, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific78000022: {generic: generic78000005, args: inst_block78000087, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific78000023: {generic: generic78000001, args: inst_block78000089, decl_block_id: inst_block_empty, decl_has_error: 0, definition_block_id: inst_block7800008A, definition_has_error: 0} -// CHECK:STDOUT: specific78000024: {generic: generic78000001, args: inst_block7800008C, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific78000025: {generic: generic78000002, args: inst_block78000089, decl_block_id: inst_block7800008D, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} -// CHECK:STDOUT: specific78000026: {generic: generic78000002, args: inst_block7800008C, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific78000000: {generic: generic78000000, args: inst_block78000015, decl_block_id: inst_block78000017, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific78000001: {generic: generic78000001, args: inst_block7800001C, decl_block_id: inst_block_empty, decl_has_error: 0, definition_block_id: inst_block7800001D, definition_has_error: 0} +// CHECK:STDOUT: specific78000002: {generic: generic78000002, args: inst_block7800001C, decl_block_id: inst_block78000022, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific78000003: {generic: generic78000001, args: inst_block78000023, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific78000004: {generic: generic78000003, args: inst_block78000026, decl_block_id: inst_block78000027, decl_has_error: 0, definition_block_id: inst_block78000028, definition_has_error: 0} +// CHECK:STDOUT: specific78000005: {generic: generic78000001, args: inst_block78000026, decl_block_id: inst_block_empty, decl_has_error: 0, definition_block_id: inst_block7800002D, definition_has_error: 0} +// CHECK:STDOUT: specific78000006: {generic: generic78000002, args: inst_block78000026, decl_block_id: inst_block7800002E, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific78000007: {generic: generic78000004, args: inst_block78000026, decl_block_id: inst_block78000032, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific78000008: {generic: generic78000001, args: inst_block7800002F, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific78000009: {generic: generic78000002, args: inst_block7800002F, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific7800000A: {generic: generic78000003, args: inst_block78000035, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific7800000B: {generic: generic78000005, args: inst_block78000015, decl_block_id: inst_block7800003A, decl_has_error: 0, definition_block_id: inst_block78000080, definition_has_error: 0} +// CHECK:STDOUT: specific7800000C: {generic: generic78000005, args: inst_block7800003D, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific7800000D: {generic: generic78000006, args: inst_block78000015, decl_block_id: inst_block78000043, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific7800000E: {generic: generic78000007, args: inst_block78000048, decl_block_id: inst_block7800004A, decl_has_error: 0, definition_block_id: inst_block7800004B, definition_has_error: 0} +// CHECK:STDOUT: specific7800000F: {generic: generic78000001, args: inst_block78000051, decl_block_id: inst_block_empty, decl_has_error: 0, definition_block_id: inst_block78000052, definition_has_error: 0} +// CHECK:STDOUT: specific78000010: {generic: generic78000002, args: inst_block78000051, decl_block_id: inst_block78000053, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific78000011: {generic: generic78000008, args: inst_block78000048, decl_block_id: inst_block78000059, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific78000012: {generic: generic78000001, args: inst_block78000054, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific78000013: {generic: generic78000002, args: inst_block78000054, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific78000014: {generic: generic78000001, args: inst_block78000056, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific78000015: {generic: generic78000002, args: inst_block78000056, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific78000016: {generic: generic78000007, args: inst_block7800005C, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific78000017: {generic: generic78000009, args: inst_block78000064, decl_block_id: inst_block78000066, decl_has_error: 0, definition_block_id: inst_block78000067, definition_has_error: 0} +// CHECK:STDOUT: specific78000018: {generic: generic78000001, args: inst_block7800006D, decl_block_id: inst_block_empty, decl_has_error: 0, definition_block_id: inst_block7800006E, definition_has_error: 0} +// CHECK:STDOUT: specific78000019: {generic: generic78000002, args: inst_block7800006D, decl_block_id: inst_block7800006F, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific7800001A: {generic: generic7800000A, args: inst_block78000064, decl_block_id: inst_block78000077, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific7800001B: {generic: generic78000001, args: inst_block78000070, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific7800001C: {generic: generic78000002, args: inst_block78000070, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific7800001D: {generic: generic78000001, args: inst_block78000072, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific7800001E: {generic: generic78000002, args: inst_block78000072, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific7800001F: {generic: generic78000001, args: inst_block78000074, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific78000020: {generic: generic78000002, args: inst_block78000074, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific78000021: {generic: generic78000009, args: inst_block7800007A, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific78000022: {generic: generic78000005, args: inst_block78000081, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific78000023: {generic: generic78000001, args: inst_block78000083, decl_block_id: inst_block_empty, decl_has_error: 0, definition_block_id: inst_block78000084, definition_has_error: 0} +// CHECK:STDOUT: specific78000024: {generic: generic78000001, args: inst_block78000086, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific78000025: {generic: generic78000002, args: inst_block78000083, decl_block_id: inst_block78000087, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} +// CHECK:STDOUT: specific78000026: {generic: generic78000002, args: inst_block78000086, decl_block_id: inst_block, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} // CHECK:STDOUT: specific_interfaces: // CHECK:STDOUT: specific_interface78000000: {interface_id: interface78000000, specific_id: specific} // CHECK:STDOUT: struct_type_fields: @@ -571,7 +571,7 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: inst7800003B: {kind: SpliceBlock, arg0: inst_block78000007, arg1: inst7800001C, type: type(TypeType)} // CHECK:STDOUT: inst7800003C: {kind: OutParam, arg0: call_param1, arg1: name(ReturnSlot), type: type(symbolic_constant7800000A)} // CHECK:STDOUT: inst7800003D: {kind: ReturnSlot, arg0: inst7800002F, arg1: inst7800003C, type: type(symbolic_constant7800000A)} -// CHECK:STDOUT: inst7800003E: {kind: FunctionDecl, arg0: function78000000, arg1: inst_block78000014, type: type(inst7800003F)} +// CHECK:STDOUT: inst7800003E: {kind: FunctionDecl, arg0: function78000000, arg1: inst_block78000013, type: type(inst7800003F)} // CHECK:STDOUT: inst7800003F: {kind: FunctionType, arg0: function78000000, arg1: specific, type: type(TypeType)} // CHECK:STDOUT: inst78000040: {kind: StructValue, arg0: inst_block_empty, type: type(inst7800003F)} // CHECK:STDOUT: inst78000041: {kind: RequireCompleteType, arg0: inst7800001D, type: type(inst(WitnessType))} @@ -583,7 +583,7 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: inst78000047: {kind: RequireCompleteType, arg0: inst78000031, type: type(inst(WitnessType))} // CHECK:STDOUT: inst78000048: {kind: NameRef, arg0: name2, arg1: inst78000022, type: type(symbolic_constant78000004)} // CHECK:STDOUT: inst78000049: {kind: TupleLiteral, arg0: inst_block_empty, type: type(inst78000026)} -// CHECK:STDOUT: inst7800004A: {kind: TupleLiteral, arg0: inst_block7800001A, type: type(symbolic_constant7800000A)} +// CHECK:STDOUT: inst7800004A: {kind: TupleLiteral, arg0: inst_block78000019, type: type(symbolic_constant7800000A)} // CHECK:STDOUT: inst7800004B: {kind: RequireCompleteType, arg0: inst7800002F, type: type(inst(WitnessType))} // CHECK:STDOUT: inst7800004C: {kind: TupleAccess, arg0: inst7800003C, arg1: element0, type: type(symbolic_constant78000004)} // CHECK:STDOUT: inst7800004D: {kind: RequireCompleteType, arg0: inst7800001D, type: type(inst(WitnessType))} @@ -626,7 +626,7 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: inst78000072: {kind: SymbolicBindingType, arg0: entity_name78000001, arg1: inst78000071, type: type(TypeType)} // CHECK:STDOUT: inst78000073: {kind: ConstType, arg0: inst78000072, type: type(TypeType)} // CHECK:STDOUT: inst78000074: {kind: ImportRefUnloaded, arg0: import_ir_inst19, arg1: entity_name} -// CHECK:STDOUT: inst78000075: {kind: ImplWitnessTable, arg0: inst_block78000027, arg1: impl78000000} +// CHECK:STDOUT: inst78000075: {kind: ImplWitnessTable, arg0: inst_block78000025, arg1: impl78000000} // CHECK:STDOUT: inst78000076: {kind: ImplWitness, arg0: inst78000075, arg1: specific78000004, type: type(inst(WitnessType))} // CHECK:STDOUT: inst78000077: {kind: FunctionDecl, arg0: function78000002, arg1: inst_block_empty, type: type(symbolic_constant78000031)} // CHECK:STDOUT: inst78000078: {kind: FunctionType, arg0: function78000002, arg1: specific78000004, type: type(TypeType)} @@ -692,7 +692,7 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: inst780000B4: {kind: ImportRefLoaded, arg0: import_ir_inst49, arg1: entity_name, type: type(inst(WitnessType))} // CHECK:STDOUT: inst780000B5: {kind: ImplDecl, arg0: impl78000005, arg1: inst_block_empty} // CHECK:STDOUT: inst780000B6: {kind: ImportRefUnloaded, arg0: import_ir_inst4B, arg1: entity_name} -// CHECK:STDOUT: inst780000B7: {kind: ImplWitnessTable, arg0: inst_block7800003C, arg1: impl78000005} +// CHECK:STDOUT: inst780000B7: {kind: ImplWitnessTable, arg0: inst_block78000039, arg1: impl78000005} // CHECK:STDOUT: inst780000B8: {kind: ImplWitness, arg0: inst780000B7, arg1: specific7800000B, type: type(inst(WitnessType))} // CHECK:STDOUT: inst780000B9: {kind: SymbolicBindingPattern, arg0: entity_name78000019, type: type(inst78000016)} // CHECK:STDOUT: inst780000BA: {kind: ImportRefLoaded, arg0: import_ir_inst4E, arg1: entity_name, type: type(TypeType)} @@ -731,15 +731,15 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: inst780000DB: {kind: ImplDecl, arg0: impl78000008, arg1: inst_block_empty} // CHECK:STDOUT: inst780000DC: {kind: SymbolicBinding, arg0: entity_name7800001C, arg1: inst, type: type(inst78000050)} // CHECK:STDOUT: inst780000DD: {kind: SymbolicBindingType, arg0: entity_name7800001C, arg1: inst780000DC, type: type(TypeType)} -// CHECK:STDOUT: inst780000DE: {kind: TupleType, arg0: inst_block7800004A, type: type(TypeType)} +// CHECK:STDOUT: inst780000DE: {kind: TupleType, arg0: inst_block78000046, type: type(TypeType)} // CHECK:STDOUT: inst780000DF: {kind: ImportRefUnloaded, arg0: import_ir_inst6D, arg1: entity_name} -// CHECK:STDOUT: inst780000E0: {kind: ImplWitnessTable, arg0: inst_block7800004B, arg1: impl78000008} +// CHECK:STDOUT: inst780000E0: {kind: ImplWitnessTable, arg0: inst_block78000047, arg1: impl78000008} // CHECK:STDOUT: inst780000E1: {kind: ImplWitness, arg0: inst780000E0, arg1: specific7800000E, type: type(inst(WitnessType))} // CHECK:STDOUT: inst780000E2: {kind: FunctionDecl, arg0: function78000004, arg1: inst_block_empty, type: type(symbolic_constant78000089)} // CHECK:STDOUT: inst780000E3: {kind: FunctionType, arg0: function78000004, arg1: specific7800000E, type: type(TypeType)} // CHECK:STDOUT: inst780000E4: {kind: StructValue, arg0: inst_block_empty, type: type(symbolic_constant78000089)} -// CHECK:STDOUT: inst780000E5: {kind: TupleType, arg0: inst_block7800004D, type: type(TypeType)} -// CHECK:STDOUT: inst780000E6: {kind: TupleValue, arg0: inst_block7800004C, type: type(inst780000E5)} +// CHECK:STDOUT: inst780000E5: {kind: TupleType, arg0: inst_block78000049, type: type(TypeType)} +// CHECK:STDOUT: inst780000E6: {kind: TupleValue, arg0: inst_block78000048, type: type(inst780000E5)} // CHECK:STDOUT: inst780000E7: {kind: PatternType, arg0: inst780000DE, type: type(TypeType)} // CHECK:STDOUT: inst780000E8: {kind: OutParamPattern, arg0: name(ReturnSlot), type: type(symbolic_constant7800008F)} // CHECK:STDOUT: inst780000E9: {kind: ReturnSlotPattern, arg0: inst780000E8, arg1: inst, type: type(symbolic_constant7800008F)} @@ -754,7 +754,7 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: inst780000F2: {kind: SymbolicBindingType, arg0: entity_name78000001, arg1: inst780000F1, type: type(TypeType)} // CHECK:STDOUT: inst780000F3: {kind: SymbolicBinding, arg0: entity_name7800001C, arg1: inst, type: type(inst78000050)} // CHECK:STDOUT: inst780000F4: {kind: SymbolicBindingType, arg0: entity_name7800001C, arg1: inst780000F3, type: type(TypeType)} -// CHECK:STDOUT: inst780000F5: {kind: TupleType, arg0: inst_block78000054, type: type(TypeType)} +// CHECK:STDOUT: inst780000F5: {kind: TupleType, arg0: inst_block7800004F, type: type(TypeType)} // CHECK:STDOUT: inst780000F6: {kind: PatternType, arg0: inst780000F5, type: type(TypeType)} // CHECK:STDOUT: inst780000F7: {kind: InitForm, arg0: inst780000F5, type: type(inst(FormType))} // CHECK:STDOUT: inst780000F8: {kind: LookupImplWitness, arg0: inst780000DC, arg1: specific_interface78000000, type: type(inst(WitnessType))} @@ -788,10 +788,10 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: inst78000114: {kind: ImportRefLoaded, arg0: import_ir_inst91, arg1: entity_name, type: type(inst78000050)} // CHECK:STDOUT: inst78000115: {kind: SymbolicBinding, arg0: entity_name78000001, arg1: inst, type: type(inst78000050)} // CHECK:STDOUT: inst78000116: {kind: SymbolicBinding, arg0: entity_name7800001C, arg1: inst, type: type(inst78000050)} -// CHECK:STDOUT: inst78000117: {kind: TupleValue, arg0: inst_block78000061, type: type(inst780000E5)} +// CHECK:STDOUT: inst78000117: {kind: TupleValue, arg0: inst_block7800005C, type: type(inst780000E5)} // CHECK:STDOUT: inst78000118: {kind: SymbolicBindingType, arg0: entity_name78000001, arg1: inst78000115, type: type(TypeType)} // CHECK:STDOUT: inst78000119: {kind: SymbolicBindingType, arg0: entity_name7800001C, arg1: inst78000116, type: type(TypeType)} -// CHECK:STDOUT: inst7800011A: {kind: TupleType, arg0: inst_block78000062, type: type(TypeType)} +// CHECK:STDOUT: inst7800011A: {kind: TupleType, arg0: inst_block7800005D, type: type(TypeType)} // CHECK:STDOUT: inst7800011B: {kind: ImplWitness, arg0: inst780000E0, arg1: specific78000016, type: type(inst(WitnessType))} // CHECK:STDOUT: inst7800011C: {kind: FunctionType, arg0: function78000004, arg1: specific78000016, type: type(TypeType)} // CHECK:STDOUT: inst7800011D: {kind: StructValue, arg0: inst_block_empty, type: type(symbolic_constant780000D4)} @@ -799,15 +799,15 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: inst7800011F: {kind: ImplDecl, arg0: impl78000009, arg1: inst_block_empty} // CHECK:STDOUT: inst78000120: {kind: SymbolicBinding, arg0: entity_name7800002B, arg1: inst, type: type(inst78000050)} // CHECK:STDOUT: inst78000121: {kind: SymbolicBindingType, arg0: entity_name7800002B, arg1: inst78000120, type: type(TypeType)} -// CHECK:STDOUT: inst78000122: {kind: TupleType, arg0: inst_block78000067, type: type(TypeType)} +// CHECK:STDOUT: inst78000122: {kind: TupleType, arg0: inst_block78000062, type: type(TypeType)} // CHECK:STDOUT: inst78000123: {kind: ImportRefUnloaded, arg0: import_ir_inst9D, arg1: entity_name} -// CHECK:STDOUT: inst78000124: {kind: ImplWitnessTable, arg0: inst_block78000068, arg1: impl78000009} +// CHECK:STDOUT: inst78000124: {kind: ImplWitnessTable, arg0: inst_block78000063, arg1: impl78000009} // CHECK:STDOUT: inst78000125: {kind: ImplWitness, arg0: inst78000124, arg1: specific78000017, type: type(inst(WitnessType))} // CHECK:STDOUT: inst78000126: {kind: FunctionDecl, arg0: function78000005, arg1: inst_block_empty, type: type(symbolic_constant780000DC)} // CHECK:STDOUT: inst78000127: {kind: FunctionType, arg0: function78000005, arg1: specific78000017, type: type(TypeType)} // CHECK:STDOUT: inst78000128: {kind: StructValue, arg0: inst_block_empty, type: type(symbolic_constant780000DC)} -// CHECK:STDOUT: inst78000129: {kind: TupleType, arg0: inst_block7800006A, type: type(TypeType)} -// CHECK:STDOUT: inst7800012A: {kind: TupleValue, arg0: inst_block78000069, type: type(inst78000129)} +// CHECK:STDOUT: inst78000129: {kind: TupleType, arg0: inst_block78000065, type: type(TypeType)} +// CHECK:STDOUT: inst7800012A: {kind: TupleValue, arg0: inst_block78000064, type: type(inst78000129)} // CHECK:STDOUT: inst7800012B: {kind: PatternType, arg0: inst78000122, type: type(TypeType)} // CHECK:STDOUT: inst7800012C: {kind: OutParamPattern, arg0: name(ReturnSlot), type: type(symbolic_constant780000E2)} // CHECK:STDOUT: inst7800012D: {kind: ReturnSlotPattern, arg0: inst7800012C, arg1: inst, type: type(symbolic_constant780000E2)} @@ -825,7 +825,7 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: inst78000139: {kind: SymbolicBindingType, arg0: entity_name7800001C, arg1: inst78000138, type: type(TypeType)} // CHECK:STDOUT: inst7800013A: {kind: SymbolicBinding, arg0: entity_name7800002B, arg1: inst, type: type(inst78000050)} // CHECK:STDOUT: inst7800013B: {kind: SymbolicBindingType, arg0: entity_name7800002B, arg1: inst7800013A, type: type(TypeType)} -// CHECK:STDOUT: inst7800013C: {kind: TupleType, arg0: inst_block78000071, type: type(TypeType)} +// CHECK:STDOUT: inst7800013C: {kind: TupleType, arg0: inst_block7800006B, type: type(TypeType)} // CHECK:STDOUT: inst7800013D: {kind: PatternType, arg0: inst7800013C, type: type(TypeType)} // CHECK:STDOUT: inst7800013E: {kind: InitForm, arg0: inst7800013C, type: type(inst(FormType))} // CHECK:STDOUT: inst7800013F: {kind: LookupImplWitness, arg0: inst78000120, arg1: specific_interface78000000, type: type(inst(WitnessType))} @@ -868,11 +868,11 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: inst78000164: {kind: SymbolicBinding, arg0: entity_name78000001, arg1: inst, type: type(inst78000050)} // CHECK:STDOUT: inst78000165: {kind: SymbolicBinding, arg0: entity_name7800001C, arg1: inst, type: type(inst78000050)} // CHECK:STDOUT: inst78000166: {kind: SymbolicBinding, arg0: entity_name7800002B, arg1: inst, type: type(inst78000050)} -// CHECK:STDOUT: inst78000167: {kind: TupleValue, arg0: inst_block78000080, type: type(inst78000129)} +// CHECK:STDOUT: inst78000167: {kind: TupleValue, arg0: inst_block7800007A, type: type(inst78000129)} // CHECK:STDOUT: inst78000168: {kind: SymbolicBindingType, arg0: entity_name78000001, arg1: inst78000164, type: type(TypeType)} // CHECK:STDOUT: inst78000169: {kind: SymbolicBindingType, arg0: entity_name7800001C, arg1: inst78000165, type: type(TypeType)} // CHECK:STDOUT: inst7800016A: {kind: SymbolicBindingType, arg0: entity_name7800002B, arg1: inst78000166, type: type(TypeType)} -// CHECK:STDOUT: inst7800016B: {kind: TupleType, arg0: inst_block78000081, type: type(TypeType)} +// CHECK:STDOUT: inst7800016B: {kind: TupleType, arg0: inst_block7800007B, type: type(TypeType)} // CHECK:STDOUT: inst7800016C: {kind: ImplWitness, arg0: inst78000124, arg1: specific78000021, type: type(inst(WitnessType))} // CHECK:STDOUT: inst7800016D: {kind: FunctionType, arg0: function78000005, arg1: specific78000021, type: type(TypeType)} // CHECK:STDOUT: inst7800016E: {kind: StructValue, arg0: inst_block_empty, type: type(symbolic_constant7800013C)} @@ -880,14 +880,14 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: inst78000170: {kind: RequireSpecificDefinition, arg0: specific7800000B, type: type(inst(RequireSpecificDefinitionType))} // CHECK:STDOUT: inst78000171: {kind: RequireSpecificDefinition, arg0: specific7800000B, type: type(inst(RequireSpecificDefinitionType))} // CHECK:STDOUT: inst78000172: {kind: RequireSpecificDefinition, arg0: specific78000022, type: type(inst(RequireSpecificDefinitionType))} -// CHECK:STDOUT: inst78000173: {kind: FacetValue, arg0: inst7800001D, arg1: inst_block78000088, type: type(inst78000050)} +// CHECK:STDOUT: inst78000173: {kind: FacetValue, arg0: inst7800001D, arg1: inst_block78000082, type: type(inst78000050)} // CHECK:STDOUT: inst78000174: {kind: FunctionType, arg0: function78000001, arg1: specific78000023, type: type(TypeType)} // CHECK:STDOUT: inst78000175: {kind: StructValue, arg0: inst_block_empty, type: type(symbolic_constant78000143)} // CHECK:STDOUT: inst78000176: {kind: FunctionTypeWithSelfType, arg0: inst78000174, arg1: inst78000173, type: type(TypeType)} // CHECK:STDOUT: inst78000177: {kind: ImplWitnessAccess, arg0: inst7800016F, arg1: element0, type: type(symbolic_constant7800014A)} // CHECK:STDOUT: inst78000178: {kind: ImplWitnessAccess, arg0: inst7800016F, arg1: element0, type: type(symbolic_constant78000145)} // CHECK:STDOUT: inst78000179: {kind: LookupImplWitness, arg0: inst7800001E, arg1: specific_interface78000000, type: type(inst(WitnessType))} -// CHECK:STDOUT: inst7800017A: {kind: FacetValue, arg0: inst7800001E, arg1: inst_block7800008B, type: type(inst78000050)} +// CHECK:STDOUT: inst7800017A: {kind: FacetValue, arg0: inst7800001E, arg1: inst_block78000085, type: type(inst78000050)} // CHECK:STDOUT: inst7800017B: {kind: FunctionType, arg0: function78000001, arg1: specific78000024, type: type(TypeType)} // CHECK:STDOUT: inst7800017C: {kind: FunctionTypeWithSelfType, arg0: inst7800017B, arg1: inst7800017A, type: type(TypeType)} // CHECK:STDOUT: inst7800017D: {kind: ImplWitnessAccess, arg0: inst78000179, arg1: element0, type: type(symbolic_constant7800014A)} @@ -896,13 +896,13 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: inst78000180: {kind: SpecificImplFunction, arg0: inst78000178, arg1: specific78000025, type: type(inst(SpecificFunctionType))} // CHECK:STDOUT: inst78000181: {kind: SpecificImplFunction, arg0: inst7800017D, arg1: specific78000026, type: type(inst(SpecificFunctionType))} // CHECK:STDOUT: inst78000182: {kind: BoundMethod, arg0: inst78000048, arg1: inst7800017F, type: type(inst(BoundMethodType))} -// CHECK:STDOUT: inst78000183: {kind: Call, arg0: inst78000182, arg1: inst_block7800008F, type: type(symbolic_constant78000004)} +// CHECK:STDOUT: inst78000183: {kind: Call, arg0: inst78000182, arg1: inst_block78000089, type: type(symbolic_constant78000004)} // CHECK:STDOUT: inst78000184: {kind: InPlaceInit, arg0: inst78000183, arg1: inst7800004C, type: type(symbolic_constant78000004)} // CHECK:STDOUT: inst78000185: {kind: TupleAccess, arg0: inst7800003C, arg1: element1, type: type(inst78000026)} // CHECK:STDOUT: inst78000186: {kind: TupleInit, arg0: inst_block_empty, arg1: inst78000185, type: type(inst78000026)} // CHECK:STDOUT: inst78000187: {kind: Converted, arg0: inst78000049, arg1: inst78000186, type: type(inst78000026)} // CHECK:STDOUT: inst78000188: {kind: InPlaceInit, arg0: inst78000187, arg1: inst78000185, type: type(inst78000026)} -// CHECK:STDOUT: inst78000189: {kind: TupleInit, arg0: inst_block78000090, arg1: inst7800003C, type: type(symbolic_constant7800000A)} +// CHECK:STDOUT: inst78000189: {kind: TupleInit, arg0: inst_block7800008A, arg1: inst7800003C, type: type(symbolic_constant7800000A)} // CHECK:STDOUT: inst7800018A: {kind: Converted, arg0: inst7800004A, arg1: inst78000189, type: type(symbolic_constant7800000A)} // CHECK:STDOUT: inst7800018B: {kind: ReturnExpr, arg0: inst7800018A, arg1: inst7800003C} // CHECK:STDOUT: constant_values: @@ -1759,20 +1759,18 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: 0: inst7800001E // CHECK:STDOUT: 1: inst78000026 // CHECK:STDOUT: inst_block78000010: -// CHECK:STDOUT: 0: inst78000038 -// CHECK:STDOUT: inst_block78000011: // CHECK:STDOUT: 0: inst78000020 // CHECK:STDOUT: 1: inst78000036 -// CHECK:STDOUT: inst_block78000012: +// CHECK:STDOUT: inst_block78000011: // CHECK:STDOUT: 0: inst7800003A // CHECK:STDOUT: 1: inst7800003C -// CHECK:STDOUT: inst_block78000013: +// CHECK:STDOUT: inst_block78000012: // CHECK:STDOUT: 0: inst7800001A // CHECK:STDOUT: 1: inst78000020 // CHECK:STDOUT: 2: inst78000023 // CHECK:STDOUT: 3: inst78000036 // CHECK:STDOUT: 4: inst78000038 -// CHECK:STDOUT: inst_block78000014: +// CHECK:STDOUT: inst_block78000013: // CHECK:STDOUT: 0: inst78000024 // CHECK:STDOUT: 1: inst78000025 // CHECK:STDOUT: 2: inst78000027 @@ -1787,11 +1785,11 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: 11: inst78000022 // CHECK:STDOUT: 12: inst7800003C // CHECK:STDOUT: 13: inst7800003D -// CHECK:STDOUT: inst_block78000015: +// CHECK:STDOUT: inst_block78000014: // CHECK:STDOUT: 0: inst78000017 -// CHECK:STDOUT: inst_block78000016: +// CHECK:STDOUT: inst_block78000015: // CHECK:STDOUT: 0: inst78000018 -// CHECK:STDOUT: inst_block78000017: +// CHECK:STDOUT: inst_block78000016: // CHECK:STDOUT: 0: inst78000019 // CHECK:STDOUT: 1: inst7800001E // CHECK:STDOUT: 2: inst78000021 @@ -1799,7 +1797,7 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: 4: inst78000031 // CHECK:STDOUT: 5: inst78000034 // CHECK:STDOUT: 6: inst78000037 -// CHECK:STDOUT: inst_block78000018: +// CHECK:STDOUT: inst_block78000017: // CHECK:STDOUT: 0: inst78000018 // CHECK:STDOUT: 1: inst7800001D // CHECK:STDOUT: 2: inst7800001F @@ -1807,7 +1805,7 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: 4: inst7800002F // CHECK:STDOUT: 5: inst78000033 // CHECK:STDOUT: 6: inst78000035 -// CHECK:STDOUT: inst_block78000019: +// CHECK:STDOUT: inst_block78000018: // CHECK:STDOUT: 0: inst78000048 // CHECK:STDOUT: 1: inst78000049 // CHECK:STDOUT: 2: inst7800004A @@ -1825,85 +1823,81 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: 14: inst78000189 // CHECK:STDOUT: 15: inst7800018A // CHECK:STDOUT: 16: inst7800018B -// CHECK:STDOUT: inst_block7800001A: +// CHECK:STDOUT: inst_block78000019: // CHECK:STDOUT: 0: inst78000048 // CHECK:STDOUT: 1: inst78000049 -// CHECK:STDOUT: inst_block7800001B: +// CHECK:STDOUT: inst_block7800001A: // CHECK:STDOUT: 0: inst78000054 -// CHECK:STDOUT: inst_block7800001C: +// CHECK:STDOUT: inst_block7800001B: // CHECK:STDOUT: 0: inst78000055 -// CHECK:STDOUT: inst_block7800001D: +// CHECK:STDOUT: inst_block7800001C: // CHECK:STDOUT: 0: inst78000052 -// CHECK:STDOUT: inst_block7800001E: +// CHECK:STDOUT: inst_block7800001D: // CHECK:STDOUT: 0: inst78000052 // CHECK:STDOUT: 1: inst78000057 // CHECK:STDOUT: 2: inst78000058 -// CHECK:STDOUT: inst_block7800001F: +// CHECK:STDOUT: inst_block7800001E: // CHECK:STDOUT: 0: inst7800005D // CHECK:STDOUT: 1: inst7800005B -// CHECK:STDOUT: inst_block78000020: +// CHECK:STDOUT: inst_block7800001F: // CHECK:STDOUT: 0: inst7800005E -// CHECK:STDOUT: inst_block78000021: -// CHECK:STDOUT: 0: inst7800005C -// CHECK:STDOUT: inst_block78000022: +// CHECK:STDOUT: inst_block78000020: // CHECK:STDOUT: 0: inst78000062 -// CHECK:STDOUT: inst_block78000023: +// CHECK:STDOUT: inst_block78000021: // CHECK:STDOUT: 0: inst78000063 // CHECK:STDOUT: 1: inst78000064 // CHECK:STDOUT: 2: inst78000065 // CHECK:STDOUT: 3: inst78000066 -// CHECK:STDOUT: inst_block78000024: +// CHECK:STDOUT: inst_block78000022: // CHECK:STDOUT: 0: inst78000052 // CHECK:STDOUT: 1: inst78000059 // CHECK:STDOUT: 2: inst7800005A // CHECK:STDOUT: 3: inst7800005F -// CHECK:STDOUT: inst_block78000025: +// CHECK:STDOUT: inst_block78000023: // CHECK:STDOUT: 0: inst78000067 -// CHECK:STDOUT: inst_block78000026: +// CHECK:STDOUT: inst_block78000024: // CHECK:STDOUT: 0: inst78000067 // CHECK:STDOUT: 1: inst78000068 // CHECK:STDOUT: 2: inst78000069 -// CHECK:STDOUT: inst_block78000027: +// CHECK:STDOUT: inst_block78000025: // CHECK:STDOUT: 0: inst78000074 -// CHECK:STDOUT: inst_block78000028: +// CHECK:STDOUT: inst_block78000026: // CHECK:STDOUT: 0: inst78000071 -// CHECK:STDOUT: inst_block78000029: +// CHECK:STDOUT: inst_block78000027: // CHECK:STDOUT: 0: inst78000071 // CHECK:STDOUT: 1: inst78000072 // CHECK:STDOUT: 2: inst78000073 // CHECK:STDOUT: 3: inst78000076 -// CHECK:STDOUT: inst_block7800002A: +// CHECK:STDOUT: inst_block78000028: // CHECK:STDOUT: 0: inst78000078 // CHECK:STDOUT: 1: inst78000079 -// CHECK:STDOUT: inst_block7800002B: +// CHECK:STDOUT: inst_block78000029: // CHECK:STDOUT: 0: inst7800007D // CHECK:STDOUT: 1: inst7800007B -// CHECK:STDOUT: inst_block7800002C: +// CHECK:STDOUT: inst_block7800002A: // CHECK:STDOUT: 0: inst7800007E -// CHECK:STDOUT: inst_block7800002D: -// CHECK:STDOUT: 0: inst7800007C -// CHECK:STDOUT: inst_block7800002E: +// CHECK:STDOUT: inst_block7800002B: // CHECK:STDOUT: 0: inst78000082 -// CHECK:STDOUT: inst_block7800002F: +// CHECK:STDOUT: inst_block7800002C: // CHECK:STDOUT: 0: inst78000083 // CHECK:STDOUT: 1: inst78000084 // CHECK:STDOUT: 2: inst78000085 // CHECK:STDOUT: 3: inst78000086 // CHECK:STDOUT: 4: inst78000087 -// CHECK:STDOUT: inst_block78000030: +// CHECK:STDOUT: inst_block7800002D: // CHECK:STDOUT: 0: inst78000071 // CHECK:STDOUT: 1: inst78000089 // CHECK:STDOUT: 2: inst7800008A -// CHECK:STDOUT: inst_block78000031: +// CHECK:STDOUT: inst_block7800002E: // CHECK:STDOUT: 0: inst78000071 // CHECK:STDOUT: 1: inst78000072 // CHECK:STDOUT: 2: inst7800008F // CHECK:STDOUT: 3: inst7800008E -// CHECK:STDOUT: inst_block78000032: +// CHECK:STDOUT: inst_block7800002F: // CHECK:STDOUT: 0: inst78000083 -// CHECK:STDOUT: inst_block78000033: +// CHECK:STDOUT: inst_block78000030: // CHECK:STDOUT: 0: inst78000083 -// CHECK:STDOUT: inst_block78000034: +// CHECK:STDOUT: inst_block78000031: // CHECK:STDOUT: 0: inst78000092 // CHECK:STDOUT: 1: inst78000093 // CHECK:STDOUT: 2: inst78000094 @@ -1911,81 +1905,79 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: 4: inst78000096 // CHECK:STDOUT: 5: inst78000097 // CHECK:STDOUT: 6: inst78000098 -// CHECK:STDOUT: inst_block78000035: +// CHECK:STDOUT: inst_block78000032: // CHECK:STDOUT: 0: inst78000071 // CHECK:STDOUT: 1: inst78000072 // CHECK:STDOUT: 2: inst78000073 // CHECK:STDOUT: 3: inst7800007A // CHECK:STDOUT: 4: inst7800007F -// CHECK:STDOUT: inst_block78000036: +// CHECK:STDOUT: inst_block78000033: // CHECK:STDOUT: 0: inst7800009A -// CHECK:STDOUT: inst_block78000037: +// CHECK:STDOUT: inst_block78000034: // CHECK:STDOUT: 0: inst7800009D -// CHECK:STDOUT: inst_block78000038: +// CHECK:STDOUT: inst_block78000035: // CHECK:STDOUT: 0: inst7800009E -// CHECK:STDOUT: inst_block78000039: +// CHECK:STDOUT: inst_block78000036: // CHECK:STDOUT: 0: inst7800009E // CHECK:STDOUT: 1: inst7800009F // CHECK:STDOUT: 2: inst780000A0 // CHECK:STDOUT: 3: inst780000A1 -// CHECK:STDOUT: inst_block7800003A: +// CHECK:STDOUT: inst_block78000037: // CHECK:STDOUT: 0: inst7800009E -// CHECK:STDOUT: inst_block7800003B: +// CHECK:STDOUT: inst_block78000038: // CHECK:STDOUT: 0: inst780000A2 // CHECK:STDOUT: 1: inst780000A3 -// CHECK:STDOUT: inst_block7800003C: +// CHECK:STDOUT: inst_block78000039: // CHECK:STDOUT: 0: inst780000B6 -// CHECK:STDOUT: inst_block7800003D: +// CHECK:STDOUT: inst_block7800003A: // CHECK:STDOUT: 0: inst78000018 // CHECK:STDOUT: 1: inst7800001D // CHECK:STDOUT: 2: inst780000B8 -// CHECK:STDOUT: inst_block7800003E: +// CHECK:STDOUT: inst_block7800003B: // CHECK:STDOUT: 0: inst780000B9 -// CHECK:STDOUT: inst_block7800003F: +// CHECK:STDOUT: inst_block7800003C: // CHECK:STDOUT: 0: inst780000BC -// CHECK:STDOUT: inst_block78000040: +// CHECK:STDOUT: inst_block7800003D: // CHECK:STDOUT: 0: inst780000BD -// CHECK:STDOUT: inst_block78000041: +// CHECK:STDOUT: inst_block7800003E: // CHECK:STDOUT: 0: inst780000BD // CHECK:STDOUT: 1: inst780000BE // CHECK:STDOUT: 2: inst780000BF -// CHECK:STDOUT: inst_block78000042: +// CHECK:STDOUT: inst_block7800003F: // CHECK:STDOUT: 0: inst780000C5 // CHECK:STDOUT: 1: inst780000C3 -// CHECK:STDOUT: inst_block78000043: +// CHECK:STDOUT: inst_block78000040: // CHECK:STDOUT: 0: inst780000C6 -// CHECK:STDOUT: inst_block78000044: -// CHECK:STDOUT: 0: inst780000C4 -// CHECK:STDOUT: inst_block78000045: +// CHECK:STDOUT: inst_block78000041: // CHECK:STDOUT: 0: inst780000CA -// CHECK:STDOUT: inst_block78000046: +// CHECK:STDOUT: inst_block78000042: // CHECK:STDOUT: 0: inst780000CB // CHECK:STDOUT: 1: inst780000CC // CHECK:STDOUT: 2: inst780000CD // CHECK:STDOUT: 3: inst780000CE -// CHECK:STDOUT: inst_block78000047: +// CHECK:STDOUT: inst_block78000043: // CHECK:STDOUT: 0: inst78000018 // CHECK:STDOUT: 1: inst7800001D // CHECK:STDOUT: 2: inst7800001F // CHECK:STDOUT: 3: inst780000C7 -// CHECK:STDOUT: inst_block78000048: +// CHECK:STDOUT: inst_block78000044: // CHECK:STDOUT: 0: inst780000BD -// CHECK:STDOUT: inst_block78000049: +// CHECK:STDOUT: inst_block78000045: // CHECK:STDOUT: 0: inst780000CF // CHECK:STDOUT: 1: inst780000D0 // CHECK:STDOUT: 2: inst780000D1 -// CHECK:STDOUT: inst_block7800004A: +// CHECK:STDOUT: inst_block78000046: // CHECK:STDOUT: 0: inst78000072 // CHECK:STDOUT: 1: inst780000DD -// CHECK:STDOUT: inst_block7800004B: +// CHECK:STDOUT: inst_block78000047: // CHECK:STDOUT: 0: inst780000DF -// CHECK:STDOUT: inst_block7800004C: +// CHECK:STDOUT: inst_block78000048: // CHECK:STDOUT: 0: inst78000071 // CHECK:STDOUT: 1: inst780000DC -// CHECK:STDOUT: inst_block7800004D: +// CHECK:STDOUT: inst_block78000049: // CHECK:STDOUT: 0: inst78000050 // CHECK:STDOUT: 1: inst78000050 -// CHECK:STDOUT: inst_block7800004E: +// CHECK:STDOUT: inst_block7800004A: // CHECK:STDOUT: 0: inst78000071 // CHECK:STDOUT: 1: inst780000DC // CHECK:STDOUT: 2: inst780000E6 @@ -1993,23 +1985,21 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: 4: inst780000DD // CHECK:STDOUT: 5: inst780000DE // CHECK:STDOUT: 6: inst780000E1 -// CHECK:STDOUT: inst_block7800004F: +// CHECK:STDOUT: inst_block7800004B: // CHECK:STDOUT: 0: inst780000E3 // CHECK:STDOUT: 1: inst780000E4 -// CHECK:STDOUT: inst_block78000050: +// CHECK:STDOUT: inst_block7800004C: // CHECK:STDOUT: 0: inst780000EA // CHECK:STDOUT: 1: inst780000E8 -// CHECK:STDOUT: inst_block78000051: +// CHECK:STDOUT: inst_block7800004D: // CHECK:STDOUT: 0: inst780000EB -// CHECK:STDOUT: inst_block78000052: -// CHECK:STDOUT: 0: inst780000E9 -// CHECK:STDOUT: inst_block78000053: +// CHECK:STDOUT: inst_block7800004E: // CHECK:STDOUT: 0: inst780000EF // CHECK:STDOUT: 1: inst780000F0 -// CHECK:STDOUT: inst_block78000054: +// CHECK:STDOUT: inst_block7800004F: // CHECK:STDOUT: 0: inst780000F2 // CHECK:STDOUT: 1: inst780000F4 -// CHECK:STDOUT: inst_block78000055: +// CHECK:STDOUT: inst_block78000050: // CHECK:STDOUT: 0: inst780000F1 // CHECK:STDOUT: 1: inst780000F2 // CHECK:STDOUT: 2: inst780000F3 @@ -2017,26 +2007,26 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: 4: inst780000F5 // CHECK:STDOUT: 5: inst780000F6 // CHECK:STDOUT: 6: inst780000F7 -// CHECK:STDOUT: inst_block78000056: +// CHECK:STDOUT: inst_block78000051: // CHECK:STDOUT: 0: inst780000DC -// CHECK:STDOUT: inst_block78000057: +// CHECK:STDOUT: inst_block78000052: // CHECK:STDOUT: 0: inst780000DC // CHECK:STDOUT: 1: inst780000F9 // CHECK:STDOUT: 2: inst780000FA -// CHECK:STDOUT: inst_block78000058: +// CHECK:STDOUT: inst_block78000053: // CHECK:STDOUT: 0: inst780000DC // CHECK:STDOUT: 1: inst780000DD // CHECK:STDOUT: 2: inst780000FF // CHECK:STDOUT: 3: inst780000FE -// CHECK:STDOUT: inst_block78000059: +// CHECK:STDOUT: inst_block78000054: // CHECK:STDOUT: 0: inst780000F1 -// CHECK:STDOUT: inst_block7800005A: +// CHECK:STDOUT: inst_block78000055: // CHECK:STDOUT: 0: inst780000F1 -// CHECK:STDOUT: inst_block7800005B: +// CHECK:STDOUT: inst_block78000056: // CHECK:STDOUT: 0: inst780000F3 -// CHECK:STDOUT: inst_block7800005C: +// CHECK:STDOUT: inst_block78000057: // CHECK:STDOUT: 0: inst780000F3 -// CHECK:STDOUT: inst_block7800005D: +// CHECK:STDOUT: inst_block78000058: // CHECK:STDOUT: 0: inst78000102 // CHECK:STDOUT: 1: inst78000103 // CHECK:STDOUT: 2: inst78000104 @@ -2050,7 +2040,7 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: 10: inst7800010C // CHECK:STDOUT: 11: inst7800010D // CHECK:STDOUT: 12: inst7800010E -// CHECK:STDOUT: inst_block7800005E: +// CHECK:STDOUT: inst_block78000059: // CHECK:STDOUT: 0: inst78000071 // CHECK:STDOUT: 1: inst78000072 // CHECK:STDOUT: 2: inst780000DC @@ -2058,22 +2048,22 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: 4: inst780000DE // CHECK:STDOUT: 5: inst780000E7 // CHECK:STDOUT: 6: inst780000EC -// CHECK:STDOUT: inst_block7800005F: +// CHECK:STDOUT: inst_block7800005A: // CHECK:STDOUT: 0: inst78000110 // CHECK:STDOUT: 1: inst7800010F -// CHECK:STDOUT: inst_block78000060: +// CHECK:STDOUT: inst_block7800005B: // CHECK:STDOUT: 0: inst78000113 // CHECK:STDOUT: 1: inst78000114 -// CHECK:STDOUT: inst_block78000061: +// CHECK:STDOUT: inst_block7800005C: // CHECK:STDOUT: 0: inst78000115 // CHECK:STDOUT: 1: inst78000116 -// CHECK:STDOUT: inst_block78000062: +// CHECK:STDOUT: inst_block7800005D: // CHECK:STDOUT: 0: inst78000118 // CHECK:STDOUT: 1: inst78000119 -// CHECK:STDOUT: inst_block78000063: +// CHECK:STDOUT: inst_block7800005E: // CHECK:STDOUT: 0: inst78000115 // CHECK:STDOUT: 1: inst78000116 -// CHECK:STDOUT: inst_block78000064: +// CHECK:STDOUT: inst_block7800005F: // CHECK:STDOUT: 0: inst78000115 // CHECK:STDOUT: 1: inst78000116 // CHECK:STDOUT: 2: inst78000117 @@ -2081,27 +2071,27 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: 4: inst78000119 // CHECK:STDOUT: 5: inst7800011A // CHECK:STDOUT: 6: inst7800011B -// CHECK:STDOUT: inst_block78000065: +// CHECK:STDOUT: inst_block78000060: // CHECK:STDOUT: 0: inst78000115 // CHECK:STDOUT: 1: inst78000116 -// CHECK:STDOUT: inst_block78000066: +// CHECK:STDOUT: inst_block78000061: // CHECK:STDOUT: 0: inst7800011C // CHECK:STDOUT: 1: inst7800011D -// CHECK:STDOUT: inst_block78000067: +// CHECK:STDOUT: inst_block78000062: // CHECK:STDOUT: 0: inst78000072 // CHECK:STDOUT: 1: inst780000DD // CHECK:STDOUT: 2: inst78000121 -// CHECK:STDOUT: inst_block78000068: +// CHECK:STDOUT: inst_block78000063: // CHECK:STDOUT: 0: inst78000123 -// CHECK:STDOUT: inst_block78000069: +// CHECK:STDOUT: inst_block78000064: // CHECK:STDOUT: 0: inst78000071 // CHECK:STDOUT: 1: inst780000DC // CHECK:STDOUT: 2: inst78000120 -// CHECK:STDOUT: inst_block7800006A: +// CHECK:STDOUT: inst_block78000065: // CHECK:STDOUT: 0: inst78000050 // CHECK:STDOUT: 1: inst78000050 // CHECK:STDOUT: 2: inst78000050 -// CHECK:STDOUT: inst_block7800006B: +// CHECK:STDOUT: inst_block78000066: // CHECK:STDOUT: 0: inst78000071 // CHECK:STDOUT: 1: inst780000DC // CHECK:STDOUT: 2: inst78000120 @@ -2111,25 +2101,23 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: 6: inst78000121 // CHECK:STDOUT: 7: inst78000122 // CHECK:STDOUT: 8: inst78000125 -// CHECK:STDOUT: inst_block7800006C: +// CHECK:STDOUT: inst_block78000067: // CHECK:STDOUT: 0: inst78000127 // CHECK:STDOUT: 1: inst78000128 -// CHECK:STDOUT: inst_block7800006D: +// CHECK:STDOUT: inst_block78000068: // CHECK:STDOUT: 0: inst7800012E // CHECK:STDOUT: 1: inst7800012C -// CHECK:STDOUT: inst_block7800006E: +// CHECK:STDOUT: inst_block78000069: // CHECK:STDOUT: 0: inst7800012F -// CHECK:STDOUT: inst_block7800006F: -// CHECK:STDOUT: 0: inst7800012D -// CHECK:STDOUT: inst_block78000070: +// CHECK:STDOUT: inst_block7800006A: // CHECK:STDOUT: 0: inst78000133 // CHECK:STDOUT: 1: inst78000134 // CHECK:STDOUT: 2: inst78000135 -// CHECK:STDOUT: inst_block78000071: +// CHECK:STDOUT: inst_block7800006B: // CHECK:STDOUT: 0: inst78000137 // CHECK:STDOUT: 1: inst78000139 // CHECK:STDOUT: 2: inst7800013B -// CHECK:STDOUT: inst_block78000072: +// CHECK:STDOUT: inst_block7800006C: // CHECK:STDOUT: 0: inst78000136 // CHECK:STDOUT: 1: inst78000137 // CHECK:STDOUT: 2: inst78000138 @@ -2139,30 +2127,30 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: 6: inst7800013C // CHECK:STDOUT: 7: inst7800013D // CHECK:STDOUT: 8: inst7800013E -// CHECK:STDOUT: inst_block78000073: +// CHECK:STDOUT: inst_block7800006D: // CHECK:STDOUT: 0: inst78000120 -// CHECK:STDOUT: inst_block78000074: +// CHECK:STDOUT: inst_block7800006E: // CHECK:STDOUT: 0: inst78000120 // CHECK:STDOUT: 1: inst78000140 // CHECK:STDOUT: 2: inst78000141 -// CHECK:STDOUT: inst_block78000075: +// CHECK:STDOUT: inst_block7800006F: // CHECK:STDOUT: 0: inst78000120 // CHECK:STDOUT: 1: inst78000121 // CHECK:STDOUT: 2: inst78000146 // CHECK:STDOUT: 3: inst78000145 +// CHECK:STDOUT: inst_block78000070: +// CHECK:STDOUT: 0: inst78000136 +// CHECK:STDOUT: inst_block78000071: +// CHECK:STDOUT: 0: inst78000136 +// CHECK:STDOUT: inst_block78000072: +// CHECK:STDOUT: 0: inst78000138 +// CHECK:STDOUT: inst_block78000073: +// CHECK:STDOUT: 0: inst78000138 +// CHECK:STDOUT: inst_block78000074: +// CHECK:STDOUT: 0: inst7800013A +// CHECK:STDOUT: inst_block78000075: +// CHECK:STDOUT: 0: inst7800013A // CHECK:STDOUT: inst_block78000076: -// CHECK:STDOUT: 0: inst78000136 -// CHECK:STDOUT: inst_block78000077: -// CHECK:STDOUT: 0: inst78000136 -// CHECK:STDOUT: inst_block78000078: -// CHECK:STDOUT: 0: inst78000138 -// CHECK:STDOUT: inst_block78000079: -// CHECK:STDOUT: 0: inst78000138 -// CHECK:STDOUT: inst_block7800007A: -// CHECK:STDOUT: 0: inst7800013A -// CHECK:STDOUT: inst_block7800007B: -// CHECK:STDOUT: 0: inst7800013A -// CHECK:STDOUT: inst_block7800007C: // CHECK:STDOUT: 0: inst78000149 // CHECK:STDOUT: 1: inst7800014A // CHECK:STDOUT: 2: inst7800014B @@ -2182,7 +2170,7 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: 16: inst78000159 // CHECK:STDOUT: 17: inst7800015A // CHECK:STDOUT: 18: inst7800015B -// CHECK:STDOUT: inst_block7800007D: +// CHECK:STDOUT: inst_block78000077: // CHECK:STDOUT: 0: inst78000071 // CHECK:STDOUT: 1: inst78000072 // CHECK:STDOUT: 2: inst780000DC @@ -2192,27 +2180,27 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: 6: inst78000122 // CHECK:STDOUT: 7: inst7800012B // CHECK:STDOUT: 8: inst78000130 -// CHECK:STDOUT: inst_block7800007E: +// CHECK:STDOUT: inst_block78000078: // CHECK:STDOUT: 0: inst7800015E // CHECK:STDOUT: 1: inst7800015D // CHECK:STDOUT: 2: inst7800015C -// CHECK:STDOUT: inst_block7800007F: +// CHECK:STDOUT: inst_block78000079: // CHECK:STDOUT: 0: inst78000161 // CHECK:STDOUT: 1: inst78000162 // CHECK:STDOUT: 2: inst78000163 -// CHECK:STDOUT: inst_block78000080: +// CHECK:STDOUT: inst_block7800007A: // CHECK:STDOUT: 0: inst78000164 // CHECK:STDOUT: 1: inst78000165 // CHECK:STDOUT: 2: inst78000166 -// CHECK:STDOUT: inst_block78000081: +// CHECK:STDOUT: inst_block7800007B: // CHECK:STDOUT: 0: inst78000168 // CHECK:STDOUT: 1: inst78000169 // CHECK:STDOUT: 2: inst7800016A -// CHECK:STDOUT: inst_block78000082: +// CHECK:STDOUT: inst_block7800007C: // CHECK:STDOUT: 0: inst78000164 // CHECK:STDOUT: 1: inst78000165 // CHECK:STDOUT: 2: inst78000166 -// CHECK:STDOUT: inst_block78000083: +// CHECK:STDOUT: inst_block7800007D: // CHECK:STDOUT: 0: inst78000164 // CHECK:STDOUT: 1: inst78000165 // CHECK:STDOUT: 2: inst78000166 @@ -2222,44 +2210,44 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: 6: inst7800016A // CHECK:STDOUT: 7: inst7800016B // CHECK:STDOUT: 8: inst7800016C -// CHECK:STDOUT: inst_block78000084: +// CHECK:STDOUT: inst_block7800007E: // CHECK:STDOUT: 0: inst78000164 // CHECK:STDOUT: 1: inst78000165 // CHECK:STDOUT: 2: inst78000166 -// CHECK:STDOUT: inst_block78000085: +// CHECK:STDOUT: inst_block7800007F: // CHECK:STDOUT: 0: inst7800016D // CHECK:STDOUT: 1: inst7800016E -// CHECK:STDOUT: inst_block78000086: +// CHECK:STDOUT: inst_block78000080: // CHECK:STDOUT: 0: inst780000C1 // CHECK:STDOUT: 1: inst780000C2 // CHECK:STDOUT: 2: inst78000042 -// CHECK:STDOUT: inst_block78000087: +// CHECK:STDOUT: inst_block78000081: // CHECK:STDOUT: 0: inst78000019 -// CHECK:STDOUT: inst_block78000088: +// CHECK:STDOUT: inst_block78000082: // CHECK:STDOUT: 0: inst7800016F -// CHECK:STDOUT: inst_block78000089: +// CHECK:STDOUT: inst_block78000083: // CHECK:STDOUT: 0: inst78000173 -// CHECK:STDOUT: inst_block7800008A: +// CHECK:STDOUT: inst_block78000084: // CHECK:STDOUT: 0: inst78000173 // CHECK:STDOUT: 1: inst78000174 // CHECK:STDOUT: 2: inst78000175 -// CHECK:STDOUT: inst_block7800008B: +// CHECK:STDOUT: inst_block78000085: // CHECK:STDOUT: 0: inst78000179 -// CHECK:STDOUT: inst_block7800008C: +// CHECK:STDOUT: inst_block78000086: // CHECK:STDOUT: 0: inst7800017A -// CHECK:STDOUT: inst_block7800008D: +// CHECK:STDOUT: inst_block78000087: // CHECK:STDOUT: 0: inst78000173 // CHECK:STDOUT: 1: inst7800001D // CHECK:STDOUT: 2: inst7800001F // CHECK:STDOUT: 3: inst780000C7 -// CHECK:STDOUT: inst_block7800008E: +// CHECK:STDOUT: inst_block78000088: // CHECK:STDOUT: 0: inst7800017A -// CHECK:STDOUT: inst_block7800008F: +// CHECK:STDOUT: inst_block78000089: // CHECK:STDOUT: 0: inst78000048 -// CHECK:STDOUT: inst_block78000090: +// CHECK:STDOUT: inst_block7800008A: // CHECK:STDOUT: 0: inst78000184 // CHECK:STDOUT: 1: inst78000188 -// CHECK:STDOUT: inst_block78000091: +// CHECK:STDOUT: inst_block7800008B: // CHECK:STDOUT: 0: inst78000043 // CHECK:STDOUT: 1: inst78000047 // CHECK:STDOUT: 2: inst78000172 @@ -2269,7 +2257,7 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: 6: inst7800017C // CHECK:STDOUT: 7: inst7800017D // CHECK:STDOUT: 8: inst78000181 -// CHECK:STDOUT: inst_block78000092: +// CHECK:STDOUT: inst_block7800008C: // CHECK:STDOUT: 0: instF // CHECK:STDOUT: 1: inst78000010 // CHECK:STDOUT: 2: inst7800003E diff --git a/toolchain/check/testdata/basics/raw_sem_ir/one_file_with_textual_ir.carbon b/toolchain/check/testdata/basics/raw_sem_ir/one_file_with_textual_ir.carbon index c15a716beb20..342e88bc483a 100644 --- a/toolchain/check/testdata/basics/raw_sem_ir/one_file_with_textual_ir.carbon +++ b/toolchain/check/testdata/basics/raw_sem_ir/one_file_with_textual_ir.carbon @@ -34,7 +34,7 @@ fn Foo(n: ()) -> ((), ()) { // CHECK:STDOUT: entity_name50000000: {name: name1, parent_scope: name_scope, index: -1, is_template: 0, is_unused: 0, form: inst} // CHECK:STDOUT: cpp_global_vars: {} // CHECK:STDOUT: functions: -// CHECK:STDOUT: function50000000: {name: name0, parent_scope: name_scope0, call_param_patterns_id: inst_block5000000C, call_params_id: inst_block5000000D, return_type_inst_id: inst50000020, return_form_inst_id: inst50000021, return_patterns_id: inst_block5000000B, body: [inst_block50000010]} +// CHECK:STDOUT: function50000000: {name: name0, parent_scope: name_scope0, call_param_patterns_id: inst_block5000000B, call_params_id: inst_block5000000C, return_type_inst_id: inst50000020, return_form_inst_id: inst50000021, return_pattern_id: inst50000025, body: [inst_block5000000F]} // CHECK:STDOUT: classes: {} // CHECK:STDOUT: interfaces: {} // CHECK:STDOUT: associated_constants: {} @@ -114,21 +114,21 @@ fn Foo(n: ()) -> ((), ()) { // CHECK:STDOUT: inst50000027: {kind: SpliceBlock, arg0: inst_block50000005, arg1: inst50000013, type: type(TypeType)} // CHECK:STDOUT: inst50000028: {kind: OutParam, arg0: call_param1, arg1: name(ReturnSlot), type: type(inst5000001A)} // CHECK:STDOUT: inst50000029: {kind: ReturnSlot, arg0: inst5000001A, arg1: inst50000028, type: type(inst5000001A)} -// CHECK:STDOUT: inst5000002A: {kind: FunctionDecl, arg0: function50000000, arg1: inst_block5000000F, type: type(inst5000002B)} +// CHECK:STDOUT: inst5000002A: {kind: FunctionDecl, arg0: function50000000, arg1: inst_block5000000E, type: type(inst5000002B)} // CHECK:STDOUT: inst5000002B: {kind: FunctionType, arg0: function50000000, arg1: specific, type: type(TypeType)} // CHECK:STDOUT: inst5000002C: {kind: StructValue, arg0: inst_block_empty, type: type(inst5000002B)} // CHECK:STDOUT: inst5000002D: {kind: NameRef, arg0: name1, arg1: inst50000016, type: type(inst50000010)} // CHECK:STDOUT: inst5000002E: {kind: TupleLiteral, arg0: inst_block_empty, type: type(inst50000010)} -// CHECK:STDOUT: inst5000002F: {kind: TupleLiteral, arg0: inst_block50000011, type: type(inst5000001A)} +// CHECK:STDOUT: inst5000002F: {kind: TupleLiteral, arg0: inst_block50000010, type: type(inst5000001A)} // CHECK:STDOUT: inst50000030: {kind: TupleAccess, arg0: inst50000028, arg1: element0, type: type(inst50000010)} -// CHECK:STDOUT: inst50000031: {kind: TupleInit, arg0: inst_block50000012, arg1: inst50000030, type: type(inst50000010)} +// CHECK:STDOUT: inst50000031: {kind: TupleInit, arg0: inst_block50000011, arg1: inst50000030, type: type(inst50000010)} // CHECK:STDOUT: inst50000032: {kind: Converted, arg0: inst5000002D, arg1: inst50000031, type: type(inst50000010)} // CHECK:STDOUT: inst50000033: {kind: InPlaceInit, arg0: inst50000032, arg1: inst50000030, type: type(inst50000010)} // CHECK:STDOUT: inst50000034: {kind: TupleAccess, arg0: inst50000028, arg1: element1, type: type(inst50000010)} // CHECK:STDOUT: inst50000035: {kind: TupleInit, arg0: inst_block_empty, arg1: inst50000034, type: type(inst50000010)} // CHECK:STDOUT: inst50000036: {kind: Converted, arg0: inst5000002E, arg1: inst50000035, type: type(inst50000010)} // CHECK:STDOUT: inst50000037: {kind: InPlaceInit, arg0: inst50000036, arg1: inst50000034, type: type(inst50000010)} -// CHECK:STDOUT: inst50000038: {kind: TupleInit, arg0: inst_block50000013, arg1: inst50000028, type: type(inst5000001A)} +// CHECK:STDOUT: inst50000038: {kind: TupleInit, arg0: inst_block50000012, arg1: inst50000028, type: type(inst5000001A)} // CHECK:STDOUT: inst50000039: {kind: Converted, arg0: inst5000002F, arg1: inst50000038, type: type(inst5000001A)} // CHECK:STDOUT: inst5000003A: {kind: ReturnExpr, arg0: inst50000039, arg1: inst50000028} // CHECK:STDOUT: constant_values: @@ -194,19 +194,17 @@ fn Foo(n: ()) -> ((), ()) { // CHECK:STDOUT: 0: inst5000001E // CHECK:STDOUT: 1: inst5000001F // CHECK:STDOUT: inst_block5000000B: -// CHECK:STDOUT: 0: inst50000025 -// CHECK:STDOUT: inst_block5000000C: // CHECK:STDOUT: 0: inst50000015 // CHECK:STDOUT: 1: inst50000024 -// CHECK:STDOUT: inst_block5000000D: +// CHECK:STDOUT: inst_block5000000C: // CHECK:STDOUT: 0: inst50000026 // CHECK:STDOUT: 1: inst50000028 -// CHECK:STDOUT: inst_block5000000E: +// CHECK:STDOUT: inst_block5000000D: // CHECK:STDOUT: 0: inst50000015 // CHECK:STDOUT: 1: inst50000017 // CHECK:STDOUT: 2: inst50000024 // CHECK:STDOUT: 3: inst50000025 -// CHECK:STDOUT: inst_block5000000F: +// CHECK:STDOUT: inst_block5000000E: // CHECK:STDOUT: 0: inst50000018 // CHECK:STDOUT: 1: inst50000019 // CHECK:STDOUT: 2: inst5000001B @@ -219,7 +217,7 @@ fn Foo(n: ()) -> ((), ()) { // CHECK:STDOUT: 9: inst50000016 // CHECK:STDOUT: 10: inst50000028 // CHECK:STDOUT: 11: inst50000029 -// CHECK:STDOUT: inst_block50000010: +// CHECK:STDOUT: inst_block5000000F: // CHECK:STDOUT: 0: inst5000002D // CHECK:STDOUT: 1: inst5000002E // CHECK:STDOUT: 2: inst5000002F @@ -234,14 +232,14 @@ fn Foo(n: ()) -> ((), ()) { // CHECK:STDOUT: 11: inst50000038 // CHECK:STDOUT: 12: inst50000039 // CHECK:STDOUT: 13: inst5000003A -// CHECK:STDOUT: inst_block50000011: +// CHECK:STDOUT: inst_block50000010: // CHECK:STDOUT: 0: inst5000002D // CHECK:STDOUT: 1: inst5000002E -// CHECK:STDOUT: inst_block50000012: {} -// CHECK:STDOUT: inst_block50000013: +// CHECK:STDOUT: inst_block50000011: {} +// CHECK:STDOUT: inst_block50000012: // CHECK:STDOUT: 0: inst50000033 // CHECK:STDOUT: 1: inst50000037 -// CHECK:STDOUT: inst_block50000014: +// CHECK:STDOUT: inst_block50000013: // CHECK:STDOUT: 0: instF // CHECK:STDOUT: 1: inst5000002A // CHECK:STDOUT: value_stores: diff --git a/toolchain/check/testdata/class/self/self.carbon b/toolchain/check/testdata/class/self/self.carbon index f7df2d87d35e..0f01c4a7bfa6 100644 --- a/toolchain/check/testdata/class/self/self.carbon +++ b/toolchain/check/testdata/class/self/self.carbon @@ -231,12 +231,14 @@ class Class { // CHECK:STDOUT: %Class.F.decl: %Class.F.type = fn_decl @Class.F [concrete = constants.%Class.F] { // CHECK:STDOUT: %self.param_patt: %pattern_type.904 = value_param_pattern [concrete] // CHECK:STDOUT: %self.patt: %pattern_type.904 = at_binding_pattern self, %self.param_patt [concrete] +// CHECK:STDOUT: %return.patt: = return_slot_pattern , [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %self.ref: %Class = name_ref self, %self // CHECK:STDOUT: %.loc12: type = converted %self.ref, [concrete = ] // CHECK:STDOUT: %self.param: %Class = value_param call_param0 // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] // CHECK:STDOUT: %self: %Class = value_binding self, %self.param +// CHECK:STDOUT: %return: = return_slot // CHECK:STDOUT: } // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type diff --git a/toolchain/check/testdata/eval/call.carbon b/toolchain/check/testdata/eval/call.carbon index f1b7eaed8600..89137726653c 100644 --- a/toolchain/check/testdata/eval/call.carbon +++ b/toolchain/check/testdata/eval/call.carbon @@ -99,7 +99,7 @@ fn UseFGenerically(X:! i32) { // CHECK:STDERR: var unused v: F(X) = {}; // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~ // CHECK:STDERR: - // CHECK:STDERR: fail_todo_dependent_call_type.carbon:[[@LINE+4]]:3: error: cannot access member of interface `Core.Destroy` in type `` that does not implement that interface [MissingImplInMemberAccess] + // CHECK:STDERR: fail_todo_dependent_call_type.carbon:[[@LINE+4]]:3: error: cannot access member of interface `Core.Destroy` in type `` that does not implement that interface [MissingImplInMemberAccess] // CHECK:STDERR: var unused v: F(X) = {}; // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~ // CHECK:STDERR: diff --git a/toolchain/check/testdata/function/call/form.carbon b/toolchain/check/testdata/function/call/form.carbon index 1664d6ebcb28..e3bc1193d8be 100644 --- a/toolchain/check/testdata/function/call/form.carbon +++ b/toolchain/check/testdata/function/call/form.carbon @@ -434,15 +434,20 @@ fn F(Form:! Core.Form()) ->? Form; // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %.1da: Core.Form = ref_form %i32 [concrete] +// CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} { +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %.loc4_8.1: %pattern_type.7ce = ref_return_pattern [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern %.loc4_8.1, constants.%i32 [concrete] +// CHECK:STDOUT: } { // CHECK:STDOUT: %i32: type = type_literal constants.%i32 [concrete = constants.%i32] -// CHECK:STDOUT: %.loc4: Core.Form = ref_form %i32 [concrete = constants.%.1da] +// CHECK:STDOUT: %.loc4_17: Core.Form = ref_form %i32 [concrete = constants.%.1da] +// CHECK:STDOUT: %.loc4_8.2: ref %i32 = ref_return +// CHECK:STDOUT: %return: ref %i32 = return_slot %.loc4_8.2 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: @@ -519,15 +524,20 @@ fn F(Form:! Core.Form()) ->? Form; // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %.754: Core.Form = value_form %i32 [concrete] +// CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} { +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %.loc4_8.1: %pattern_type.7ce = value_return_pattern [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern %.loc4_8.1, constants.%i32 [concrete] +// CHECK:STDOUT: } { // CHECK:STDOUT: %i32: type = type_literal constants.%i32 [concrete = constants.%i32] -// CHECK:STDOUT: %.loc4: Core.Form = value_form %i32 [concrete = constants.%.754] +// CHECK:STDOUT: %.loc4_17: Core.Form = value_form %i32 [concrete = constants.%.754] +// CHECK:STDOUT: %.loc4_8.2: %i32 = value_return +// CHECK:STDOUT: %return: %i32 = return_slot %.loc4_8.2 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/function/declaration/ref.carbon b/toolchain/check/testdata/function/declaration/ref.carbon index 97f388af078f..c9270d95ada4 100644 --- a/toolchain/check/testdata/function/declaration/ref.carbon +++ b/toolchain/check/testdata/function/declaration/ref.carbon @@ -29,11 +29,11 @@ fn G() { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %.1da: Core.Form = ref_form %i32 [concrete] +// CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] -// CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -52,10 +52,15 @@ fn G() { // CHECK:STDOUT: .G = %G.decl // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} { +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %.loc4_8.1: %pattern_type.7ce = ref_return_pattern [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern %.loc4_8.1, %i32 [concrete] +// CHECK:STDOUT: } { // CHECK:STDOUT: %i32: type = type_literal constants.%i32 [concrete = constants.%i32] // CHECK:STDOUT: %.loc4_11.1: type = ref_tag %i32 // CHECK:STDOUT: %.loc4_11.2: Core.Form = ref_form %i32 [concrete = constants.%.1da] +// CHECK:STDOUT: %.loc4_8.2: ref %i32 = ref_return +// CHECK:STDOUT: %return: ref %i32 = return_slot %.loc4_8.2 // CHECK:STDOUT: } // CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {} // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/impl/import_use_generic.carbon b/toolchain/check/testdata/impl/import_use_generic.carbon index 1b83ca5718bd..a91d98ee3fe0 100644 --- a/toolchain/check/testdata/impl/import_use_generic.carbon +++ b/toolchain/check/testdata/impl/import_use_generic.carbon @@ -284,13 +284,18 @@ fn H() -> C({}).(I.F)() {} // CHECK:STDOUT: %C: type = class_type @C, @C(constants.%empty_struct_type) [concrete = constants.%C.850] // CHECK:STDOUT: } // CHECK:STDOUT: %c: ref %C.850 = ref_binding c, %c.var [concrete = %c.var] -// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} { +// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] { +// CHECK:STDOUT: %return.patt: = return_slot_pattern , [concrete] +// CHECK:STDOUT: } { // CHECK:STDOUT: %c.ref: ref %C.850 = name_ref c, file.%c [concrete = file.%c.var] // CHECK:STDOUT: %I.ref: type = name_ref I, imports.%Main.I [concrete = constants.%I.type] // CHECK:STDOUT: %F.ref: %I.assoc_type = name_ref F, imports.%Main.import_ref.a54 [concrete = constants.%assoc0] // CHECK:STDOUT: %.loc16: %I.type = converted %c.ref, [concrete = ] +// CHECK:STDOUT: %return: = return_slot // CHECK:STDOUT: } -// CHECK:STDOUT: %H.decl: %H.type = fn_decl @H [concrete = constants.%H] {} { +// CHECK:STDOUT: %H.decl: %H.type = fn_decl @H [concrete = constants.%H] { +// CHECK:STDOUT: %return.patt: = return_slot_pattern , [concrete] +// CHECK:STDOUT: } { // CHECK:STDOUT: %C.ref: %C.type = name_ref C, imports.%Main.C [concrete = constants.%C.generic] // CHECK:STDOUT: %.loc25_14: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] // CHECK:STDOUT: %.loc25_15: type = converted %.loc25_14, constants.%empty_struct_type [concrete = constants.%empty_struct_type] @@ -303,6 +308,7 @@ fn H() -> C({}).(I.F)() {} // CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @C.as.I.impl.F(constants.%empty_struct_type) [concrete = constants.%C.as.I.impl.F.specific_fn] // CHECK:STDOUT: %C.as.I.impl.F.call: init %empty_tuple.type = call %specific_fn() // CHECK:STDOUT: %.loc25_23: type = converted %C.as.I.impl.F.call, [concrete = ] +// CHECK:STDOUT: %return: = return_slot // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/incomplete.carbon b/toolchain/check/testdata/impl/incomplete.carbon index be741ab50168..28da79100c1a 100644 --- a/toolchain/check/testdata/impl/incomplete.carbon +++ b/toolchain/check/testdata/impl/incomplete.carbon @@ -697,10 +697,13 @@ interface B { // CHECK:STDOUT: interface @Incomplete; // CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.I.impl: %C.ref as %.loc8_13 { -// CHECK:STDOUT: %C.as.I.impl.F.decl: %C.as.I.impl.F.type = fn_decl @C.as.I.impl.F [concrete = constants.%C.as.I.impl.F] {} { +// CHECK:STDOUT: %C.as.I.impl.F.decl: %C.as.I.impl.F.type = fn_decl @C.as.I.impl.F [concrete = constants.%C.as.I.impl.F] { +// CHECK:STDOUT: %return.patt: = return_slot_pattern , [concrete] +// CHECK:STDOUT: } { // CHECK:STDOUT: %Self.ref: type = name_ref Self, @C.as.I.impl.%C.ref [concrete = constants.%C] // CHECK:STDOUT: %Incomplete.ref: type = name_ref Incomplete, file.%Incomplete.decl [concrete = constants.%Incomplete.type] // CHECK:STDOUT: %T.ref: = name_ref T, [concrete = ] +// CHECK:STDOUT: %return: = return_slot // CHECK:STDOUT: } // CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (), @C.as.I.impl [concrete] // CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table [concrete = constants.%I.impl_witness] diff --git a/toolchain/check/testdata/impl/use_assoc_entity.carbon b/toolchain/check/testdata/impl/use_assoc_entity.carbon index 1e00e13889fb..6ee488b2ac8e 100644 --- a/toolchain/check/testdata/impl/use_assoc_entity.carbon +++ b/toolchain/check/testdata/impl/use_assoc_entity.carbon @@ -2650,6 +2650,7 @@ fn F() { // CHECK:STDOUT: %E.as.J.impl.F.decl.loc27_21.1: %E.as.J.impl.F.type.4b5c2a.1 = fn_decl @E.as.J.impl.F.loc27_21.1 [concrete = constants.%E.as.J.impl.F.b4e6ab.1] { // CHECK:STDOUT: %u.param_patt: = value_param_pattern [concrete] // CHECK:STDOUT: %u.patt: = at_binding_pattern u, %u.param_patt [concrete] +// CHECK:STDOUT: %return.patt: = return_slot_pattern , [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %U.ref.loc27_19: %J.assoc_type = name_ref U, @U.%assoc0 [concrete = constants.%assoc0.ebd] // CHECK:STDOUT: %.loc27_19: type = converted %U.ref.loc27_19, [concrete = ] @@ -2659,6 +2660,7 @@ fn F() { // CHECK:STDOUT: %.loc27_13: type = converted %U.ref.loc27_13, [concrete = ] // CHECK:STDOUT: } // CHECK:STDOUT: %u: = value_binding u, [concrete = ] +// CHECK:STDOUT: %return: = return_slot // CHECK:STDOUT: } // CHECK:STDOUT: %.loc5_17.1: type = specific_constant @J.WithSelf.F.%U.ref.loc5_17, @J.WithSelf.F(constants.%J.facet) [concrete = constants.%i32] // CHECK:STDOUT: %.loc5_17.2: type = specific_constant @J.WithSelf.F.%.loc5_17.2, @J.WithSelf.F(constants.%J.facet) [concrete = constants.%.ff5] @@ -3158,9 +3160,12 @@ fn F() { // CHECK:STDOUT: requirement_rewrite %impl.elem0, %.loc8_32.2 // CHECK:STDOUT: } // CHECK:STDOUT: } -// CHECK:STDOUT: %E.G.decl: %E.G.type = fn_decl @E.G [concrete = constants.%E.G] {} { +// CHECK:STDOUT: %E.G.decl: %E.G.type = fn_decl @E.G [concrete = constants.%E.G] { +// CHECK:STDOUT: %return.patt: = return_slot_pattern , [concrete] +// CHECK:STDOUT: } { // CHECK:STDOUT: %X.ref: %J.assoc_type = name_ref X, @X.%assoc0 [concrete = constants.%assoc0.df0] // CHECK:STDOUT: %.loc18_13: type = converted %X.ref, [concrete = ] +// CHECK:STDOUT: %return: = return_slot // CHECK:STDOUT: } // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -3304,6 +3309,7 @@ fn F() { // CHECK:STDOUT: %self.patt: @J2.WithSelf.F.%pattern_type (%pattern_type.21d) = at_binding_pattern self, %self.param_patt [concrete] // CHECK:STDOUT: %z.param_patt: = value_param_pattern [concrete] // CHECK:STDOUT: %z.patt: = at_binding_pattern z, %z.param_patt [concrete] +// CHECK:STDOUT: %return.patt: = return_slot_pattern , [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %Self.ref.loc19_35: %J2.type = name_ref Self, @J2.%Self [symbolic = %Self (constants.%Self)] // CHECK:STDOUT: %Self.as_type.loc19_39: type = facet_access_type %Self.ref.loc19_35 [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] @@ -3324,6 +3330,7 @@ fn F() { // CHECK:STDOUT: %U2.ref.loc19_27: = name_ref U2, [concrete = ] // CHECK:STDOUT: } // CHECK:STDOUT: %z: = value_binding z, [concrete = ] +// CHECK:STDOUT: %return: = return_slot // CHECK:STDOUT: } // CHECK:STDOUT: %assoc1: %J2.assoc_type = assoc_entity element1, %J2.WithSelf.F.decl [concrete = constants.%assoc1] // CHECK:STDOUT: @@ -3365,9 +3372,11 @@ fn F() { // CHECK:STDOUT: %empty_tuple.type.as.J2.impl.F.decl.loc23_40.2: %empty_tuple.type.as.J2.impl.F.type.56bdaf.2 = fn_decl @empty_tuple.type.as.J2.impl.F.loc23_40.2 [concrete = constants.%empty_tuple.type.as.J2.impl.F.7b8679.2] { // CHECK:STDOUT: %self.param_patt: %pattern_type.cb1 = value_param_pattern [concrete] // CHECK:STDOUT: %self.patt: %pattern_type.cb1 = at_binding_pattern self, %self.param_patt [concrete] +// CHECK:STDOUT: %return.patt: = return_slot_pattern , invalid [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %self.param: %empty_tuple.type = value_param call_param0 // CHECK:STDOUT: %self: %empty_tuple.type = value_binding self, %self.param +// CHECK:STDOUT: %return: = return_slot // CHECK:STDOUT: } // CHECK:STDOUT: %J2.impl_witness_table = impl_witness_table (%impl_witness_assoc_constant, %empty_tuple.type.as.J2.impl.F.decl.loc23_40.2), @empty_tuple.type.as.J2.impl [concrete] // CHECK:STDOUT: %J2.impl_witness: = impl_witness %J2.impl_witness_table [concrete = constants.%J2.impl_witness.941] @@ -3403,9 +3412,11 @@ fn F() { // CHECK:STDOUT: %C2.as.J2.impl.F.decl.loc32_40.2: %C2.as.J2.impl.F.type.d2a210.2 = fn_decl @C2.as.J2.impl.F.loc32_40.2 [concrete = constants.%C2.as.J2.impl.F.720bb2.2] { // CHECK:STDOUT: %self.param_patt: %pattern_type.8df = value_param_pattern [concrete] // CHECK:STDOUT: %self.patt: %pattern_type.8df = at_binding_pattern self, %self.param_patt [concrete] +// CHECK:STDOUT: %return.patt: = return_slot_pattern , invalid [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %self.param: %C2 = value_param call_param0 // CHECK:STDOUT: %self: %C2 = value_binding self, %self.param +// CHECK:STDOUT: %return: = return_slot // CHECK:STDOUT: } // CHECK:STDOUT: %J2.impl_witness_table = impl_witness_table (%impl_witness_assoc_constant, %C2.as.J2.impl.F.decl.loc32_40.2), @C2.as.J2.impl [concrete] // CHECK:STDOUT: %J2.impl_witness: = impl_witness %J2.impl_witness_table [concrete = constants.%J2.impl_witness.30f] diff --git a/toolchain/check/testdata/interface/fail_lookup_undefined.carbon b/toolchain/check/testdata/interface/fail_lookup_undefined.carbon index c36a8de270b8..5f282a71a3d1 100644 --- a/toolchain/check/testdata/interface/fail_lookup_undefined.carbon +++ b/toolchain/check/testdata/interface/fail_lookup_undefined.carbon @@ -87,9 +87,12 @@ interface BeingDefined { // CHECK:STDOUT: %BeingDefined.WithSelf.decl = interface_with_self_decl @BeingDefined [concrete] // CHECK:STDOUT: // CHECK:STDOUT: !with Self: -// CHECK:STDOUT: %BeingDefined.WithSelf.H.decl: @BeingDefined.WithSelf.%BeingDefined.WithSelf.H.type (%BeingDefined.WithSelf.H.type) = fn_decl @BeingDefined.WithSelf.H [symbolic = @BeingDefined.WithSelf.%BeingDefined.WithSelf.H (constants.%BeingDefined.WithSelf.H)] {} { +// CHECK:STDOUT: %BeingDefined.WithSelf.H.decl: @BeingDefined.WithSelf.%BeingDefined.WithSelf.H.type (%BeingDefined.WithSelf.H.type) = fn_decl @BeingDefined.WithSelf.H [symbolic = @BeingDefined.WithSelf.%BeingDefined.WithSelf.H (constants.%BeingDefined.WithSelf.H)] { +// CHECK:STDOUT: %return.patt: = return_slot_pattern , [concrete] +// CHECK:STDOUT: } { // CHECK:STDOUT: %BeingDefined.ref: type = name_ref BeingDefined, file.%BeingDefined.decl [concrete = constants.%BeingDefined.type] // CHECK:STDOUT: %T.ref: = name_ref T, [concrete = ] +// CHECK:STDOUT: %return: = return_slot // CHECK:STDOUT: } // CHECK:STDOUT: %assoc0: %BeingDefined.assoc_type = assoc_entity element0, %BeingDefined.WithSelf.H.decl [concrete = constants.%assoc0] // CHECK:STDOUT: %BeingDefined.WithSelf.I.decl: @BeingDefined.WithSelf.%BeingDefined.WithSelf.I.type (%BeingDefined.WithSelf.I.type) = fn_decl @BeingDefined.WithSelf.I [symbolic = @BeingDefined.WithSelf.%BeingDefined.WithSelf.I (constants.%BeingDefined.WithSelf.I)] {} {} diff --git a/toolchain/check/testdata/interface/fail_member_lookup.carbon b/toolchain/check/testdata/interface/fail_member_lookup.carbon index 47c6449080a7..21c895fc5eaf 100644 --- a/toolchain/check/testdata/interface/fail_member_lookup.carbon +++ b/toolchain/check/testdata/interface/fail_member_lookup.carbon @@ -97,6 +97,7 @@ fn G(U:! Different) -> U.(Interface.T); // CHECK:STDOUT: %Different.decl: type = interface_decl @Different [concrete = constants.%Different.type] {} {} // CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] { // CHECK:STDOUT: %U.patt: %pattern_type.cb4 = symbolic_binding_pattern U, 0 [concrete] +// CHECK:STDOUT: %return.patt: = return_slot_pattern , [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %U.ref: %Different.type = name_ref U, %U.loc32_7.2 [symbolic = %U.loc32_7.1 (constants.%U)] // CHECK:STDOUT: %Interface.ref: type = name_ref Interface, file.%Interface.decl [concrete = constants.%Interface.type] @@ -107,6 +108,7 @@ fn G(U:! Different) -> U.(Interface.T); // CHECK:STDOUT: %Different.ref: type = name_ref Different, file.%Different.decl [concrete = constants.%Different.type] // CHECK:STDOUT: } // CHECK:STDOUT: %U.loc32_7.2: %Different.type = symbolic_binding U, 0 [symbolic = %U.loc32_7.1 (constants.%U)] +// CHECK:STDOUT: %return: = return_slot // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/let/compile_time_bindings.carbon b/toolchain/check/testdata/let/compile_time_bindings.carbon index 3f6c2bbf93c7..d905e00f4caa 100644 --- a/toolchain/check/testdata/let/compile_time_bindings.carbon +++ b/toolchain/check/testdata/let/compile_time_bindings.carbon @@ -622,8 +622,11 @@ impl i32 as Empty { // CHECK:STDOUT: %.loc9_11.2: type = type_literal type [concrete = type] // CHECK:STDOUT: } // CHECK:STDOUT: %T: type = value_binding T, %i32 -// CHECK:STDOUT: %I.F.decl: %I.F.type = fn_decl @I.F [concrete = constants.%I.F] {} { +// CHECK:STDOUT: %I.F.decl: %I.F.type = fn_decl @I.F [concrete = constants.%I.F] { +// CHECK:STDOUT: %return.patt: = return_slot_pattern , [concrete] +// CHECK:STDOUT: } { // CHECK:STDOUT: %T.ref: type = name_ref T, @I.%T +// CHECK:STDOUT: %return: = return_slot // CHECK:STDOUT: } // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -674,8 +677,11 @@ impl i32 as Empty { // CHECK:STDOUT: %.loc8_9.2: type = type_literal type [concrete = type] // CHECK:STDOUT: } // CHECK:STDOUT: %T: type = value_binding T, @__global_init.%i32 -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} { +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %return.patt: = return_slot_pattern , [concrete] +// CHECK:STDOUT: } { // CHECK:STDOUT: %T.ref: type = name_ref T, file.%T +// CHECK:STDOUT: %return: = return_slot // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/packages/export_import.carbon b/toolchain/check/testdata/packages/export_import.carbon index 8d1f193d0aac..e5aed17db6ce 100644 --- a/toolchain/check/testdata/packages/export_import.carbon +++ b/toolchain/check/testdata/packages/export_import.carbon @@ -900,8 +900,11 @@ export Poison; // CHECK:STDOUT: .Poison = // CHECK:STDOUT: .F = %F.decl // CHECK:STDOUT: } -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} { +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %return.patt: = return_slot_pattern , [concrete] +// CHECK:STDOUT: } { // CHECK:STDOUT: %Poison.ref: = name_ref Poison, [concrete = ] +// CHECK:STDOUT: %return: = return_slot // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/return/fail_call_in_type.carbon b/toolchain/check/testdata/return/fail_call_in_type.carbon index 27d23226c0f5..804ae40792d3 100644 --- a/toolchain/check/testdata/return/fail_call_in_type.carbon +++ b/toolchain/check/testdata/return/fail_call_in_type.carbon @@ -74,11 +74,14 @@ fn Six() -> ReturnType() { return 6; } // CHECK:STDOUT: %return.param: ref type = out_param call_param0 // CHECK:STDOUT: %return: ref type = return_slot %return.param // CHECK:STDOUT: } -// CHECK:STDOUT: %Six.decl: %Six.type = fn_decl @Six [concrete = constants.%Six] {} { +// CHECK:STDOUT: %Six.decl: %Six.type = fn_decl @Six [concrete = constants.%Six] { +// CHECK:STDOUT: %return.patt: = return_slot_pattern , [concrete] +// CHECK:STDOUT: } { // CHECK:STDOUT: %ReturnType.ref: %ReturnType.type = name_ref ReturnType, file.%ReturnType.decl [concrete = constants.%ReturnType] // CHECK:STDOUT: %ReturnType.call: init type = call %ReturnType.ref() // CHECK:STDOUT: %.loc22_24.1: type = value_of_initializer %ReturnType.call // CHECK:STDOUT: %.loc22_24.2: type = converted %ReturnType.call, %.loc22_24.1 +// CHECK:STDOUT: %return: = return_slot // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/return/fail_error_in_type.carbon b/toolchain/check/testdata/return/fail_error_in_type.carbon index e55c89d9a699..03f67e3c5cba 100644 --- a/toolchain/check/testdata/return/fail_error_in_type.carbon +++ b/toolchain/check/testdata/return/fail_error_in_type.carbon @@ -39,8 +39,11 @@ fn Six() -> x; // CHECK:STDOUT: .Six = %Six.decl // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core -// CHECK:STDOUT: %Six.decl: %Six.type = fn_decl @Six [concrete = constants.%Six] {} { +// CHECK:STDOUT: %Six.decl: %Six.type = fn_decl @Six [concrete = constants.%Six] { +// CHECK:STDOUT: %return.patt: = return_slot_pattern , [concrete] +// CHECK:STDOUT: } { // CHECK:STDOUT: %x.ref: = name_ref x, [concrete = ] +// CHECK:STDOUT: %return: = return_slot // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/return/fail_let_in_type.carbon b/toolchain/check/testdata/return/fail_let_in_type.carbon index 13e3b906ca01..c52568a25acc 100644 --- a/toolchain/check/testdata/return/fail_let_in_type.carbon +++ b/toolchain/check/testdata/return/fail_let_in_type.carbon @@ -87,8 +87,11 @@ fn FirstPerfectNumber() -> z { return 6; } // CHECK:STDOUT: } // CHECK:STDOUT: %.loc15: type = type_literal type [concrete = type] // CHECK:STDOUT: %x: type = value_binding x, @__global_init.%i32.loc15 -// CHECK:STDOUT: %Six.decl: %Six.type = fn_decl @Six [concrete = constants.%Six] {} { +// CHECK:STDOUT: %Six.decl: %Six.type = fn_decl @Six [concrete = constants.%Six] { +// CHECK:STDOUT: %return.patt: = return_slot_pattern , [concrete] +// CHECK:STDOUT: } { // CHECK:STDOUT: %x.ref: type = name_ref x, file.%x +// CHECK:STDOUT: %return: = return_slot // CHECK:STDOUT: } // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %y.patt: %pattern_type.98f = value_binding_pattern y [concrete] @@ -98,8 +101,11 @@ fn FirstPerfectNumber() -> z { return 6; } // CHECK:STDOUT: %.loc27_9.2: type = type_literal type [concrete = type] // CHECK:STDOUT: } // CHECK:STDOUT: %y: type = value_binding y, @__global_init.%i32.loc27 -// CHECK:STDOUT: %HalfDozen.decl: %HalfDozen.type = fn_decl @HalfDozen [concrete = constants.%HalfDozen] {} { +// CHECK:STDOUT: %HalfDozen.decl: %HalfDozen.type = fn_decl @HalfDozen [concrete = constants.%HalfDozen] { +// CHECK:STDOUT: %return.patt: = return_slot_pattern , [concrete] +// CHECK:STDOUT: } { // CHECK:STDOUT: %y.ref: type = name_ref y, file.%y +// CHECK:STDOUT: %return: = return_slot // CHECK:STDOUT: } // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %z.patt: %pattern_type.98f = value_binding_pattern z [concrete] @@ -109,8 +115,11 @@ fn FirstPerfectNumber() -> z { return 6; } // CHECK:STDOUT: %.loc39_18.2: type = type_literal type [concrete = type] // CHECK:STDOUT: } // CHECK:STDOUT: %z: type = value_binding z, @__global_init.%i32.loc39 -// CHECK:STDOUT: %FirstPerfectNumber.decl: %FirstPerfectNumber.type = fn_decl @FirstPerfectNumber [concrete = constants.%FirstPerfectNumber] {} { +// CHECK:STDOUT: %FirstPerfectNumber.decl: %FirstPerfectNumber.type = fn_decl @FirstPerfectNumber [concrete = constants.%FirstPerfectNumber] { +// CHECK:STDOUT: %return.patt: = return_slot_pattern , [concrete] +// CHECK:STDOUT: } { // CHECK:STDOUT: %z.ref: type = name_ref z, file.%z +// CHECK:STDOUT: %return: = return_slot // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/return/fail_var_in_type.carbon b/toolchain/check/testdata/return/fail_var_in_type.carbon index 3b198de4897c..c0e62d3380bb 100644 --- a/toolchain/check/testdata/return/fail_var_in_type.carbon +++ b/toolchain/check/testdata/return/fail_var_in_type.carbon @@ -67,9 +67,12 @@ fn Six() -> x { return 6; } // CHECK:STDOUT: %x.var: ref type = var %x.var_patt [concrete] // CHECK:STDOUT: %.loc15: type = type_literal type [concrete = type] // CHECK:STDOUT: %x: ref type = ref_binding x, %x.var [concrete = %x.var] -// CHECK:STDOUT: %Six.decl: %Six.type = fn_decl @Six [concrete = constants.%Six] {} { +// CHECK:STDOUT: %Six.decl: %Six.type = fn_decl @Six [concrete = constants.%Six] { +// CHECK:STDOUT: %return.patt: = return_slot_pattern , [concrete] +// CHECK:STDOUT: } { // CHECK:STDOUT: %x.ref: ref type = name_ref x, file.%x [concrete = file.%x.var] // CHECK:STDOUT: %.loc20: type = acquire_value %x.ref +// CHECK:STDOUT: %return: = return_slot // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/struct/fail_duplicate_name.carbon b/toolchain/check/testdata/struct/fail_duplicate_name.carbon index fad33070cca0..6a6f213c1f07 100644 --- a/toolchain/check/testdata/struct/fail_duplicate_name.carbon +++ b/toolchain/check/testdata/struct/fail_duplicate_name.carbon @@ -98,12 +98,15 @@ var y: {.b: i32, .c: i32} = {.b = 3, .b = 4}; // CHECK:STDOUT: .y = %y // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} { +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %return.patt: = return_slot_pattern , [concrete] +// CHECK:STDOUT: } { // CHECK:STDOUT: %i32.loc22_16: type = type_literal constants.%i32 [concrete = constants.%i32] // CHECK:STDOUT: %i32.loc22_27: type = type_literal constants.%i32 [concrete = constants.%i32] // CHECK:STDOUT: %i32.loc22_36: type = type_literal constants.%i32 [concrete = constants.%i32] // CHECK:STDOUT: %i32.loc22_47: type = type_literal constants.%i32 [concrete = constants.%i32] // CHECK:STDOUT: %i32.loc22_56: type = type_literal constants.%i32 [concrete = constants.%i32] +// CHECK:STDOUT: %return: = return_slot // CHECK:STDOUT: } // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %v.patt: = value_binding_pattern v [concrete] diff --git a/toolchain/check/thunk.cpp b/toolchain/check/thunk.cpp index c4e8a6a8a5df..48d03c62d615 100644 --- a/toolchain/check/thunk.cpp +++ b/toolchain/check/thunk.cpp @@ -125,10 +125,27 @@ static auto ClonePattern(Context& context, SemIR::SpecificId specific_id, new_pattern_id = CloneBindingPattern(context, pattern_id, *binding, get_type(pattern_id)); } else if (auto return_slot = pattern.TryAs()) { - auto new_subpattern_id = RebuildPatternInst( - context, return_slot->subpattern_id, - {.type_id = get_type(return_slot->subpattern_id), - .pretty_name_id = SemIR::NameId::ReturnSlot}); + auto new_subpattern_id = SemIR::InstId::None; + auto subpattern = context.insts().Get(return_slot->subpattern_id); + CARBON_KIND_SWITCH(subpattern) { + case SemIR::OutParamPattern::Kind: + case SemIR::RefReturnPattern::Kind: + case SemIR::ValueReturnPattern::Kind: + // These are leaf insts, so we can reuse their contents after updating + // the type. + subpattern.SetType(get_type(return_slot->subpattern_id)); + new_subpattern_id = + RebuildPatternInst(context, return_slot->subpattern_id, subpattern); + break; + case SemIR::ErrorInst::Kind: + subpattern.SetType(SemIR::ErrorInst::TypeId); + new_subpattern_id = SemIR::ErrorInst::InstId; + break; + default: + CARBON_FATAL("Unexpected kind for return slot subpattern {0}", + subpattern); + } + new_pattern_id = RebuildPatternInst( context, pattern_id, {.type_id = get_type(pattern_id), @@ -200,8 +217,8 @@ 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_patterns_id = ClonePatternBlock(context, signature_specific_id, - signature.return_patterns_id); + auto return_pattern_id = + ClonePattern(context, signature_specific_id, signature.return_pattern_id); auto return_type_inst_id = CloneTypeInstId(context, signature_specific_id, signature.return_type_inst_id); auto return_form_inst_id = CloneInstId(context, signature_specific_id, @@ -211,9 +228,8 @@ static auto CloneFunctionDecl(Context& context, SemIR::LocId loc_id, // Perform callee-side pattern matching to rebuild the parameter list. context.inst_block_stack().Push(); - auto match_results = - CalleePatternMatch(context, implicit_param_patterns_id, param_patterns_id, - return_patterns_id); + auto match_results = CalleePatternMatch(context, implicit_param_patterns_id, + param_patterns_id, return_pattern_id); auto decl_block_id = context.inst_block_stack().Pop(); // Create the `FunctionDecl` instruction. @@ -244,7 +260,7 @@ static auto CloneFunctionDecl(Context& context, SemIR::LocId loc_id, .call_param_ranges = match_results.param_ranges, .return_type_inst_id = return_type_inst_id, .return_form_inst_id = return_form_inst_id, - .return_patterns_id = return_patterns_id, + .return_pattern_id = return_pattern_id, .virtual_modifier = callee.virtual_modifier, .virtual_index = callee.virtual_index, .evaluation_mode = signature.evaluation_mode, diff --git a/toolchain/lower/handle.cpp b/toolchain/lower/handle.cpp index a2edb0c49f87..b67a47c7dd8f 100644 --- a/toolchain/lower/handle.cpp +++ b/toolchain/lower/handle.cpp @@ -321,6 +321,15 @@ auto HandleInst(FunctionContext& context, SemIR::InstId /*inst_id*/, } } +auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, + SemIR::RefReturn /*inst*/) -> void { + // A `RefReturn` is a placeholder that represents the absence of a storage + // location, so it should never actually be used, but in some cases it will + // be propagated, so we poison it. + context.SetLocal(inst_id, + llvm::PoisonValue::get(context.GetTypeOfInst(inst_id))); +} + auto HandleInst(FunctionContext& /*context*/, SemIR::InstId /*inst_id*/, SemIR::SpecificFunction /*inst*/) -> void { // Nothing to do. This value should never be consumed. @@ -367,6 +376,15 @@ auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, llvm::PoisonValue::get(context.GetTypeOfInst(inst_id))); } +auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, + SemIR::ValueReturn /*inst*/) -> void { + // A `ValueReturn` is a placeholder that represents the absence of a storage + // location, so it should never actually be used, but in some cases it will + // be propagated, so we poison it. + context.SetLocal(inst_id, + llvm::PoisonValue::get(context.GetTypeOfInst(inst_id))); +} + auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, SemIR::VarStorage /* inst */) -> void { context.SetLocal(inst_id, diff --git a/toolchain/sem_ir/function.h b/toolchain/sem_ir/function.h index b25d08f3eeca..c42046958ddc 100644 --- a/toolchain/sem_ir/function.h +++ b/toolchain/sem_ir/function.h @@ -116,16 +116,13 @@ struct FunctionFields { // any. InstId return_form_inst_id; - // The 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. + // The parameter pattern inst that is declared by the function's return + // declaration. This will be a ReturnSlotPattern, or None if the function + // doesn't have a return declaration. It 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. - InstBlockId return_patterns_id; + // TODO: Extend this to support composite return forms. + InstId return_pattern_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 @@ -195,8 +192,8 @@ struct Function : public EntityWithParamsBase, if (return_type_inst_id.has_value()) { out << ", return_form_inst_id: " << return_form_inst_id; } - if (return_patterns_id.has_value()) { - out << ", return_patterns_id: " << return_patterns_id; + if (return_pattern_id.has_value()) { + out << ", return_pattern_id: " << return_pattern_id; } if (!body_block_ids.empty()) { out << llvm::formatv( diff --git a/toolchain/sem_ir/inst_categories.h b/toolchain/sem_ir/inst_categories.h index fbcd30dc78cd..9dfea264ae60 100644 --- a/toolchain/sem_ir/inst_categories.h +++ b/toolchain/sem_ir/inst_categories.h @@ -387,6 +387,22 @@ struct AnyStructType { AnyRawId arg1; }; +// clang-format off +#define AnyReturnPattern_CARBON_INST_CATEGORY(X, Sep) \ + X(::Carbon::SemIR::RefReturnPattern) Sep() \ + X(::Carbon::SemIR::ValueReturnPattern) +// clang-format on + +#define AnyReturnPattern_CARBON_KIND_ANY_EXPAND \ + CARBON_INST_CATEGORY_ANY_EXPAND(AnyReturnPattern) + +struct AnyReturnPattern { + using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyReturnPattern); + + InstKind kind; + TypeId type_id; +}; + // clang-format off #define AnyVarPattern_CARBON_INST_CATEGORY(X, Sep) \ X(::Carbon::SemIR::VarParamPattern) Sep() \ diff --git a/toolchain/sem_ir/inst_kind.def b/toolchain/sem_ir/inst_kind.def index 14189ef9ced5..f045bfaaf9af 100644 --- a/toolchain/sem_ir/inst_kind.def +++ b/toolchain/sem_ir/inst_kind.def @@ -119,6 +119,8 @@ CARBON_SEM_IR_INST_KIND(RefBindingPattern) CARBON_SEM_IR_INST_KIND(RefForm) CARBON_SEM_IR_INST_KIND(RefParam) CARBON_SEM_IR_INST_KIND(RefParamPattern) +CARBON_SEM_IR_INST_KIND(RefReturn) +CARBON_SEM_IR_INST_KIND(RefReturnPattern) CARBON_SEM_IR_INST_KIND(RefTagExpr) CARBON_SEM_IR_INST_KIND(RefineTypeAction) CARBON_SEM_IR_INST_KIND(RequireCompleteType) @@ -171,6 +173,8 @@ CARBON_SEM_IR_INST_KIND(ValueForm) CARBON_SEM_IR_INST_KIND(ValueOfInitializer) CARBON_SEM_IR_INST_KIND(ValueParam) CARBON_SEM_IR_INST_KIND(ValueParamPattern) +CARBON_SEM_IR_INST_KIND(ValueReturn) +CARBON_SEM_IR_INST_KIND(ValueReturnPattern) CARBON_SEM_IR_INST_KIND(VarParamPattern) CARBON_SEM_IR_INST_KIND(VarPattern) CARBON_SEM_IR_INST_KIND(VarStorage) diff --git a/toolchain/sem_ir/typed_insts.h b/toolchain/sem_ir/typed_insts.h index f3d421f15c05..919dca8bffff 100644 --- a/toolchain/sem_ir/typed_insts.h +++ b/toolchain/sem_ir/typed_insts.h @@ -1490,6 +1490,32 @@ struct RefParamPattern { NameId pretty_name_id; }; +// Represents a reference return form within the function body, in the same +// way that `OutParam` represents an initializing return form. It is used where +// output storage would otherwise be expected, and signifies that the output +// in question is not written to memory, but is instead returned directly, +// as the result (or part of the result) of the `Call` inst. +struct RefReturn { + static constexpr auto Kind = InstKind::RefReturn.Define( + {.ir_name = "ref_return", + .expr_category = ExprCategory::EphemeralRef, + .constant_kind = InstConstantKind::Never}); + + TypeId type_id; +}; + +// A pattern that represents a reference return form, in the same way that an +// OutParamPattern represents an initializing return form. +struct RefReturnPattern { + static constexpr auto Kind = InstKind::RefReturnPattern.Define( + {.ir_name = "ref_return_pattern", + .expr_category = ExprCategory::Pattern, + .constant_kind = InstConstantKind::AlwaysUnique, + .is_lowered = false}); + + TypeId type_id; +}; + // A `ref x` expression. The semantics of this instruction depend on the usage // context: // - As an argument to a `ref` parameter, it evaluates to `x`, but requires @@ -1656,7 +1682,7 @@ struct ReturnExpr { struct ReturnSlot { static constexpr auto Kind = InstKind::ReturnSlot.Define( {.ir_name = "return_slot", - .expr_category = ExprCategory::DurableRef, + .expr_category = ComputedExprCategory::SameAsSecondOperand, .constant_kind = InstConstantKind::Never}); // The type of the value that will be stored in this slot (i.e. the return @@ -2212,6 +2238,33 @@ struct ValueParamPattern { NameId pretty_name_id; }; +// Represents a value return form within the function body, in the same way +// that `OutParam` represents an initializing return form. It is used where +// output storage would otherwise be expected, and signifies that the output +// in question is not written to memory, but is instead returned directly, +// as the result (or part of the result) of the `Call` inst. +struct ValueReturn { + static constexpr auto Kind = InstKind::ValueReturn.Define( + {.ir_name = "value_return", + .expr_category = ExprCategory::Value, + .constant_kind = InstConstantKind::Never}); + + TypeId type_id; +}; + +// A pattern that represents a value return form, in the same way that an +// OutParamPattern represents an initializing return form. +struct ValueReturnPattern { + static constexpr auto Kind = + InstKind::ValueReturnPattern.Define( + {.ir_name = "value_return_pattern", + .expr_category = ExprCategory::Pattern, + .constant_kind = InstConstantKind::AlwaysUnique, + .is_lowered = false}); + + TypeId type_id; +}; + // A `var` pattern that is a `Call` parameter. See `AnyVarPattern` for member // documentation. Note that there is no `VarParam` -- a `VarParamPattern` // corresponds to a `RefParam`.