Restructure return declaration handling (#7076)

- A function with a return declaration always has exactly one
`ReturnSlotPattern`, representing the whole return declaration (whereas
previously that was omitted for value and reference returns).
- The `ReturnSlotPattern` always has a subpattern with the same form.
`OutParamPattern` already plays that role for initializing forms, and
`TuplePattern` will play that role for tuple forms. This change
introduces `ValueReturnPattern` and `RefReturnPattern` to represent
value and reference return forms.
- As before, the `ReturnSlotPattern` has a corresponding `ReturnSlot`
that represents the output that is initialized by a `return` statement.
Its structure parallels the structure of the `ReturnSlotPattern`, so we
need `ValueReturn` and `RefReturn` insts that correspond to
`ValueReturnPattern` and `RefReturnPattern`.

This is a step toward supporting generic return forms, where the
`ReturnSlotPattern`'s subpattern may be an action: this change ensures
that evaluating the action for a specific form produces the same SemIR
as if the form were concrete to begin with. More speculatively, this
should simplify the implementation of `return` statements with compound
return forms.

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
This commit is contained in:
Geoff Romer
2026-04-22 23:38:21 +00:00
committed by GitHub
co-authored by Chandler Carruth
parent 3abc334c42
commit 49c7288619
40 changed files with 598 additions and 390 deletions
+8 -9
View File
@@ -236,17 +236,16 @@ auto PerformCallToFunction(Context& context, SemIR::LocId loc_id,
return_type_id = GetTupleType(context, {});
}
llvm::SmallVector<SemIR::InstId, 1> 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<SemIR::TemporaryStorage>(
context, loc_id, {.type_id = arg_type_id}));
return_arg_id = AddInst<SemIR::TemporaryStorage>(
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: {
+4 -5
View File
@@ -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<SemIR::InstId> arg_refs,
llvm::ArrayRef<SemIR::InstId> 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);
}
+1 -2
View File
@@ -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<SemIR::InstId> arg_refs,
llvm::ArrayRef<SemIR::InstId> 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;
+12 -14
View File
@@ -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<SemIR::InitForm>(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,
+7 -8
View File
@@ -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
+36 -29
View File
@@ -32,42 +32,52 @@ auto FindSelfPattern(Context& context,
});
}
auto AddReturnPatterns(Context& context, SemIR::LocId loc_id,
Context::FormExpr form_expr) -> SemIR::InstBlockId {
llvm::SmallVector<SemIR::InstId, 1> 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<SemIR::RefReturnPattern>(context, loc_id,
{.type_id = result_type_id});
break;
}
case SemIR::ValueForm::Kind: {
result_type_id = GetPatternType(context, form_expr.type_component_id);
result_id = AddInst<SemIR::ValueReturnPattern>(
context, loc_id, {.type_id = result_type_id});
break;
}
case CARBON_KIND(SemIR::InitForm _): {
auto pattern_type_id =
GetPatternType(context, form_expr.type_component_id);
auto out_param_id = AddInst<SemIR::OutParamPattern>(
result_type_id = GetPatternType(context, form_expr.type_component_id);
result_id = AddInst<SemIR::OutParamPattern>(
context, SemIR::LocId(form_expr.form_inst_id),
{.type_id = pattern_type_id,
{.type_id = result_type_id,
.pretty_name_id = SemIR::NameId::ReturnSlot});
return_patterns.push_back(AddInst<SemIR::ReturnSlotPattern>(
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<SemIR::ReturnSlotPattern>(
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.
+2 -2
View File
@@ -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,
+1 -1
View File
@@ -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}}}));
}
+9 -9
View File
@@ -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<SemIR::FunctionId, SemIR::InstId> {
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<Parse::NodeCategory::ReturnDecl>();
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}};
+1 -1
View File
@@ -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);
+27 -5
View File
@@ -1568,6 +1568,23 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, ParamPatternT inst,
.pretty_name_id = name_id});
}
template <typename ReturnPatternT>
requires SemIR::Internal::HasInstCategory<SemIR::AnyReturnPattern,
ReturnPatternT>
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<ReturnPatternT>(
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);
}
+3 -3
View File
@@ -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;
+2 -2
View File
@@ -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
+1 -1
View File
@@ -404,7 +404,7 @@ class NodeStack {
Parse::NodeCategory::Modifier,
Id::Kind::None);
set_id_if_category_is(Parse::NodeCategory::ReturnDecl,
Id::KindFor<SemIR::InstBlockId>());
Id::KindFor<SemIR::InstId>());
return result;
}
+37 -14
View File
@@ -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<CalleeState*>(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<SemIR::InstId> arg_refs,
llvm::ArrayRef<SemIR::InstId> 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);
+5 -5
View File
@@ -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<SemIR::InstId> arg_refs,
llvm::ArrayRef<SemIR::InstId> 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.
+207 -219
View File
@@ -337,12 +337,12 @@ fn Foo[T:! type](p: T*) -> (T*, ()) {
// CHECK:STDOUT: entity_name7800003F: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0, form: inst<none>}
// 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<none>}
// 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<none>}
// 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<none>, 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<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000003: {generic: generic78000001, args: inst_block78000025, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, 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<none>, 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<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000008: {generic: generic78000001, args: inst_block78000032, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000009: {generic: generic78000002, args: inst_block78000032, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific7800000A: {generic: generic78000003, args: inst_block78000038, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, 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<none>, decl_has_error: 0, definition_block_id: inst_block<none>, 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<none>, 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<none>, 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<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000012: {generic: generic78000001, args: inst_block78000059, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000013: {generic: generic78000002, args: inst_block78000059, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000014: {generic: generic78000001, args: inst_block7800005B, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000015: {generic: generic78000002, args: inst_block7800005B, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000016: {generic: generic78000007, args: inst_block78000061, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, 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<none>, 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<none>, definition_has_error: 0}
// CHECK:STDOUT: specific7800001B: {generic: generic78000001, args: inst_block78000076, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific7800001C: {generic: generic78000002, args: inst_block78000076, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific7800001D: {generic: generic78000001, args: inst_block78000078, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific7800001E: {generic: generic78000002, args: inst_block78000078, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific7800001F: {generic: generic78000001, args: inst_block7800007A, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000020: {generic: generic78000002, args: inst_block7800007A, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000021: {generic: generic78000009, args: inst_block78000080, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000022: {generic: generic78000005, args: inst_block78000087, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, 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<none>, decl_has_error: 0, definition_block_id: inst_block<none>, 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<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000026: {generic: generic78000002, args: inst_block7800008C, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, 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<none>, 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<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000003: {generic: generic78000001, args: inst_block78000023, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, 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<none>, 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<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000008: {generic: generic78000001, args: inst_block7800002F, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000009: {generic: generic78000002, args: inst_block7800002F, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific7800000A: {generic: generic78000003, args: inst_block78000035, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, 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<none>, decl_has_error: 0, definition_block_id: inst_block<none>, 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<none>, 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<none>, 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<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000012: {generic: generic78000001, args: inst_block78000054, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000013: {generic: generic78000002, args: inst_block78000054, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000014: {generic: generic78000001, args: inst_block78000056, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000015: {generic: generic78000002, args: inst_block78000056, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000016: {generic: generic78000007, args: inst_block7800005C, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, 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<none>, 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<none>, definition_has_error: 0}
// CHECK:STDOUT: specific7800001B: {generic: generic78000001, args: inst_block78000070, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific7800001C: {generic: generic78000002, args: inst_block78000070, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific7800001D: {generic: generic78000001, args: inst_block78000072, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific7800001E: {generic: generic78000002, args: inst_block78000072, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific7800001F: {generic: generic78000001, args: inst_block78000074, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000020: {generic: generic78000002, args: inst_block78000074, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000021: {generic: generic78000009, args: inst_block7800007A, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000022: {generic: generic78000005, args: inst_block78000081, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, 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<none>, decl_has_error: 0, definition_block_id: inst_block<none>, 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<none>, definition_has_error: 0}
// CHECK:STDOUT: specific78000026: {generic: generic78000002, args: inst_block78000086, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific_interfaces:
// CHECK:STDOUT: specific_interface78000000: {interface_id: interface78000000, specific_id: specific<none>}
// 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<none>, 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<none>}
// 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<none>, 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<none>}
// 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<none>, 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<none>, 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<none>}
// 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<none>, 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<none>, 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<none>, type: type(inst78000050)}
// CHECK:STDOUT: inst78000115: {kind: SymbolicBinding, arg0: entity_name78000001, arg1: inst<none>, type: type(inst78000050)}
// CHECK:STDOUT: inst78000116: {kind: SymbolicBinding, arg0: entity_name7800001C, arg1: inst<none>, 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<none>, 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<none>}
// 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<none>, 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<none>, 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<none>, type: type(inst78000050)}
// CHECK:STDOUT: inst78000165: {kind: SymbolicBinding, arg0: entity_name7800001C, arg1: inst<none>, type: type(inst78000050)}
// CHECK:STDOUT: inst78000166: {kind: SymbolicBinding, arg0: entity_name7800002B, arg1: inst<none>, 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
@@ -34,7 +34,7 @@ fn Foo(n: ()) -> ((), ()) {
// CHECK:STDOUT: entity_name50000000: {name: name1, parent_scope: name_scope<none>, index: -1, is_template: 0, is_unused: 0, form: inst<none>}
// 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<none>, 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:
+2
View File
@@ -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: <error> = return_slot_pattern <error>, <error> [concrete]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.ref: %Class = name_ref self, %self
// CHECK:STDOUT: %.loc12: type = converted %self.ref, <error> [concrete = <error>]
// 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: <error> = return_slot <error>
// CHECK:STDOUT: }
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type]
// CHECK:STDOUT: complete_type_witness = %complete_type
+1 -1
View File
@@ -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 `<cannot stringify inst7C00018B: {kind: Call, arg0: inst7C00003E, arg1: inst_block7C000091, type: type(TypeType)}>` 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 `<cannot stringify inst7C00018B: {kind: Call, arg0: inst7C00003E, arg1: inst_block7C00008A, type: type(TypeType)}>` that does not implement that interface [MissingImplInMemberAccess]
// CHECK:STDERR: var unused v: F(X) = {};
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
+16 -6
View File
@@ -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:
+7 -2
View File
@@ -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: }
+8 -2
View File
@@ -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: <error> = return_slot_pattern <error>, <error> [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, <error> [concrete = <error>]
// CHECK:STDOUT: %return: <error> = return_slot <error>
// 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: <error> = return_slot_pattern <error>, <error> [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> = 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, <error> [concrete = <error>]
// CHECK:STDOUT: %return: <error> = return_slot <error>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
+4 -1
View File
@@ -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: <error> = return_slot_pattern <error>, <error> [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: <error> = name_ref T, <error> [concrete = <error>]
// CHECK:STDOUT: %return: <error> = return_slot <error>
// CHECK:STDOUT: }
// CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (), @C.as.I.impl [concrete]
// CHECK:STDOUT: %I.impl_witness: <witness> = impl_witness %I.impl_witness_table [concrete = constants.%I.impl_witness]
+12 -1
View File
@@ -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: <error> = value_param_pattern [concrete]
// CHECK:STDOUT: %u.patt: <error> = at_binding_pattern u, %u.param_patt [concrete]
// CHECK:STDOUT: %return.patt: <error> = return_slot_pattern <error>, <error> [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, <error> [concrete = <error>]
@@ -2659,6 +2660,7 @@ fn F() {
// CHECK:STDOUT: %.loc27_13: type = converted %U.ref.loc27_13, <error> [concrete = <error>]
// CHECK:STDOUT: }
// CHECK:STDOUT: %u: <error> = value_binding u, <error> [concrete = <error>]
// CHECK:STDOUT: %return: <error> = return_slot <error>
// 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: <error> = return_slot_pattern <error>, <error> [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, <error> [concrete = <error>]
// CHECK:STDOUT: %return: <error> = return_slot <error>
// CHECK:STDOUT: }
// CHECK:STDOUT: %complete_type: <witness> = 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: <error> = value_param_pattern [concrete]
// CHECK:STDOUT: %z.patt: <error> = at_binding_pattern z, %z.param_patt [concrete]
// CHECK:STDOUT: %return.patt: <error> = return_slot_pattern <error>, <error> [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: <error> = name_ref U2, <error> [concrete = <error>]
// CHECK:STDOUT: }
// CHECK:STDOUT: %z: <error> = value_binding z, <error> [concrete = <error>]
// CHECK:STDOUT: %return: <error> = return_slot <error>
// 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: <error> = return_slot_pattern <error>, 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: <error> = return_slot <error>
// 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: <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: <error> = return_slot_pattern <error>, 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: <error> = return_slot <error>
// 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: <witness> = impl_witness %J2.impl_witness_table [concrete = constants.%J2.impl_witness.30f]
@@ -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: <error> = return_slot_pattern <error>, <error> [concrete]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %BeingDefined.ref: type = name_ref BeingDefined, file.%BeingDefined.decl [concrete = constants.%BeingDefined.type]
// CHECK:STDOUT: %T.ref: <error> = name_ref T, <error> [concrete = <error>]
// CHECK:STDOUT: %return: <error> = return_slot <error>
// 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)] {} {}
@@ -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: <error> = return_slot_pattern <error>, <error> [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: <error> = return_slot <error>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
+8 -2
View File
@@ -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: <error> = return_slot_pattern <error>, <error> [concrete]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %T.ref: type = name_ref T, @I.%T
// CHECK:STDOUT: %return: <error> = return_slot <error>
// CHECK:STDOUT: }
// CHECK:STDOUT: %complete_type: <witness> = 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: <error> = return_slot_pattern <error>, <error> [concrete]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %T.ref: type = name_ref T, file.%T
// CHECK:STDOUT: %return: <error> = return_slot <error>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
+4 -1
View File
@@ -900,8 +900,11 @@ export Poison;
// CHECK:STDOUT: .Poison = <poisoned>
// 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: <error> = return_slot_pattern <error>, <error> [concrete]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %Poison.ref: <error> = name_ref Poison, <error> [concrete = <error>]
// CHECK:STDOUT: %return: <error> = return_slot <error>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
+4 -1
View File
@@ -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: <error> = return_slot_pattern <error>, <error> [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: <error> = return_slot <error>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
+4 -1
View File
@@ -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: <error> = return_slot_pattern <error>, <error> [concrete]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %x.ref: <error> = name_ref x, <error> [concrete = <error>]
// CHECK:STDOUT: %return: <error> = return_slot <error>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
+12 -3
View File
@@ -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: <error> = return_slot_pattern <error>, <error> [concrete]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %x.ref: type = name_ref x, file.%x
// CHECK:STDOUT: %return: <error> = return_slot <error>
// 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: <error> = return_slot_pattern <error>, <error> [concrete]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %y.ref: type = name_ref y, file.%y
// CHECK:STDOUT: %return: <error> = return_slot <error>
// 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: <error> = return_slot_pattern <error>, <error> [concrete]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %z.ref: type = name_ref z, file.%z
// CHECK:STDOUT: %return: <error> = return_slot <error>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
+4 -1
View File
@@ -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: <error> = return_slot_pattern <error>, <error> [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: <error> = return_slot <error>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
+4 -1
View File
@@ -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: <error> = return_slot_pattern <error>, <error> [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: <error> = return_slot <error>
// CHECK:STDOUT: }
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %v.patt: <error> = value_binding_pattern v [concrete]
+26 -10
View File
@@ -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<SemIR::ReturnSlotPattern>()) {
auto new_subpattern_id = RebuildPatternInst<SemIR::OutParamPattern>(
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<SemIR::ReturnSlotPattern>(
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,
+18
View File
@@ -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,
+8 -11
View File
@@ -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(
+16
View File
@@ -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() \
+4
View File
@@ -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)
+54 -1
View File
@@ -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<Parse::NodeId>(
{.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<Parse::NodeId>(
{.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<Parse::NodeId>(
{.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<Parse::NodeId>(
{.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<Parse::NodeId>(
{.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`.